2021 Annual Petri Reader Survey - We want to know what's important to you! 2021 Annual Petri Reader Survey - We want to know what's important to you!
Hyper-V

Testing Hyper-V Disk Health

I use Hyper-V extensively to provide a domain environment that serves as my training and test playground. And because my environment has to be portable, I tend to run into more problems than hopefully you do. However, you might still benefit from experiences and maybe you will learn something about PowerShell along the way. If a virtual machine is already running, I’m not too concerned about it. Instead, I need a heads up on all my other virtual machines, especially if there is a problem that would keep them from starting.

Using the Hyper-V module, grabbing all virtual machines is pretty easy.

Getting virtual machine status (Image Credit: Jeff Hicks)
Getting virtual machine status (Image Credit: Jeff Hicks)

As you can see, I have one virtual machine with a critical problem, which is because the virtual machine configuration file is missing or corrupt. The configuration file is an XML file named with the virtual machine’s ID. I can confirm that the file is missing.

Get-VM | select Name,ConfigurationLocation,
@{Name="ConfigFile";Expression={ Join-path -Path "$($_.configurationLocation)\Virtual Machines" -ChildPath "$($_.vmid).xml" -Resolve }}
format-table -autosize
Listing configuration file locations (Image Credit: Jeff Hicks)
Listing configuration file locations (Image Credit: Jeff Hicks)

That’s a pretty easy thing to check and fix. What’s a bit harder is verifying that the virtual disk files, which include vhd and vhdx files, are all in place. I can easily see what the files should be.

Listing virtual machine disk files (Image Credit: Jeff Hicks)
Listing virtual machine disk files (Image Credit: Jeff Hicks)

But unless the virtual machine is running without error, I really don’t know. One thing I can do is test each path.

Get-VM | Get-VMHardDiskDrive | Where { -Not (test-path $_.path)}
Listing virtual machines with invalid disk files (Image Credit: Jeff Hicks)
Listing virtual machines with invalid disk files (Image Credit: Jeff Hicks)

Or perhaps I want to check all virtual machines and insert a custom property that indicates if virtual disks exist.

Get-VM | Select Name,State,@{Name="TestVHD";Expression = { $_ | Get-VMHardDiskDrive | Test-Path }},Status
Adding a custom property (Image Credit: Jeff Hicks)
Adding a custom property (Image Credit: Jeff Hicks)

There is one slight wrinkle with this approach. The virtual machine called demo doesn’t have any virtual disks defined, so I don’t get any results. Let me refine the command to take this into account.

Get-VM | Select Name,State,
@{Name="TestVHD";Expression = {
if ($_.HardDrives) {
$_ | Get-VMHardDiskDrive | Test-Path
}
else {
#no hard drive files configured
$false
} }},
Status

Better handling of missing disk files (Image Credit: Jeff Hicks)
Better handling of missing disk files (Image Credit: Jeff Hicks)

That’s better. Although for virtual machines with multiple disk files, my custom property is an array, as you can see for Nano-01. Eventually I want to get to a point where I can filter on the TestVHD property. For my purposes, all disks must test as true, otherwise I’ll treat the entire test as a failure. Here’s how I might accomplish this:

Get-VM | Select Name,State,
@{Name="TestVHD";Expression = {
$test = @()
if ($_.HardDrives) {
$test+=$_ | Get-VMHardDiskDrive | Test-Path
}
else {
#no hard drive files configured
$test+=$false
}
if ($test -contains $False) {
$False
}
else {
$True
}
}},
Status

I initialize a variable, $test, to hold the values from Test-Path. Next, I test using the –Contains operator to see if $test has any values of $False. If so, then the value for TestVHD should be false.

Testing for multiple disk files (Image Credit: Jeff Hicks)
Testing for multiple disk files (Image Credit: Jeff Hicks)

That’s much better. Now I can get a better feel for what virtual machines need attention.

Get-VM | Where {$_.state -ne "running"} | Select Name,State,
@{Name="TestVHD";Expression = {
$test = @()
if ($_.HardDrives) {
$test+=$_ | Get-VMHardDiskDrive | Test-Path
}
else {
#no hard drive files configured
$test+=$false
}
if ($test -contains $False) {
$False
}
else {
$True
}
}},
@{Name="Drives";Expression={$_.HardDrives.path}},Status | Where {-Not $_.TestVHD}

In this example, I am also grabbing the paths of each virtual disk file.

Listing problem virtual machines (Image Credit: Jeff Hicks)
Listing problem virtual machines (Image Credit: Jeff Hicks)

Although that’s helpful information, that’s a lot to type each time I want to test. In another article, I’ll demonstrate how to take this a step further. As always, comments and questions are welcome.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (0)

Leave a Reply

Register for the Hybrid Identity Protection (HIP) Europe Conference!

Hybrid Identity Protection (HIP) Europe 2021 - Virtual Conference

Mobile workforces, cloud applications, and digitalization are changing every aspect of the modern enterprise. And with radical transformation come new business risks. Hybrid Identity Protection (HIP) is the premier educational forum for identity-centric practitioners. At the inaugural HIP Europe, join your local IAM experts and Microsoft MVPs to learn all the latest from the Hybrid Identity world.