How to Fix Hyper-V VHD Locked by Another Process: Complete Troubleshooting Guide


2 views

When attempting to start a Hyper-V virtual machine, you might encounter the frustrating error: "The process cannot access the file because it is being used by another process". This typically occurs when the Virtual Hard Disk (VHD/VHDX) file is locked by another process, preventing Hyper-V from gaining exclusive access.

Several situations can lead to this file access conflict:

  • Another Hyper-V manager or virtualization software has the file open
  • Antivirus software is scanning the VHD file
  • File system permissions are incorrect
  • The VM didn't shut down cleanly, leaving file handles open
  • Backup software is accessing the virtual disk

1. Basic Troubleshooting

First, try these quick fixes:

# Restart the Hyper-V Virtual Machine Management service
Stop-Service vmms
Start-Service vmms

# Or completely reboot the Hyper-V host
Restart-Computer -Force

2. Identify the Locking Process

Use PowerShell to find which process has the handle:

# Requires SysInternals Handle.exe in your PATH
$vhdPath = "C:\Path\To\Your\VirtualDisk.vhdx"
handle.exe $vhdPath | Select-String -Pattern "pid"

Alternatively, use Resource Monitor:

  1. Open Resource Monitor (resmon.exe)
  2. Go to the CPU tab
  3. Search for your VHD filename in "Associated Handles"

3. Force Release the VHD

If you've identified the process and can't stop it gracefully:

# Kill the process by PID (replace 1234 with actual PID)
Stop-Process -Id 1234 -Force

# For stubborn cases, use handle.exe to close just that handle
handle.exe -p 1234 -c handleValue -y

Using Diskpart to Detach VHD

When standard methods fail, use diskpart:

diskpart
select vdisk file="C:\Path\To\Locked.vhdx"
detach vdisk
exit

Preventing Future Locks

Add these registry tweaks to improve file handling:

# Disable VHD indexing in Windows Search
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Search" -Name "IndexingEnabled" -Value 0

# Exclude VHD files from antivirus scanning
Add-MpPreference -ExclusionExtension ".vhd",".vhdx"

Here's a complete PowerShell function to handle VHD unlocking:

function Unlock-HyperVVHD {
    param (
        [Parameter(Mandatory=$true)]
        [string]$VHDPath
    )
    
    # Check for Handle.exe
    if (-not (Get-Command handle.exe -ErrorAction SilentlyContinue)) {
        Write-Warning "SysInternals Handle.exe not found in PATH"
        return
    }

    # Find locking processes
    $handles = handle.exe $VHDPath 2>$null | 
        Where-Object { $_ -match "pid: (\d+)\s.*handle: (\w+)" } |
        ForEach-Object {
            [PSCustomObject]@{
                PID = $matches[1]
                Handle = $matches[2]
                Process = (Get-Process -Id $matches[1]).ProcessName
            }
        }

    if (-not $handles) {
        Write-Host "No processes found locking the VHD"
        return
    }

    # Attempt to close handles
    $handles | ForEach-Object {
        try {
            handle.exe -p $_.PID -c $_.Handle -y | Out-Null
            Write-Host "Successfully closed handle $($_.Handle) from $($_.Process) (PID: $($_.PID))"
        }
        catch {
            Write-Warning "Failed to close handle $($_.Handle): $_"
        }
    }
}

For persistent cases, consider these nuclear options:

  • Take ownership of the VHD file using icacls
  • Boot into safe mode and try operations
  • Create a new VM configuration pointing to the same VHD
  • As last resort, use a Linux live CD to access the file

Remember to always have backups before attempting aggressive solutions.


When attempting to start a Hyper-V virtual machine, you might encounter this frustrating error indicating your VHD file is locked by another process. This typically happens when:

  • The VM didn't shut down cleanly
  • Hyper-V management services crashed
  • Another application has file handles open
  • Antivirus software is scanning the file

Before attempting forceful methods, try these basic checks:

# Check if Hyper-V services are running properly
Get-Service vmms | Restart-Service -Force
Get-Service vds | Restart-Service -Force

Use PowerShell to find which process holds the file handle:

# Requires Handle.exe from Sysinternals
$vhdPath = "C:\path\to\your.vhdx"
.\handle.exe -a $vhdPath | Select-String "pid"

If standard methods fail, use this PowerShell script to force release:

function Unlock-VHD {
    param(
        [Parameter(Mandatory=$true)]
        [string]$VHDPath
    )
    
    $fileStream = [System.IO.File]::Open(
        $VHDPath,
        [System.IO.FileMode]::Open,
        [System.IO.FileAccess]::ReadWrite,
        [System.IO.FileShare]::ReadWrite
    )
    
    $fileStream.Close()
    $fileStream.Dispose()
    
    Write-Host "VHD lock released successfully" -ForegroundColor Green
}

# Usage example
Unlock-VHD -VHDPath "D:\VMs\WinServer.vhdx"

If PowerShell doesn't work, consider these approaches:

  1. Use Process Explorer to manually close handles
  2. Restart the Hyper-V Virtual Machine Management service
  3. Temporarily disable antivirus real-time scanning

Add these registry tweaks to improve Hyper-V file handling:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization]
"DisableWritesThroughBuffering"=dword:00000001
"MemoryPreAllocation"=dword:00000001

For administrators managing multiple VMs:

$lockedVHDs = Get-VM | Where-Object {$_.State -eq "Error"} | 
              Select-Object -ExpandProperty HardDrives | 
              Where-Object {$_.Path -like "*.vh*"}

foreach ($vhd in $lockedVHDs) {
    try {
        $vm = Get-VM -Id $vhd.VMId
        Stop-VM -VM $vm -Force -ErrorAction Stop
        Unlock-VHD -VHDPath $vhd.Path
        Start-VM -VM $vm
    }
    catch {
        Write-Warning "Failed to process $($vhd.Path): $_"
    }
}