Hello everyone,

One day, I upgraded my Hyper-V host to the fastest Solid State Drive on the market.

It’s pretty expensive, but it deserves performance.

Consecutive number: 550 MB / s.
Consecutive write: 550 MB / s.
Random number: 100000 IOPS.
Random text: 90000 IOPS.

Now, before replacing the disk, I copied all my virtual machines to a safe location, replaced the disk, and then restored all the virtual machines back.

When I try to boot from a virtual machine…

Sorry!

The error message clearly indicates that Hyper-V does not have sufficient permissions to use the virtual hard disk. The problem is because I copy all my virtual machines from one drive to an external drive. Therefore, a virtual machine SID virtual hard drive is missing.

Start-VM-GeneralAccessDenied-02

Some time ago, I came across a similar thing here Attempted to initialize virtual machine saved space – Saved status file could not be created or accessed.

The most common solution is to simply go to the security tab of each virtual hard drive and add an account. Set access rights (Read to write). However, there are a lot of flaws in this approach, so it’s not my favorite. It is always possible that you skipped the setting and something may not work as intended.

Another option is to use icacls as documented below KB article.

My third and favorite option is Use Hyper-V Manager Remove the disk from the virtual machine, then go back and reinsert it.

Start-VM-GeneralAccessDenied-03

Because every time you add a virtual hard disk, Hyper-V gives that Virtual Machine account the necessary permissions on the virtual hard disks.

Start-VM-GeneralAccessDenied-04

Now this works well if you have pairs of virtual machines, but what if you have dozens of virtual machines and each virtual machine has multiple virtual hard disks.

Start-VM-GeneralAccessDenied-05

PowerShell to help again!

Therefore, I wrote a script that allows you to configure a single virtual machine or Hyper-V host, and a script:

1. Turn off the virtual machine if it is running (most of the time, the virtual machine is offline due to missing permission, but in some situations, the virtual machine is in stored mode, you must force it to shut down).
2. Delete any VHD / X files attached to the virtual machine drivers that do not have a Virtual Machine Id license.
3. Verify that the virtual machine is using Shared VHD / X.
4. Paste the VHD / X files back to the same drivers and locations in the VM settings.
5. Start the virtual machine.

<#
    .SYNOPSIS
    Reset Virtual Hard Disk Permission Tool.

    .DESCRIPTION
    Reset Virtual Hard Disk Permission for a single or all Virtual Machines.

    .NOTES
    ========================================================================
    File Name    : Reset-VHDPermission.ps1
    Author       : Charbel Nemnom
    Version      : 1.0
    Date created : 23.June.2015
    Last modified: 26.June.2015
    Requires     : PowerShell Version 4.0 or above
    OS           : WS 2012, WS 2012 R2, WS 2016 Hyper-V TP2
    Module       : Hyper-V-PowerShell
    =========================================================================

    .LINK
    To provide feedback or for further assistance please visit:
    
Cover Page
.EXAMPLE .Reset-VHDPermission.ps1 -VMName <VMName> This example will reset the selected VM by turnig Off the VM if it is in Saved State, Then remove any VHD/X files attached to any of the VM controllers, Check if the VM is using Shared VHDX, then attach the VHD/X files back To the same controllers and locations, and finally start the virtual machine. .EXAMPLE .Reset-VHDPermission.ps1 -HVHost <Hyper-V Host> This example will reset all Virtual Machines by turnig Off the VM if it is in Saved State, Then remove any VHD/X files attached to any of the VM’s controllers, Check if the VM is using Shared VHDX, then attach the VHD/X files back To the same controllers and locations, and finally start the virtual machine. #> [CmdletBinding ()] Param ( [Parameter(Mandatory = $true, HelpMessage = 'Virtual Machine Name', ParameterSetName = "VM")] [String]$VMName, [Parameter(Mandatory = $true, HelpMessage = 'Hyper-V Host', ParameterSetName = "Host")] [String]$HVHost ) Function VirtualMachine { $VM = Get-VM $VMName $VMStatus = $VM.State [string]$VMid = $VM.VMid if ($VMStatus -eq "Saved") { # Turn Off the VM if it is in Saved State and wait 5 seconds Write-Output "Turn Off $VMName Virtual Machine" Stop-VM $VMName -Force -TurnOff Sleep 5 } # Get all the disks in the VM $AllVHD = Get-VMHardDiskDrive $VMName if ($AllVHD -eq $NULL) { Write-Output "There are no virtual hard disks attached to the VM" Break } foreach ($VHD in $AllVHD) { # Get the VM VHD details [string]$VHDXFile = Get-Item $VHD.Path [string]$ControllerType = $VHD.ControllerType [string]$ControllerNumber = $VHD.ControllerNumber [string]$ControllerLocation = $VHD.ControllerLocation [string]$SharedVHDX = $VHD.SupportPersistentReservations [string]$objACL = @((get-acl -Path $VHD.Path).Access | Select-Object -ExpandProperty IdentityReference) If ($objACL -notmatch $VMid) { # Remove the VHD(x) Write-Output "Removing $VHDXFile from $VMName Virtual Machine" Remove-VMHardDiskDrive $VHD Sleep 3 # Attach the VHD/X files back to the same controllers and locations Write-Output "Adding $VHDXFile to $VMName Virtual Machine" If ($SharedVHDX -eq $true) { Add-VMHardDiskDrive -VMName $VMName -Path $VHDXFile -ControllerType $ControllerType -ControllerNumber $ControllerNumber -ControllerLocation $ControllerLocation -SupportPersistentReservations } Else { Add-VMHardDiskDrive -VMName $VMName -Path $VHDXFile -ControllerType $ControllerType -ControllerNumber $ControllerNumber -ControllerLocation $ControllerLocation } Sleep 3 } } # Start the VM Write-Output "Starting $VMName Virtual Machine" Start-VM $VMName Write-Output "Reset VHD Permission of $VMName has completed" } Function HyperV-Host { $VMs = Get-VM -ComputerName $HVHost foreach ($VM in $VMs) { $VMStatus = $VM.State $VMName = $VM.Name [string]$VMid = $VM.VMid if ($VMStatus -eq "Saved") { # Turn Off the VM if it is in Saved State and wait 5 seconds Write-Output "Turn Off $VMName Virtual Machine" Stop-VM $VMName -Force -TurnOff Sleep 5 } # Get all the disks in the VM $AllVHD = Get-VMHardDiskDrive $VMName if ($AllVHD -eq $NULL) { Write-Output "There are no virtual hard disks attached to the VM $VMName" Break } foreach ($VHD in $AllVHD) { # Get the VM VHD details [string]$VHDXFile = Get-Item $VHD.Path [string]$ControllerType = $VHD.ControllerType [string]$ControllerNumber = $VHD.ControllerNumber [string]$ControllerLocation = $VHD.ControllerLocation [string]$SharedVHDX = $VHD.SupportPersistentReservations [string]$objACL = @((get-acl -Path $VHD.Path).Access | Select-Object -ExpandProperty IdentityReference) If ($objACL -notmatch $VMid) { # Remove the VHD(x) Write-Output "Removing $VHDXFile from $VMName Virtual Machine" Remove-VMHardDiskDrive $VHD Sleep 3 # Attach the VHD/X files back to the same controllers and locations Write-Output "Adding $VHDXFile to $VMName Virtual Machine" If ($SharedVHDX -eq $true) { Add-VMHardDiskDrive -VMName $VMName -Path $VHDXFile -ControllerType $ControllerType -ControllerNumber $ControllerNumber -ControllerLocation $ControllerLocation -SupportPersistentReservations } Else { Add-VMHardDiskDrive -VMName $VMName -Path $VHDXFile -ControllerType $ControllerType -ControllerNumber $ControllerNumber -ControllerLocation $ControllerLocation } Sleep 3 } # Start the VM Write-Output "Starting $VMName Virtual Machine" Start-VM $VMName Write-Output "Reset VHD Permission of $VMName has completed" } } } Switch ($PSCmdlet.ParameterSetName) { "VM" { VirtualMachine } "Host" { HyperV-Host } }

Start-VM-GeneralAccessDenied-06

Hopefully this will help!

Enjoy your weekend …

Cheers,
/Charbel

LEAVE A REPLY

Please enter your comment!
Please enter your name here