Get-Screenshot.ps1
function Get-ScreenShot { <# .Synopsis Gets a screen capture .Description Captures the current screen .Example # Capture the whole screen Get-ScreenShot .Example # Capture the current window Get-ScreenShot -OfWindow .Example # Capture a set of coordinates Get-ScreenShot -OfCoordinates 320, 240 .Link http://stackoverflow.com/questions/2969321/how-can-i-do-a-screen-capture-in-windows-powershell #> [CmdletBinding(DefaultParameterSetName='OfWholeScreen')] param( # If set, takes a screen capture of the current window [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='OfWindow')] [Switch]$OfWindow, # If set, takes a screenshot of a location on the screen. # If two numbers are passed, the screenshot will be from 0,0 to first (left), second (top) # If four numbers are passed, the screenshot will be from first (Left), second(top), third (width), fourth (height) [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='OfLocation')] [Double[]]$OfLocation, # The path for the screenshot. # If this isn't set, the screenshot will be automatically saved to a file in the current directory named ScreenCapture [Parameter(ValueFromPipelineByPropertyName=$true)] [string] $Path, # The image format used to store the screen capture [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateSet('PNG', 'JPEG', 'TIFF', 'GIF', 'BMP')] [string] $ImageFormat = 'JPEG', # The time before and after each screenshot [Parameter(ValueFromPipelineByPropertyName=$true)] [Timespan]$ScreenshotTimer = "0:0:0.125" ) begin { Add-Type -AssemblyName System.Drawing, System.Windows.Forms $saveScreenshotFromClipboard = { if ([Runspace]::DefaultRunspace.ApartmentState -ne 'STA') { # The clipboard isn't accessible in MTA, so save the image in background runspace $cmd = [PowerShell]::Create().AddScript({ $bitmap = [Windows.Forms.Clipboard]::GetImage() $bitmap.Save($args[0], $args[1], $args[2]) $bitmap.Dispose() }).AddParameters(@("${screenCapturePathBase}${c}.$ImageFormat",$Codec, $ep)) $runspace = [RunspaceFactory]::CreateRunspace() $runspace.ApartmentState = 'STA' $runspace.ThreadOptions = 'ReuseThread' $runspace.Open() $cmd.Runspace = $runspace $cmd.Invoke() $runspace.Close() $runspace.Dispose() $cmd.Dispose() } else { $bitmap = [Windows.Forms.Clipboard]::GetImage() $bitmap.Save("${screenCapturePathBase}${c}.$ImageFormat", $Codec, $ep) $bitmap.Dispose() } } } process { #region Codec Info $Codec = [Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where-Object { $_.FormatDescription -eq $ImageFormat } $ep = New-Object Drawing.Imaging.EncoderParameters if ($ImageFormat -eq 'JPEG') { $ep.Param[0] = New-Object Drawing.Imaging.EncoderParameter ([System.Drawing.Imaging.Encoder]::Quality, [long]100) } #endregion Codec Info #region PreScreenshot timer if ($ScreenshotTimer -and $ScreenshotTimer.TotalMilliseconds) { Start-Sleep -Milliseconds $ScreenshotTimer.TotalMilliseconds } #endregion Prescreenshot Timer #region File name if (-not $Path) { $screenCapturePathBase = "$pwd\ScreenCapture" } else { $screenCapturePathBase = $Path } $c = 0 while (Test-Path "${screenCapturePathBase}${c}.$ImageFormat") { $c++ } #endregion if ($psCmdlet.ParameterSetName -eq 'OfWindow') { [Windows.Forms.Sendkeys]::SendWait("%{PrtSc}") #region PostScreenshot timer if ($ScreenshotTimer -and $ScreenshotTimer.TotalMilliseconds) { Start-Sleep -Milliseconds $ScreenshotTimer.TotalMilliseconds } #endregion Postscreenshot Timer . $saveScreenshotFromClipboard Get-Item -ErrorAction SilentlyContinue -Path "${screenCapturePathBase}${c}.$ImageFormat" } elseif ($psCmdlet.ParameterSetName -eq 'OfLocation') { if ($OfLocation.Count -ne 2 -and $OfLocation.Count -ne 4) { Write-Error "Must provide either a width and a height, or a top, left, width, and height" return } if ($OfLocation.Count -eq 2) { $bounds = New-Object Drawing.Rectangle -Property @{ Width = $OfLocation[0] Height = $OfLocation[1] } } else { $bounds = New-Object Drawing.Rectangle -Property @{ X = $OfLocation[0] Y = $OfLocation[1] Width = $OfLocation[2] Height = $OfLocation[3] } } $bitmap = New-Object Drawing.Bitmap $bounds.width, $bounds.height $graphics = [Drawing.Graphics]::FromImage($bitmap) $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size) #region PostScreenshot timer if ($ScreenshotTimer -and $ScreenshotTimer.TotalMilliseconds) { Start-Sleep -Milliseconds $ScreenshotTimer.TotalMilliseconds } #endregion Postscreenshot Timer $bitmap.Save("${screenCapturePathBase}${c}.$ImageFormat", $Codec, $ep) $graphics.Dispose() $bitmap.Dispose() Get-Item -ErrorAction SilentlyContinue -Path "${screenCapturePathBase}${c}.$ImageFormat" } elseif ($psCmdlet.ParameterSetName -eq 'OfWholeScreen') { [Windows.Forms.Sendkeys]::SendWait("{PrtSc}") #region PostScreenshot timer if ($ScreenshotTimer -and $ScreenshotTimer.TotalMilliseconds) { Start-Sleep -Milliseconds $ScreenshotTimer.TotalMilliseconds } #endregion Postscreenshot Timer . $saveScreenshotFromClipboard Get-Item -ErrorAction SilentlyContinue -Path "${screenCapturePathBase}${c}.$ImageFormat" } } } |