Hyper-V WMI: Creating a Thumbnail Image

Hyper-V has a WMI API that will allow you to create a thumbnail image of any running or paused virtual machine.  You can create any sized thumbnail you want (640x480, 800x600, 1024x768 etc…).  Creating the image is pretty easy, you just call GetVirtualSystemThumbnailImage passing a reference to an Msvm_VirutalSystemSettingData instance and the size of the image you want…  However getting something useful from the returned data is a bit tricky…  You get an array of unit8’s that represent pixels, the API doesn’t have much choice and luckily Powershell makes this not an impossible feat.  All you have to do is create a new bitmap object and read (marshal) the pixel data into the object…  So here’s a script for you!

Windows Server 2008 - x64_running Windows Server 2008 - x64_saved
Running Virtual Machine Saved Virtual Machine

 

Powershell Script:

[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") $HyperVParent = "localhost" $HyperVGuest = "Windows Server 2008 - x64" $ImagePath = "c:\Temp" $xRes = 640 $yRes = 480 $VMManagementService = Get-WmiObject -class "Msvm_VirtualSystemManagementService" -namespace "root\virtualization" -ComputerName $HyperVParent $Vm = Get-WmiObject -Namespace "root\virtualization" -ComputerName $HyperVParent -Query "Select * From Msvm_ComputerSystem Where ElementName='$HyperVGuest'" $VMSettingData = Get-WmiObject -Namespace "root\virtualization" -Query "Associators of {$Vm} Where ResultClass=Msvm_VirtualSystemSettingData AssocClass=Msvm_SettingsDefineState" -ComputerName $HyperVParent $RawImageData = $VMManagementService.GetVirtualSystemThumbnailImage($VMSettingData, "$xRes", "$yRes") #| ProcessWMIJob $VMManagementService.PSBase.ClassPath "GetVirtualSystemThumbnailImage" $VMThumbnail = new-object System.Drawing.Bitmap($xRes, $yRes, [System.Drawing.Imaging.PixelFormat]::Format16bppRgb565) $rectangle = new-object System.Drawing.Rectangle(0,0,$xRes,$yRes) [System.Drawing.Imaging.BitmapData] $VMThumbnailBitmapData = $VMThumbnail.LockBits($rectangle, [System.Drawing.Imaging.ImageLockMode]::WriteOnly, [System.Drawing.Imaging.PixelFormat]::Format16bppRgb565) [System.Runtime.InteropServices.marshal]::Copy($RawImageData.ImageData, 0, $VMThumbnailBitmapData.Scan0, $xRes*$yRes*2) $VMThumbnail.UnlockBits($VMThumbnailBitmapData); $VMThumbnail $VMThumbnail.Save("$ImagePath\$HyperVGuest.jpg")

Taylor Brown
Hyper-V Integration Test Lead
https://blogs.msdn.com/taylorb

clip_image001