Migrate Hyper-V File based Authorization Store to AD Authorization Store Script

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.

image

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. (0x80070020)

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(0x20)

$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. (0x80072098).

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)

Advertisements

About Hikmat Kanaan

I’m big fan of technology; I have worked almost with every MS windows OS up to Windows 8 and server 2012 including OS deployment, AD and almost every MS OS service included major MS products ISA ,TMS, Exchange, System center ,Sharepoint ,SQL , Storage system, Networking, security, Cisco, HP, and Checkpoint products. Designing and Architecting IT solutions and infrastructure . I do admire automation and working based on best practices toward building highly reliable solution that provide the required services to Business. I also run the Jordan IT professionals user Group http://www.jitpros.net
This entry was posted in Hyper-v, Tips, VMM2012, Windows 2012 and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s