Change Image Size Using Microsoft PowerShell

Ray Turner
Ray Turner used Ask the Experts™
I have a set of photos that where taken using a typical 35mm camera to be displayed on a website.  The jpg's are quite large and I'd like to reduced the size of each of the photos before uploading them.  Is there a to shrink the size of the files using Microsoft PowerShell?

If so,  please provide the code.

Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Sam Simon NasserIT Support Professional

if you have Photoshop, you can do batch processing (
or you use photo resizer software (
in my opinion, you don't need complex code to do that!
NoahHardware Tester and Debugger

Hi there! :)

You may refer to this file for an example. You can view and edit it with Notepad++.

Shaun VermaakSenior Consultant
Awarded 2017
Distinguished Expert 2018

I have used TinyPNG API (yes it supports JPEG), 500 free per month and you do not need to resize or lose quality
Ray TurnerSenior Consultant


For my clarification.  I only want to reduce the size of the file without changing its dimensions.  Can this be done with the PowerShell script?
Shaun VermaakSenior Consultant
Awarded 2017
Distinguished Expert 2018

I understand your requirements. That is what TinyPNG is for. Visit their site
NoahHardware Tester and Debugger

Sorry, I misunderstood your question. The Powershell script resizes the resolution.
Most Valuable Expert 2018
Distinguished Expert 2018
PowerShell approach, using .NET; save as Convert-ImageQuality.ps1 or Whatever.ps1
Get-Help is supported, so you can run Get-Help .\Convert-ImageQuality.ps1 -ShowWindow once the script is saved.
Reduces the size of an image by lowering its quality and saving it as .jpg.
The function Convert-ImageQuality reduces the size of an image by lowering its quality and saving it as .jpg.
By default, the converted images are by default stored in the original directory, with a suffix indicating the quality used.
An output directory to store the converted pictures in can be specified using the -Destination parameter.
The path to the image(s) to convert. You can specify a folder or file names, or objects returned from Get-item or Get-ChildItem (anything Get-ChildItem accepts as input).
Files that can not be opened as image will be skipped, and a warning written.
You can pipe objects to this parameter.
The level of compression (0-100).
The lower the number specified, the higher the compression and therefore the lower the quality of the image. Zero would give you the lowest quality image and 100 the highest.
The suffix that will be attached to the original file's BaseName.
Use the placeholder %Quality% to insert the selected quality as a three-digit number with leading zeros, if required.
.PARAMETER Destination
The target directory for the converted image(s); the directory must exist before running the function.
Default is the original image's directory.
'C:\Windows\Web\Screen' | .\Convert-ImageQuality.ps1 -Quality 50 -Destination C:\Temp\Reduced -Verbose
Will save all images from 'C:\Windows\Web\Screen' to 'C:\Temp\Reduced' as jpg with a quality of 50, adding "_050" (the default suffix which adds the quality) to each file name.
Image.Save Method
[CmdletBinding(SupportsShouldProcess=$true, DefaultParameterSetName='Width_Locked', ConfirmImpact='Low')]
	[Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
	[PSObject]$Path = (Get-Location -PSProvider FileSystem).Path,
	[ValidateRange(0, 100)]
	[String]$Suffix = '_%Quality%',
	[ValidateScript({Test-Path -Path $_ -PathType Container})]
Begin {
	Add-Type -AssemblyName System.Drawing
	$encoder = [System.Drawing.Imaging.Encoder]::Quality
	$encoderParams = New-Object -TypeName System.Drawing.Imaging.EncoderParameters -ArgumentList 1 
	$encoderParams.Param[0] = New-Object -TypeName System.Drawing.Imaging.EncoderParameter -ArgumentList $encoder, $Quality
	$imageCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where-Object {$_.Clsid -eq '557cf401-1a04-11d3-9a73-0000f81ef32e'}
	$targetExt = '.jpg'
	If ($Suffix) {
		$Suffix = $Suffix -replace '%Quality%', $Quality.ToString('D3')
Process {
	$Path | Get-ChildItem | ForEach-Object {
		Try {
			$item = $_
			$image = [System.Drawing.Image]::FromFile($item.FullName)
			$targetDir = If ($Destination) {$Destination} Else {$item.DirectoryName}
			If ($PSCmdlet.ShouldProcess($item.FullName, "Convert quality to $($Quality)% of the original")) {
				[void]$image.Save("$($targetDir)\$($item.BaseName)$($Suffix)$($targetExt)", $imageCodecInfo, $encoderParams)
		} Catch {
			If ($_.Exception.InnerException.StackTrace -like '*System.Drawing.Image.FromFile*') {
				Write-Warning "[$($MyInvocation.MyCommand.Name)] Not an image: '$($item.FullName)'"
			} Else {

Open in new window

Shaun VermaakSenior Consultant
Awarded 2017
Distinguished Expert 2018

Better of using TinyPNG API IMO if you want lowest size without loss in quality

Original (57kb)
Using Convert-ImageQuality.ps1  (6kb but looks crap and lost transparency)
Using TinyPNG (15kb no visual difference)
Ray TurnerSenior Consultant



Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial