Archive | Hyper-V RSS for this section

Set Hyper-V VM Resynchronization Schedule via PowerShell

We were recently working through a multi-site Hyper-V VDI deployment for a customer and needed to set the Hyper-V replica ReSync Schedule for all VM’s and ensure that Auto Resync was enabled.¬† Per Host, this was accomplished by running the following script:

get-vm | Where-Object ReplicationMode -EQ “Primary” | Set-VMReplication -AutoResynchronizeEnabled $True -AutoResynchronizeIntervalStart “00:00:00” -AutoResynchronizeIntervalEnd “23:59:59”


For all VM’s, we used the following script:

$HVHOSTS = Get-ADComputer -Filter {Name -like “*host*” -and Name -notlike “*hvhost*”} | Select -ExpandProperty Name #NOTE: Your filter will look different , adjust to suit
foreach ($HVHOST in $HVHOSTS){
$VMs = get-vm -ComputerName $HVHOST | Where-Object ReplicationMode -eq “Primary”
foreach ($VM in $VMs){

Set-VMReplication -ComputerName $HVHOST -VMName $VM.Name -AutoResynchronizeEnabled $True -AutoResynchronizeIntervalStart “00:00:00” -AutoResynchronizeIntervalEnd “23:59:59”



Disclaimer: As with any script – please review & lab test in your own environment, before rolling out to production! ūüôā

Check disk space remotely with PowerShell

I work with a customer with a large VDI environment.  They had asked for a weekly report to generate with an overview of VDI disk free space.  I have created the script below to do just that.

Effectively it has three parameters (ie Get-DiskSpaceReport.ps1 – To – SMTPServer -From ¬†It runs against the AD Computer filter specified in the script (in my case it’s computers with the name VDI in it). ¬† After the report is ran, you receive an e-mail with the results sorted by % Free:


This is the result:

Param (

Import-Module ActiveDirectory
$VDISearch = get-adcomputer -filter * | Where-Object Name -Like *VDI* #Change this filter to suit your needs

$VDIs = $VDISearch.Name
$Results = @()
foreach ($VDI in $VDIs){
$disk = Get-WmiObject win32_logicaldisk -ComputerName $VDI -Filter “Drivetype=3” -ErrorAction SilentlyContinue
$Results += New-Object PSObject -Property @{
‘VDI’ = $Disk.SystemName
‘Drive Letter’ = $Disk.DeviceID + ‘\’
‘Free Space (GB)’ = ((“{0:N1}” -f ($Disk.FreeSpace/1GB)) + ‘ GB’)
‘% Free’ = ((“{0,6:P0}” -f (($Disk.FreeSpace/1GB)/($Disk.Size/1GB)) ))

$Header = @”
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}

$splat = @{
From = $From
To = $To
SMTPServer = $SMTPServer
Subject = “VDI Disk Space Report Generated by $env:computername”

$Results = $Results | Select ‘VDI’, ‘Drive Letter’, ‘Free Space (GB)’,’% Free’ | Sort ‘% Free’

$Body = $Results | ConvertTo-Html -Head $Header | Out-String

Send-MailMessage @splat -Body $Body -BodyAsHTML


PowerShell Script to Move Hyper-V VM’s

Quick easy PowerShell script to move VM’s from one Hyper-V host to another:

Get-VM -computer SOURCESERVERNAME | Out-GridView -Title “Select one or more VMs to Live Migrate” -PassThru | Move-VM -DestinationHost DESTINATIONSERVERNAME -DestinationStoragePath J:\Hyper-V (Or whatever your destination path is)

“Storage migration for virtual machine ‘servername’ failed with error ‘General access denied error’ (0x80070005).

I was recently moving storage for a customer’s Hyper-V VM from one CSV to another new storage tier. On moving the VHD, I selected the root of the storage folder as the destination. After¬†starting the storage move, I received the following error:
“Storage migration for virtual machine ‘servername’ failed with error ‘General access denied error’ (0x80070005). Migration did not succeed. Could not start mirror operation for the VHD file C:\ClusterStorage\Volume5\servername\disk-2.vhdx to C:\ClusterStorage\Volume2\disk-2.vhdx’: General access denied error’ (0x80070005).


As generally Hyper-V will create a folder name for the VM when selecting the root folder, I hadn’t given it much thought however after creating a folder with the name of the server and selecting it as the destination it completed successfully.


Hyper-V 2012R2/VMM 2012R2 VM “Missing” status/Stuck “Starting”

I recently had an issue with a customer with a missing VM after it was shutdown for maintenance.  As soon as it was started in Virtual Machine Manager, it immediately went to a Failed state and was missing from all Hyper-V hosts and stuck in a Failed state in Failover Cluster Manager.


The unusual thing was VMM and Failover Cluster manager thought they were on different hosts(follow steps below for the host that Cluster Manager says it should be on). The issue was due to the missing symbolic link to the VM on the Host it was missing from.

The fix was to re-create the symbolic link on the Host Failover Cluster Manager thinks it’s missing from. ¬†First, find the GUID for your¬†VM from the source location for the specific¬†VM config:


Then browse to¬†C:\ProgramData\Microsoft\Windows\Hyper-V\Virtual Machines on the host in question. ¬†Run CMD prompt as Administrator from the folder¬†and create the link with the following command:¬†Mklink FA060046-2C40-4D8E-A6EA-2A4587A84B3B.xml “C:\ClusterStorage\Volume4\YOURVMNAMEHERE\Virtual Machines\FA060046-2C40-4D8E-A6EA-2A4587A84B3B.xml”

Then grant permissions:

icacls “%SYSTEMDRIVE%\ProgramData\Microsoft\Windows\Hyper-V\Virtual Machines\FA060046-2C40-4D8E-A6EA-2A4587A84B3B.xml” /grant “NT VIRTUAL MACHINE\FA060046-2C40-4D8E-A6EA-2A4587A84B3B”:F /l


Finally restart the Hyper-V Virtual Machine Service and all should be back online!



Check for open application and reboot Hyper-V VM

I’ve recently had a requirement for a scheduled reboot of a large group of Hyper-V VDIs. Due to the nature of the line of business application, it was imperative that we checked that several specific apps were not running before the reboot was ran.¬† Here is an example of the script I wrote for this task.¬† Simply replace the $process, $process2, etc. with your specific application (name only, no path or .exe, etc. requirement).¬† The script checks the running process on the VDI, if one of the apps are running it breaks the loop for that VM and continues to the next, otherwise it reboots the VM and notifies the user.¬† Here’s the script:

$vms2reboot = get-vm | Where-Object Name -like *test-vm001* | Select-Object -Expand Name
$process = “Notepad”
$process2 = “Calc”
$process3 = “Mspaint”
start-transcript “C:\reboot-vms.log”
foreach ($vm2reboot in $vms2reboot){

if(get-process -Computername $vm2reboot | where-object {
$_.ProcessName -contains “$process” -or
$_.ProcessName -contains “$process2”-or
$_.ProcessName -contains “$process3”
Write-Host “A business app is currently running.¬† Reboot will not continue on $vm2reboot”
Else {write-host “Rebooting VM $vm2reboot”
shutdown -r -f -m \\$vm2reboot -c “Reboot commencing for maintenance”


10-04-2015 9-10-51 p-m-new

If one of the apps are open, reboot does not continue:

10-04-2015 9-16-53 p-m-

Otherwise it reboots the VM:

10-04-2015 9-15-12 p-m-

10-04-2015 9-14-37 p-m-


Create Hyper-V VDI/VM by name from CSV file

I was working on a Hyper-V VDI project for a customer recently, who needed to easily deploy a VDI Template VHD from a CSV file and create VMs based on this VHD. I put this script together to fit this requirement.

It references a CSV file called vdi.csv, which contains your desired Hyper-V VM names.  It then builds as many copies of the VM as your CSV contains:
Here’s the script!
$VDIs = get-content .\vdi.csv
foreach ($VDI in $VDIs){
write-host $VDI is being copied from a VHD template.¬† This will take approxmiately 2 minutes…
copy “F:\Hyper-V\Virtual Hard Disks\vdi-template.vhd” “F:\Hyper-V\Virtual Hard Disks\$VDI.vhd”
New-VM -Name $VDI -BootDevice IDE -VHDPath “F:\Hyper-V\Virtual Hard Disks\$VDI.vhd” -MemoryStartupBytes 2GB -SwitchName “External”
Set-VMMemory -VMName $VDI -DynamicMemoryEnabled $true -MinimumBytes 512MB -StartupBytes 2GB -MaximumBytes 4GB
Set-VM -Name $VDI -AutomaticStopAction Shutdown
write-host $VDI Has now been created and ready for use…
It’s a quick and dirty script – I’ll look at building it out as future requirements dictate.

Merging a Hyper-V child VHD/VHDX differencing disks with the parent VHD/VHDX.

I’ve recently had a requirement to merge some child differencing disks, with the associated VHD/VHDX in Hyper-V.

Thankfully this is very straight forward and can be done one of two ways(after a confirmed backup and/or export of your VM!):
1.) Using the edit disk option in Hyper-V:
2.) Using DiskPart from a command prompt.
Enter Diskpart.
select vidsk file=”C:\Temp\MT12-SC-H2-LON-AP1\Virtual Hard Disks\MT12-SC-H2-LON-AP1.vhd
merge vdisk depth=1
Remember in either option, you will need to go back into your VHD location in the Hyper-V VM settings and change the path to point to the base disk.
Note: If you go with Option 2, you will need to manually remove the child differencing disk from your VHD storage location.

Powershell: get-vmswitch, get-vm, etc. blank

Recently when running a get-vmswitch PowerShell command on a Hyper-V host I noticed that the content came back blank.¬† Even though I was a local admin on the host, I still needed to run my PowerShell session as an Administrator.¬† Doh!¬† If you notice you are not getting results, might pay to give it a go. ūüôā

VMM cannot complete the host operation on the hvhost.x.x

In Virtual Machine Manager or Hyper-V, when accessing an ISO from VMM Library Server, you may find the following message:
Error (12700)
VMM cannot complete the host operation on the hvhost.x.x server because of the error: ‘VM’ failed to add device ‘Virtual CD/DVD Disk’. (Virtual machine ID B3C07289-26B9-4D52-977D-91F5DB15C6A1)

‘VM’: User account does not have permission required to open attachment ‘\\SCVMM.x.x\MSSCVMMLibrary\ISOs\Microsoft\MS Server 2008 R2\en_windows_server_2008_r2_standard_enterprise_datacenter_web_vl_build_x64_dvd_x15-59754.iso’. Error: ‘General access denied error’ (0x80070005). (Virtual machine ID B3C07289-26B9-4D52-977D-91F5DB15C6A1)
Unknown error (0x8001)

Recommended Action
Resolve the host issue and then try the operation again.To work around this, you will need to
a) Provide full NTFS & Share access to the Hyper-V’s host’s Computer Account for the MSCVMMLibrary Share
b) Setup constrained delegation in AD for the Hyper-V Host


After completing the steps listed above, you should be able to attach your ISO without any issues.