Skip to content

Instantly share code, notes, and snippets.

@BenjaminArmstrong
Last active May 3, 2024 17:33
Show Gist options
  • Save BenjaminArmstrong/e6e4c771b5553b6c15788a3406feb934 to your computer and use it in GitHub Desktop.
Save BenjaminArmstrong/e6e4c771b5553b6c15788a3406feb934 to your computer and use it in GitHub Desktop.
Sample PowerShell script that shows you how to create a .BMP file of the display of a Hyper-V virtual machine.
$VMName = "VM 1"
$BMPName = "C:\Users\benja\Desktop\test.bmp"
Add-Type -AssemblyName "System.Drawing"
$VMCS = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_ComputerSystem -Filter "ElementName='$($VMName)'"
# Get the resolution of the screen at the moment
$video = $VMCS.GetRelated("Msvm_VideoHead")
$xResolution = $video.CurrentHorizontalResolution[0]
$yResolution = $video.CurrentVerticalResolution[0]
function getVMScreenBMP {
param
(
$VM,
$x,
$y
)
$VMMS = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemManagementService
# Get screenshot
$image = $VMMS.GetVirtualSystemThumbnailImage($VMCS, $x, $y).ImageData
# Transform into bitmap
$BitMap = New-Object System.Drawing.Bitmap -Args $x,$y,Format16bppRgb565
$Rect = New-Object System.Drawing.Rectangle 0,0,$x,$y
$BmpData = $BitMap.LockBits($Rect,"ReadWrite","Format16bppRgb565")
[System.Runtime.InteropServices.Marshal]::Copy($Image, 0, $BmpData.Scan0, $BmpData.Stride*$BmpData.Height)
$BitMap.UnlockBits($BmpData)
return $BitMap
}
(getVMScreenBMP $VMCS $xResolution $yResolution).Save($BMPName)
@jdhitsolutions
Copy link

As a PowerShell best practice you shouldn't really reference variables outside the function scope. Here's my fork of your script, although I'm still testing a few things. https://gist.github.com/jdhitsolutions/78d71ceeefb54675a7c53a13ac861780

@BenjaminArmstrong
Copy link
Author

Good point - I have updated to code to be cleaner on scoping

Copy link

ghost commented Jun 9, 2016

I have an error with a new version of the script:

"A Using variable cannot be retrieved. A Using variable can be used only with Invoke-Command, Start-Job, or InlineScript in the script workflow. When it is used with Invoke-Command, the Using variable is valid only if the script block is invoked on a remote computer."

I have Powershell v5.0.10586.117 on the host (2012 R2) and 2012 R2 guest from Image Factory (https://github.com/BenjaminArmstrong/Hyper-V-PowerShell/tree/master/Image-Factory)

@BenjaminArmstrong
Copy link
Author

Gah! Okay, take three. This one should work.

Copy link

ghost commented Jun 16, 2016

Perfect! Thank you.

@AlexJamesHaines
Copy link

Awesome, works great still on Server 2019 :)

@MakotoE
Copy link

MakotoE commented Mar 12, 2024

This is supposed to be run on the host machine, not inside the guest machine, right?

@citelao
Copy link

citelao commented May 3, 2024

I can confirm this works on Windows PowerShell, but not modern PowerShell (powershell.exe, not pwsh.exe), at least on my machine. This is awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment