#requires -version 2.0 <# .SYNOPSIS Compress files by extension .DESCRIPTION Using WMI find files by extension that are at least 4KB in size and compress them. The script will search the C: drive by default but you can specify a path. All files that meet the filtering criteria will be compressed recursively. This script could take a long time to run. Even though the script name uses the Compress verb, you can use the -Uncompress parameter to uncompress files that meet the search criteria. NOTE: When you specify the extensions do NOT include the period. .PARAMETER Extension An array of file extensions. Do NOT include the period. .PARAMETER Path The search path. The default is C:\. .PARAMETER Size The minimum file size in bytes. The default and minimum is 4KB. Typically it doesn't make sense to compress files smaller than 4KB. .PARAMETER Computername The name of the computer to query. The default is the local host. .PARAMETER Uncompress Specify if you want to Uncompress files that meet the filtering criteria. .EXAMPLE PS C:\> c:\scripts\compress-filetype "txt,","ps1","log" -path c:\files -size 10kb Compress all TXT, PS1 and LOG files in C:\files that are greater than 10KB in size. .EXAMPLE PS C:\> $s={ >> Param([string[]]$e,$p="c:\",$sz=4kb,$c=$env:computername) >> C:\Scripts\Compress-FileType.ps1 -ext $e -path $p -size $sz -comp $c >> } >> PS C:\> start-job $s -ArgumentList @("txt","xml"),"c:\shares",10kb,"File01" Compress all TXT and XML files on \\File01 under C:\Shares that are over 10KB in size. Run this as a background job. Because of the way the script is structured, the best way is to wrap the script inside a scriptblock and run that in Start-Job. .NOTES NAME : Compress-Filetype.ps1 VERSION : 2.0 LAST UPDATED: 9/30/2011 AUTHOR : Jeff Hicks .LINK Get-WMIObject .INPUTS None .OUTPUTS Custom #> [cmdletbinding(SupportsShouldProcess=$True)] Param ( [Parameter(Mandatory=$True,HelpMessage="Enter a file extension, without the period")] [ValidateNotNullorEmpty()] [string[]]$Extension, [ValidatePattern("^[a-zA-Z]:")] [string]$Path="c:\", [ValidateScript({$_ -ge 4KB})] [int]$Size=4KB, [ValidateNotNullorEmpty()] [string]$Computername=$env:computername, [switch]$Uncompress ) Write-Verbose "Starting $($myinvocation.mycommand)" #get first two characters for drive $Drive=$Path.Substring(0,2) Write-Verbose "Connecting to drive $drive on $computername" Write-Verbose "Finding files >= than $size" #build query $extensions=$extension -as [string] #parse the extensions and build a complex OR structure for each one $extFilter="(Extension='{0}{1}" -f ($extensions.replace(" ","' OR Extension='")),"')" if ($Uncompress) { Write-Verbose "Uncompressing files" $Compress="TRUE" } else { $Compress="FALSE" } #split off the folder portion of the path, change \ to \\ $folder=$Path.Split(":")[1].Replace("\","\\") $filter="Drive='$Drive' AND Path Like '%$Folder\\%'AND Compressed='$Compress' AND FileSize >= $size AND $extFilter" #define a subset of properties to return in hopes of tweaking performance $properties="Drive,Path,Compressed,FileSize,Extension,CSName,Name" Write-Verbose "Query = $filter" Write-Progress -Activity "Compress File Types" -status "Running filter $filter on $computername" ` -currentoperation "Searching $Path. Please wait...this may take several minutes..." #capture time before the WMI Query $start=Get-Date Try { Write-Verbose "Getting files from $Path" $files=Get-WmiObject -class CIM_DATAFILE -filter $filter -Property $properties -computername $computername -ErrorAction Stop } Catch { Write-Error ("Failed to run query on $computername. Exception: {0}" -f $_.Exception.Message) } $filecount=($files | measure-object).count Write-Verbose "Found $filecount files" #define some variables for Write-Progress if ($Uncompress) { $activity="Uncompress File Types" $status="Uncompressing" } else { $activity="Compress File Types" $status="Compressing" } #only process if files were returned if ($filecount -gt 0) { #keep a running count of compressed files $iCompressed=0 $iFailures=0 $i=0 Write-Verbose "Processing files" foreach ($file in $files) { $i++ [int]$percent=($i/$filecount)*100 Write-Verbose $file.name Write-Progress -Activity $activity -Status $status -currentoperation $file.name -percentComplete $percent if ($pscmdlet.ShouldProcess($file.name)) { if ($Uncompress) { $rc=$file.Uncompress() } else { $rc=$file.Compress() } Switch ($rc.returnvalue) { 0 { $Result="The request was successful" #increment the counter $iCompressed++ #write the WMI file object to the pipeline write $file | select @{Name="Computername";Expression={$_.CSName}}, Name,FileSize,Extension Break } 2 { $Result="Access was denied." ; Break} 8 { $Result="An unspecified failure occurred."; Break} 9 { $Result="The name specified was invalid."; Break} 10 { $Result="The object specified already exists."; Break} 11 { $Result="The file system is not NTFS."; Break} 12 { $Result="The operating system is not supported."; Break} 13 { $Result="The drive is not the same."; Break} 14 { $Result="The directory is not empty."; Break} 15 { $Result="There has been a sharing violation." ; Break} 16 { $Result="The start file specified was invalid."; Break} 17 { $Result="A privilege required for the operation is not held."; Break} 21 { $Result="A parameter specified is invalid."; Break} } #end Switch #display a warning message if there was a problem if ($rc.returnvalue -ne 0) { $msg="Error compressing: {0}. {1}" -f $file.name,$Result Write-Warning $msg $iFailures++ } Write-Verbose "Result=$result" } #if should process } #foreach #get the time after all files have been compressed/uncompressed $End=Get-Date [string]$RunTime=($End=$Start) Write-Verbose "Presenting summary" Write-Progress -Activity "Compress File Types" -status "Finished" -completed $True Write-Host "`n$Status Summary" -ForegroundColor CYAN Write-Host "**************************************" -ForegroundColor CYAN Write-Host "Computer : $computername" -foregroundcolor CYAN Write-Host "File types : $extensions" -foregroundcolor CYAN Write-Host "Minimum Size : $size" -ForegroundColor CYAN Write-Host "Path : $path" -foregroundcolor CYAN Write-Host "Total Files : $filecount" -foregroundcolor CYAN Write-Host "Success : $iCompressed" -foregroundcolor CYAN Write-Host "Failures : $iFailures" -foregroundcolor CYAN Write-Host "Runtime : $Runtime" -ForegroundColor CYAN } else { Write-Warning "No matching files ($extensions) found in $Path on $computername with a minimum size of $size." } #end of script