Take multiple screenshots

This script gets the dimensions of the users working display area and takes screenshots. The screenshots can be saved as a BMP, JPG or PNG in a location of choice.

Version: 1.2.2
Created: 2019-03-13T00:05:27.757
Modified: 2019-03-31T10:04:14.373
Creator: Ton de Vreede
Downloads: 58
The Script Copy Script Copied to clipboard

$ErrorActionPreference = ‘Stop’
<# .SYNOPSIS This script will take multiple screenshots of all displays of the user session. .DESCRIPTION This script gets the dimensions of the users working display area and takes screenshots. The screenshots can be saved as a BMP, JPG or PNG in a location of choice. .PARAMETER strScreenShotPath The location the screenshot should be saved, without a trailing backslash (ie. \serversaharescreenshots). Environment variables such as %USERPROFILE% may be used. .PARAMETER strImageType The desired screenshot format. BMP --> Large, no compression (only included for compatibility)
JPG –> Smallest, compression artifacts
PNG –> Larger than JPG, but losslesscompression, default

.PARAMETER intScreenShotAmount
The amount of screenshots to take.

.PARAMETER intScreenShotInterval
The time between each screenshot, in seconds.

Example is not relevant as this script will be called through ControlUp Console

The working display area of a session is affected by the Scaling choice in Display settings. For example, a user
display may be 1920×1080 with 125% scaling will result in a 1536×864 screenshot
If the screenshots are written to a shared location make sure users can write and modify in that location, but not
read to make sure they cannot open other users’s screenshots.

[string]$strScreenShotPath = $args[0]
[string]$strImageType = $args[1]
[int]$intScreenShotAmount = $args[2]
# Sleeptimer uses milliseconds, convert now
[int]$intScreenShotInterval = ($args[3] * 1000)

Function Feedback {
Param (
[Parameter(Mandatory = $true,
Position = 0)]
[Parameter(Mandatory = $false,
Position = 1)]

# This function provides feedback in the console on errors or progress, and aborts if error has occured.
If (!$error -and !$Oops) {
# Write content of feedback string
Write-Host $Message -ForegroundColor ‘Green’

# If an error occured report it, and exit the script with ErrorLevel 1
Else {
# Write content of feedback string but to the error stream

# Display error details
If ($Exception) {
$Host.UI.WriteErrorLine(“Exception detail:`n$Exception”)

# Exit errorlevel 1
Exit 1

function Save-BitmapObject {
param (
[parameter(Mandatory = $true,
position = 0)]
[parameter(Mandatory = $true,
position = 1)]
[parameter(Mandatory = $true,
position = 2)]
switch ($FileType) {
“BMP” { $Bitmap.Save(“$FilePathAndName”, ([System.Drawing.Imaging.ImageFormat]::Bmp)) }
“PNG” { $Bitmap.Save(“$FilePathAndName”, ([System.Drawing.Imaging.ImageFormat]::Png)) }
“JPG” { $Bitmap.Save(“$FilePathAndName”, ([System.Drawing.Imaging.ImageFormat]::Jpeg)) }

# Check all the arguments have been passsed
<#if ($args.Count -ne 4) { Feedback -Message 'The script did not get enough arguments from the Console.' -Oops }#>

# Set filename
[string]$strNow = (Get-Date).ToString(“yyyyMMdd-HHmmss”)
$strScreenShotFileName = “$strNow-%COMPUTERNAME%-%USERNAME%”

# Take screenshot(s) and save them
# Load the assemblies required for using screen and form calls
try {
[System.Reflection.Assembly]::LoadWithPartialName(“System.Drawing”) | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”) | Out-Null
catch {
Feedback -Message ‘Required assemblies could not be loaded.’ -Oops

# Get the bounds of the entire display area
try {
$Screens = [System.Windows.Forms.Screen]::AllScreens

[int]$intRightMostMonitorStart = $screens.Bounds.X | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum
[int]$intWidth = $intRightMostMonitorStart + ($Screens | Where-Object { $_.Bounds.X -eq $intRightMostMonitorStart }).Bounds.Width

[int]$intTopMostMonitorStart = $screens.Bounds.Y | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum
[int]$intHeight = $intTopMostMonitorStart + ($Screens | Where-Object { $_.Bounds.X -eq $intTopMostMonitorStart }).Bounds.Height
catch {
Feedback -Message ‘The dimensions of the entire display area could not be retreived.’ -Oops

# Take the screenshot
try {

$bmpScreenShot = New-Object System.Drawing.Bitmap $intWidth, $intHeight
$sizScreenShot = New-Object System.Drawing.Size $intWidth, $intHeight
$imgScreenshot = [System.Drawing.Graphics]::FromImage($bmpScreenShot)
[datetime]$dtScreenShot = Get-Date
$imgScreenShot.CopyFromScreen(0, 0, 0, 0, $sizScreenShot)
catch {
Feedback -Message ‘There was a problem taking the screenshot.’ -Oops

# Save the first screenshot to desired path. Change path to %TEMP% if chosen path can’t be written to
try {
$strFilePathAndName = ([System.Environment]::ExpandEnvironmentVariables(“$strScreenShotPath$strScreenShotFileName”))
Save-BitmapObject -Bitmap $bmpScreenShot -FilePathAndName “$strFilePathAndName-1.$strImageType” -FileType $strImageType
catch {
# Failure perhaps because of filepath problem, revert to %TEMP% if this was not the filepath already
if ($strScreenShotPath -ne ‘%TEMP%’) {
# Clear the error raised by first save attempt failure

# Try saving to %TEMP% instead
try {
$strFilePathAndName = ([System.Environment]::ExpandEnvironmentVariables(“%TEMP%$strScreenShotFileName”))
Save-BitmapObject -Bitmap $bmpScreenShot -FilePathAndName “$strFilePathAndName-1.$strImageType” -FileType $strImageType
catch {
Feedback -Message ‘Screenshots could not be saved.’ -Oops
else {
# The file path the screenshot was supposed to be saved to was already %TEMP%, so something else was going on.
Feedback -Message ‘Screenshots could not be saved.’ -Oops

# Everything seems to be working fine, take more screenshots and save them if more than one was specified
If ($intScreenShotAmount -gt 1) {
for ($i = 2; $i -le $intScreenShotAmount; $i++) {
# Calculate the interval, based on the time the CopyFromScreen and Save file took. If it took longer than then screenshot interval set the sleep timer to 0 seconds.
[int]$intSleepMilliseconds = ([timespan](New-TimeSpan -Start $dtScreenShot -End $(Get-Date))).TotalMilliseconds

# Test if less time has passed than sepcified interval, if so sleep remainder of time
if ($intSleepMilliseconds -lt $intScreenShotInterval) { Start-Sleep -Milliseconds ($intScreenShotInterval – $intSleepMilliseconds) }

# Interval has passed, set datetime of screenshot, take the screenshot and save it
$dtScreenShot = Get-Date
$imgScreenShot.CopyFromScreen(0, 0, 0, 0, $sizScreenShot)

# Save it
Save-BitmapObject -Bitmap $bmpScreenShot -FilePathAndName “$strFilePathAndName-$($i).$($strImageType)” -FileType $strImageType
else {
Feedback -Message “Screenshot saved to $strFilePathAndName-1.$strImageType”
Exit 0

# Script has not exited, so multiple screenshots have been taken.
Feedback -Message “Screenshots saved to $([System.Environment]::ExpandEnvironmentVariables(“$strScreenShotPath”))”


Get Your Download Link

Gain access to ControlUp from your PC. Register and get a link to start your Free Trial.