I don’t know about you, but my Hyper-V box has a number of virtual machines. Many of them created for ad-hoc or testing purposes. I suspect you might be in the same boat. In most cases a running virtual machine indicates it is “in production”. But what about the other machines? How can I tell when they were last used? We can get creation time easy enough using PowerShell and the Get-VM cmdlet.

I piped the result to Out-Gridview to make easier to re-sort or perform additional filtering. You can see my results in Figure 1.

Figure 1

That can be useful information but I want to know when the virtual machine was last fired up. My initial thought was to check the timestamp on the virtual machine configuration file. But it is possible for someone to adjust the configuration without actually starting the virtual machine. Thinking about it, the best solution would be to look at the timestamp on the VHD or VHDX file. This assumes that you have Windows file system access to the associated disk files. Since a virtual machine might have multiple associated hard disk files, I decided to simply check the first one in the array, working under the assumption that this is an active drive. The disk file should be updated whenever the virtual machine is running so looking at the timestamp of the disk file should tell me when the virtual machine was last used. Here’s one way.

All I’ve done is create a custom property called LastUse which gets the first hard drive from the HardDrives property and then retrieves the LastWriteTime property. You can see my result in Figure 2

Figure 2

As you can see I have a couple virtual machines missing hard disk files. This could be a configuration issue or perhaps a sign that these machines are obsolete. In either case I have actionable data. Dates are nice but it might also be helpful to see some aging. That is easy enough using PowerShell.

This one-line PowerShell command subtracts the creation time and last write time properties from the current time to create a TimeSpan object. I get the TotalDays property and cast it as an integer which has the effect of rounding the value as you can see in Figure 3.

Figure 3

In the grid view I clicked on the LastUseAge heading to sort. I sent output to Out-Gridview but you could have just as easily exported to a CSV file or created an HTML report. Allow me to wrap up with a PowerShell script you can run to create a last use report. This script focuses on when a virtual machine was last used which was my intent all along.

I wrote this as a script file so that you could run it remotely using Invoke-Command against your Hyper-V server from your desktop. You could easily turn this into a function and/or modify it to include additional aging information if you find that useful. The script also has comment based help. But with this script there’s no limit to what I can do with the data. For example, I can send last use information via email

Or find virtual machines that haven’t been used in over 30 days:

Results are in Figure 4.

Figure 4

Or I could simply remove the virtual machine.

Is aging information useful to you? How do you use it? What other type of management information would be beneficial in managing your Hyper-V infrastructure? I’d truly like to know. In the mean time I hope you’ll try some of these PowerShell techniques. Enjoy.