MS Hyper-V implements role-based access control to define what users can and cannot do with virtual machines, after installing the Hyper-V it will always be configured to use a local XML file located at \programdata\Microsoft\Windows\Hyper-V\InitialStore.xml on the system partition. The store file content used to perform access checks to grant or deny a user account access to operations based on roles that user account is a member of. The Hyper-v Store can be stored in Active Directory database, which must be at the Windows Server 2003 Domain functional level, or in an XML file on the local server running the Hyper-V role.
The Authorization Manager snap-in (AzMan.msc) is the user interface tool to manipulate the content of authorization store, to create new User roles and delegate permission on hyper-v .
Two registry keys on Hyper-V define policy store both are under:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Virtualization.
StoreLocation points to a file called InitialStore in a hidden directory c:\ProgramData.
ServiceApplication defines the application Name in the policy store.
When Hyper-v Host added to SCVMM the default Authorization store is changed to use a new file located at “%systemDrive%\ProgramData\Microsoft\Virtual Machine Manager\HyperVAuthStore.xml” and point hyper-v to that file. Every 30 minutes, VMM will run a refresher that will update this file and ensure that the only privileges to VMs are the ones that VMM knows about.
On heavy used Hosts where SCVMM perform multiple VM management tasks such as creating multiple VMs or change multiple VM’s Owners , multiple JOB threads might try to update the Authorization store file simultaneously, This will result in an error to be logged on Hyper-v event logs as access valuation error.
Event ID 17090, Source Hyper-V-VMMS/Admin, User: System
The content of the authorization store could not be updated from the persistent location.
Error: The process cannot access the file because it is being used by another process. (0×80070020)
This error is due to the fact that NTFS file system does not support applications issuing a sequence of separate write operations as a single logical write to a file when multiple applications write to the same file
To overcome this problem the Authorization store can be migrated to AD and Hyper-v be configured to use AD store instead of File based Authorization store. There is no Built-in utility on windows that can perform this operation. The below PowerShell Script can be used to Create and migrate Hyper-v Authorization store file to utilize Authorization Store in AD. The script Create Authorization Store at CN=ProgramData,DC=Domain,DC=DomainSuffix , it must be run on each Hyper-v host that will use AD as authorization Store for the hyper-v Role. Each Host Should have its own Authorization Store Container in AD.
Notes:
1. The Script will create a backup of the current registry setting in the same folder with name BackupRegVirtualization.reg , you can restore your pervious configuration by double click this File.
2. The AD Store name is constructed as : CN=AZ+HostName,CN=Program Data,DC=Domain,Dc=Domain
3. VDI Virtualization Hosts is not Supported , this script will fail if Remote Desktop Virtual host is installed
4. The Script support hosts under SCVMM control
Power Shell Script below :
——————————Start Of Script ———————-
# Copy Roles Definitions
function CopyRoleDefinition($taskName)
{
$sourceTask = $HyperVAzManStoreSource.OpenTask($taskName);
$targetTask = $HyperVAzManStoretarget.CreateTask($taskName);
$targetTask.IsRoleDefinition = $true
$operations = $sourceTask.Operations
for ($opIdx = 0; $opIdx -lt $operations.length; $opIdx++)
{
$targetTask.AddOperation($operations[$opIdx])
}
$targetTask.Submit()
}
#Copy role Assignment
function CopyRoleAssignmet($AssingedRole)
{
$sourceRoleAssignment = $HyperVAzManStoreSource.OpenRoleAssignment($AssingedRole)
$targetRoleAssignment = $HyperVAzManStoretarget.CreateRoleAssignment($AssingedRole)
$targetRoleAssignment.Description=$sourceRoleAssignment.Description
$sourceRoleAssignment.members | ForEach-Object { $targetRoleAssignment.addmember($_)}
$sourceRoleAssignment.Tasks | ForEach-Object { $targetRoleAssignment.addtask($_)}
$sourceRoleAssignment.Operations | ForEach-Object { $targetRoleAssignment.AddOperation($_)}
$targetRoleAssignment.Submit()
}
Function CopyScope($ScopeName)
{
# Create AzMan Application
$HyperVAzManStoreSource.OpenScope($ScopeName)
$targetScope=$HyperVAzManStoretarget.CreateScope($ScopeName)
$targetScope.submit()
#CopyRoleDefinition($ScopeName)
#CopyRoleAssignmet($ScopeName)
}
# copy Scope Role Definistion
function CopyScopeDefinition($SourceScopeRole)
{
$sourceTask = $ScopeEnmDefSource.OpenTask($taskName);
$targetTask = $ScopeEnmDeftarget.CreateTask($taskName);
$targetTask.IsRoleDefinition = $true
$operations = $sourceTask.Operations
for ($opIdx = 1; $opIdx -lt $operations.length; $opIdx++)
{
$targetTask.AddOperation($operations[$opIdx])
}
$targetTask.Submit()
}
# Copy Sole Role Assignment
function CopyScopeAssignmet($AssingedRole)
{
$sourceRoleAssignment = $ScopeEnm.OpenRoleAssignment($AssingedRole)
# $sourceRoleAssignment
$targetRoleAssignment = $ScopeEnmDeftarget.CreateRoleAssignment($AssingedRole)
$targetRoleAssignment.Description=$sourceRoleAssignment.Description
$sourceRoleAssignment.members | ForEach-Object { $targetRoleAssignment.addmember($_)}
$sourceRoleAssignment.Tasks | ForEach-Object { $targetRoleAssignment.addtask($_)}
$sourceRoleAssignment.Operations | ForEach-Object { $targetRoleAssignment.AddOperation($_)}
$targetRoleAssignment.Submit()
}
# Convert a domain Name from DNS Form to DN
function DomainStringtoDN ($DomainName)
{
$DomainNameArray = $DomainName.Split(“.”)
for ($Dom = 0; $Dom -lt $DomainNameArray.Length ; $Dom++)
{
if ($Dom -eq ($DomainNameArray.Length – 1)){$Separator = “”}
else{$Separator =”,”}
[string]$DN += “DC=” + $DomainNameArray[$Dom] + $Separator
}
return $DN
}
# This Script will Create an AD AzMan Store using a path constructed from Hyper-v Hostname and Domain Name that the host is Joined to
# The Store path is CN=AZ+HostName,CN=Program Data,DC=Domain,Dc=Domain
# to Setup up manual AD Location , specify static value for the $AzManStoreLocationtraget Variable
$HyperVHostName=Get-WmiObject -class win32_computersystem
$DomainDN=DomainStringtoDN($HyperVHostName.Domain)
# Construct the Target AD Store Location
$AzManStoreLocationtraget=”msldap://CN=”+”Az”+$HyperVHostName.Name+”,CN=Program Data,”+$DomainDN
#get Current Store location
$AzManStoreLocationSource = (Get-ItemProperty -path “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization”).StoreLocation
# Check if System Already configured with AD AzMan Store
if ($AzManStoreLocationSource.contains(“msldap:”))
{
Write-host ” Your System Already use AD Autorization Store”
exit
}
# Open the XML AzMan store
$AzManStore = new-object -ComObject “AzRoles.AzAuthorizationStore”
$AzManStore.Initialize(2, $AzManStoreLocationSource)
# Handle the default Hyper-V AzMan store and the SCVMM AzMan store
if (@($AzManStore.Applications | ? {$_.Name -contains “Hyper-V services”}).count -eq 1)
{
$HyperVAzManStoreSource = $AzManStore.OpenApplication(“Hyper-V services”)
}
elseif (@($AzManStore.Applications | ? {$_.Name -contains “Virtual Machine Manager”}).count -eq 1)
{
$HyperVAzManStoreSource = $AzManStore.OpenApplication(“Virtual Machine Manager”)
}
else
{
Write-Host “Unable to find AzMan application group.”
Write-Host -NoNewLine “Press any key to continue…”
$null = $Host.UI.RawUI.ReadKey(“NoEcho,IncludeKeyDown”)
exit
}
# Backup registry Key before Operations
regedit /e BackupRegVirtualization.reg “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization”
# Create New AzMan Store in AD
$AzManStoreTarget = new-object -ComObject “AzRoles.AzAuthorizationStore”
$AzManStoreTarget.Initialize(1, $AzManStoreLocationtraget)
$AzManStoreTarget.Submit()
$AzManStoreTarget.UpgradeStoresFunctionalLevel(0×20)
$AzManStoreTarget.Submit()
# Create AzMan Application
$HyperVAzManStoretarget=$AzManStoreTarget.CreateApplication($HyperVAzManStoreSource.name)
$HyperVAzManStoretarget.version=$HyperVAzManStoreSource.version
$HyperVAzManStoretarget.submit()
### Copy Oprations
$AzOperationCount=$HyperVAzManStoreSource.Operations.Count
#$AzOperationCount
for ($i=1; $i -le $AzOperationCount; $i++)
{
$sourceOp = $HyperVAzManStoreSource.Operations.Item($i)
$targetOp = $HyperVAzManStoretarget.CreateOperation($sourceOp.Name)
$targetOp.OperationID = $sourceOp.OperationID
$targetOp.Submit()
}
# Select Default Role Defintions
$RolesDef=$HyperVAzManStoreSource.RoleDefinitions | select -ExpandProperty name
$Rolesdef | ForEach-Object { CopyRoleDefinition($_) }
# Select Default Role Assingnment
$RoleAssignment=$HyperVAzManStoreSource.RoleAssignments | select -ExpandProperty name
$RoleAssignment | ForEach-Object {CopyRoleAssignmet($_)}
# Scope Copy Operation
$AZSourceScops=$HyperVAzManStoreSource.Scopes | select -ExpandProperty name
$AZSourceScops | ForEach-Object {CopyScope($_)}
$AZTargetScops=$HyperVAzManStoretarget.scopes | select -ExpandProperty name
for ($i=1; $i -le $HyperVAzManStoreSource.Scopes.count; $i++)
{
$ScopeEnm=$HyperVAzManStoreSource.Scopes.item($i)
$ScopeEnmDeftarget=$HyperVAzManStoretarget.OpenScope($ScopeEnm.name)
# Select Default Role Defintions
$ScopeEnmDefSource=$ScopeEnm.RoleDefinitions | select -ExpandProperty name
if ($ScopeEnmDefSource -ne $null) {
$ScopeEnmDefSource | ForEach-Object { CopyScopeDefinition($_) }
}
}
###################
for ($i=1; $i -le $HyperVAzManStoreSource.Scopes.count; $i++)
{
$ScopeEnm=$HyperVAzManStoreSource.Scopes.item($i)
$ScopeEnmDeftarget=$HyperVAzManStoretarget.OpenScope($ScopeEnm.name)
# Select Default Role Defintions
$ScopeEnmDefSource=$ScopeEnm.RoleAssignments | select -ExpandProperty name
$ScopeEnmDefSource | ForEach-Object { CopyScopeAssignmet($_) }
}
# Set Hyper-v registry to use AD Azman Store
Set-ItemProperty -path “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization” -name StoreLocation -Value $AzManStoreLocationtraget
Write-Host (“Completed ………………………….!”)
——————————End Of Script ———————-
After the Script Complete Open The new Store in AZMAN , right click the sore name , select the security Tab and Add the Host Computer account and SCVMM service account as administrators
Restart the Hyper-V Virtual Machine Management service
The following error Might appear in your event log if your host is also a Domain Controller :
Log Name: Microsoft-Windows-Hyper-V-Worker-Admin
Source: Microsoft-Windows-Hyper-V-Worker
Date: 9/3/2012 11:53:25 AM
Event ID: 17040
Task Category: None
Level: Error
Keywords:
User: NETWORK SERVICE
Computer: JDC01.jitpros.local
Description:
The authorization store could not be initialized from storage location ‘msldap://CN=AzJDC01,CN=Program Data,DC=jitpros,DC=local’. Error: Insufficient access rights to perform the operation. (0×80072098).
To solve the problem Run Azman.msc , Open the Created AD Authorization Store , right click the Application name , select security tab , add Host name and Network services (only if the host is also a DC)