#requires -version 2.0 # ----------------------------------------------------------------------------- # Script: Out-CompressedFile.ps1 # Author: Jeffery Hicks # http://jdhitsolutions.com/blog # Date: 12/6/2010 # Keywords: WMI, Out-File # Comments: Send output to a compressed text file. This uses NTFS compression # on a per file basis. # # # "Those who forget to script are doomed to repeat their work." # # **************************************************************** # * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * # * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * # * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * # * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * # **************************************************************** # ----------------------------------------------------------------------------- Function Out-CompressedFile { <# .Synopsis Send output to a compressed text file .Description This function is a wrapper for Out-File that redirects output to a compressed text file. File compression is done using the Compress() method of the WMI CIM_DATAFILE class. This will only work if the underlying file system is NTFS. If the file can't be compressed, the function will continue without it. You can append to an existing file. If it is not already compressed, it will be. .Parameter FilePath The file name. If you dont' specify a full path, the current working directory will be used. .Parameter InputObject The PowerShell objects you want to redirect. .Parameter Append Append output an existing file. The file must already exist or an exception will be thrown. If the file is not already compressed, it will be. .Example PS C:\Work\> dir $env:temp -recurse | out-compressedfile mytemp.txt Redirect the directoty listing of %TEMP% to compressed file "c:\work\mytemp.txt" .Example PS C:\> invoke-command {get-eventlog -list} -comp (get-content computers.txt) | out-compressedfile "c:\work\elogs.txt" Run a command on a group of remote computers and save the results to a compressed file. .Notes NAME: Out-CompressedFile VERSION: 1.0 AUTHOR: Jeffery Hicks LASTEDIT: 12/06/2010 Learn more with a copy of Windows PowerShell 2.0: TFM (SAPIEN Press 2010) .Link Http://jdhitsolutions.com/blog .Link Out-File Out-Printer Out-Null Out-Host Tee-Object .Inputs Any object or objects .Outputs None #> [cmdletBinding(SupportsShouldProcess=$True)] Param( [Parameter(Position=0,Mandatory=$True,HelpMessage="Enter a file path and name", ValueFromPipeline=$False)] [ValidateNotNullorEmpty()] [string]$FilePath, [Parameter(Position=1,Mandatory=$False,ValueFromPipeline=$True)] [psobject]$InputObject, [switch]$Append ) Begin { Write-Verbose -Message "$(Get-Date) Starting $($myinvocation.mycommand)" #get file if -append was specified if ($Append -AND (Test-Path $FilePath)) { Write-Verbose -Message "$(Get-Date) Appending to $Filepath" #get full path if (-Not $FilePath.Contains("\")) { $FilePath=(Get-Item $filePath).fullname } } elseif (-Not $Append) { #otherwise, create an empty file Write-Verbose -Message "$(Get-Date) Creating $FilePath" #if just a file name, then use the current working directory" if (-not $FilePath.Contains("\")) { Write-Verbose -Message "$(Get-Date) Using current working directory $PWD" $FilePath=Join-Path -Path (Get-item $pwd).FullName -ChildPath $FilePath } if ($pscmdlet.ShouldProcess($filepath)) { Try { #Create the file $f=[System.IO.File]::Create($filepath) $f.Close() #get the full file name $FilePath=$f.Name } #close Try Catch { Write-Warning "Failed to create $Filepath" Write-Error $_ Exit } #close Catch } #close if should process } #close elseif not $append else { Write-Error "Failed to find $filepath. You can only append to an existing file." Exit } Write-Verbose -Message "$(Get-Date) Full path is $FilePath" #replace \ with \\ for WMI $wmipath=$filePath.Replace("\","\\") Write-Verbose -Message "$(Get-Date) Getting $wmipath" #check and see if file is already compressed $CIMFile=Get-WmiObject -Class CIM_DATAFILE -filter "Name='$wmipath'" if (-Not $CIMFile.Compressed) { #if not, compress it if ($pscmdlet.ShouldProcess("$Filepath")) { Write-Verbose -Message "$(Get-Date) Compressing $Filepath" $rc=$CIMFile.Compress() if ($rc.ReturnValue -ne 0) { Write-Warning "Failed to compress $Filepath. Continuing without it." } } } #close if not compressed #initialize a variable to hold all the input Write-Verbose -Message "$(Get-Date) Initializing data variable" $data=@() } #close Begin Process { Foreach ($item in $InputObject) { $data+=$item }#close Foreach } #close process End { Write-Verbose -Message "$(Get-Date) Sending output to $FilePath" #data will always be appended because the file always exists, even it is empty $data | Out-File -FilePath $Filepath -append Write-Verbose -Message "$(Get-Date) Ending $($myinvocation.mycommand)" } #close End } #end Function #OPTIONAL: Create an alias #Set-Alias -Name ocf -Value Out-CompressedFile