Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesTo capture one Windows application window with PowerShell, obtain that window’s handle (HWND), read its screen rectangle with Win32 GetWindowRect, copy those pixels with .NET’s Graphics.CopyFromScreen, and save the bitmap as PNG. The script below performs the bounds and capture steps; you supply the correct HWND for the window you want.
What this method captures
This approach is coordinate-based. GetWindowRect returns the target window’s screen coordinates, and CopyFromScreen copies whatever is currently rendered in that rectangle into a bitmap. It does not retrieve an application’s private, off-screen surface.
The lower-right values in a Win32 RECT are exclusive, so width is Right - Left and height is Bottom - Top. A window must be represented on the current desktop for the copied pixels to show the expected content. A covered or minimized window can produce an obstructed or unusable image.
Prerequisites and target selection
- Windows PowerShell or PowerShell 7 running on Windows.
- Permission to load
System.Drawingand call User32 APIs. - A valid HWND for the intended window.
- A visible desktop if you need the pixels currently displayed on screen.
Window selection and image capture are separate operations. A process can expose several windows, and a process’s main-window handle may point to a parent while the dialog you need has another handle. Never treat a zero or invalid handle as a valid target; verify the handle and, when possible, inspect the resulting image.
#1 Best Overall
- Book - powershell for sysadmins: workflow automation made easy
- Language: english
- Binding: paperback
Complete PowerShell script
The following is an illustrative implementation of the documented API signatures. Add your own HWND-resolution logic before the capture block. It includes validation, disposal of GDI+ objects, and a post-save existence check.
Add-Type -AssemblyName System.Drawing
if (-not ('WindowCaptureNative' -as [type])) {
Add-Type @'
using System;
using System.Runtime.InteropServices;
public static class WindowCaptureNative {
[StructLayout(LayoutKind.Sequential)]
public struct RECT { public int Left, Top, Right, Bottom; }
[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
}
'@
}
# Replace this with the HWND you resolved for the desired window.
$hwnd = [IntPtr]123456
if ($hwnd -eq [IntPtr]::Zero) {
throw 'The target HWND is zero or invalid.'
}
$rect = New-Object WindowCaptureNative+RECT
if (-not [WindowCaptureNative]::GetWindowRect($hwnd, [ref]$rect)) {
$errorCode = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
throw "GetWindowRect failed. Win32 error: $errorCode"
}
$width = $rect.Right - $rect.Left
$height = $rect.Bottom - $rect.Top
if ($width -le 0 -or $height -le 0) {
throw "Window bounds are empty: $width x $height."
}
$output = Join-Path $PWD 'window.png'
$bitmap = New-Object System.Drawing.Bitmap($width, $height)
$graphics = [System.Drawing.Graphics]::FromImage($bitmap)
try {
$graphics.CopyFromScreen($rect.Left, $rect.Top, 0, 0, $bitmap.Size)
$bitmap.Save($output, [System.Drawing.Imaging.ImageFormat]::Png)
}
catch [System.ComponentModel.Win32Exception] {
throw "CopyFromScreen failed: $($_.Exception.Message)"
}
finally {
$graphics.Dispose()
$bitmap.Dispose()
}
if (-not (Test-Path -LiteralPath $output)) {
throw "The output file was not created: $output"
}
Write-Host "Saved $output ($width x $height)"
Save the file as Capture-Window.ps1, replace the example handle, and run it from the directory where you want window.png. The output dimensions are the rectangle dimensions returned by User32.
How to resolve the correct HWND
Use a window-inspection utility
For a one-off task, use a Windows window-inspection tool to identify the handle, then paste that numeric value into $hwnd. Confirm the title, process, and visible bounds before capturing. This avoids accidentally selecting a hidden helper window or a parent when the desired content is in a dialog.
Resolve handles in your own automation
In a repeatable workflow, enumerate top-level windows and match a title, process, or other property, then pass the resulting handle to GetWindowRect. Keep the selection rule explicit: titles can change, multiple instances can exist, and localized Windows builds may use different text. If the application opens a secondary dialog, enumerate again rather than assuming the main handle is still correct.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Invisible borders, DPI, and coordinate errors
On Windows Vista and later, GetWindowRect can include invisible resize borders. That can make the PNG slightly larger than the visible frame. For visible-frame bounds, Microsoft recommends the Desktop Window Manager attribute DWMWA_EXTENDED_FRAME_BOUNDS. Those DWM bounds have different DPI behavior from GetWindowRect; do not mix values from the two APIs without accounting for their coordinate spaces.
Per-monitor DPI scaling can also make a capture appear offset or incorrectly sized when a script and target window use different DPI awareness. Keep the bounds API and the copy coordinates in the same desktop coordinate system, and test on the monitor where the target normally appears.
What can make the image differ from the window
- Another window covers it:
CopyFromScreencopies the covering pixels. - The window is minimized: its normal content may not be present in the desktop region.
- The window is on another virtual desktop: the current desktop may contain different pixels.
- Protected or restricted content: some applications deliberately prevent normal screen capture.
- Window movement during capture: the rectangle can become stale between reading bounds and copying pixels.
For these cases, inspect the PNG instead of assuming that a successful API call means the desired application surface was captured.
Safer production handling
Validate before allocating
Check the HWND, the return value from GetWindowRect, and positive width and height before creating a bitmap. This prevents invalid dimensions from reaching GDI+.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Always dispose GDI+ objects
Graphics and Bitmap hold native resources. The finally block releases them even when copying or saving throws an exception.
Use deterministic output paths
An absolute path or a known working directory makes scheduled jobs easier to diagnose. After saving, check that the file exists and report its dimensions and path to the caller.
Rank #3
Manual and application-level alternatives
Snipping Tool Window mode
For a manual one-off, open Windows Snipping Tool, start a new snip, choose Window, and select the target. Windows also exposes an ms-screenclip://capture/image?window protocol that can launch the interactive window-capture mode. This is user-driven, so it does not provide automatic HWND selection.
Windows.Graphics.Capture
Applications that need a display or application-window capture surface can integrate Windows.Graphics.Capture and present its system picker. Microsoft documents support on Windows desktop devices and Windows Mixed Reality immersive headsets. It requires application integration rather than a turnkey PowerShell command, but it is a better fit when you need a capture surface instead of copying visible desktop coordinates.
Troubleshooting
“GetWindowRect failed”
The handle may be stale, zero, invalid, or no longer refer to a window. Re-resolve it immediately before capture, verify the selected process and title, and inspect the Win32 error code emitted by the script.
“Window bounds are empty”
The window may be closing, hidden, or returning unusable geometry. Confirm that Right is greater than Left and Bottom is greater than Top, then retry after the window is fully shown.
CopyFromScreen throws a Win32Exception
Check that the desktop coordinates are valid, the bitmap is disposed only after the copy, and the target is on the active desktop. Catch the exception, log its message, and avoid leaving partially written output.
Rank #4
The PNG includes a border or shadow
This is consistent with invisible resize borders or non-client frame pixels returned by GetWindowRect. Use a visible-frame strategy based on DWM bounds, while handling its different DPI rules, or crop the saved image after verifying the dimensions.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →The screenshot shows another window
The method copies screen pixels, not an isolated application buffer. Bring the target forward, restore it if minimized, prevent movement during capture, or switch to an application capture API when unobstructed content is required.
The script cannot load System.Drawing
Run on Windows with the appropriate .NET/PowerShell desktop components installed. Confirm the assembly load succeeds before creating the bitmap; on systems where the assembly is unavailable, use Snipping Tool or integrate Windows.Graphics.Capture instead.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Performance, reliability, and format choices
Capture time is mainly affected by the window’s pixel dimensions and desktop composition. A large, high-DPI window creates a larger bitmap and file. PNG is lossless and preserves text well; if you add another encoder, choose JPEG only when smaller files matter more than sharp UI edges.
For scheduled jobs, resolve the HWND immediately before each capture, ensure the window is in a stable state, write to a temporary filename, and rename it after a successful save. This prevents consumers from reading a partially written file. Keep logs containing the selected handle, rectangle, output path, and exception text.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
Or skip the browser setup
If you need website screenshots rather than a local Windows desktop window, ScreenshotNeo provides a single HTTP request for PNG, JPEG, WebP, or PDF output. Its cleanup steps accept cookie and consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
See the ScreenshotNeo documentation for all options, including full-page lazy-image loading, CSS-selector element capture, device presets, retina scale, PDF margins and page ranges, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture, usage data, and the OpenAPI specification.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 shots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account to try it.
Frequently Asked Questions
Can this script capture a window that is behind another window?
No. CopyFromScreen reads the pixels currently visible in the desktop rectangle, so an obstructing window can appear in the result.
Why is my screenshot larger than the visible frame?
GetWindowRect may include invisible resize borders. A DWM extended-frame query or a verified post-capture crop is needed for visible-frame dimensions.
Should I use Snipping Tool or PowerShell?
Use Snipping Tool for an interactive one-off and PowerShell when you need repeatable, scriptable output.
The Bottom Line
PowerShell can reliably automate a specific window capture when you select the right HWND, validate its rectangle, and accept that CopyFromScreen captures visible desktop pixels. Use a capture-surface API when you need content independent of occlusion or window state.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

