PoshCode Archive  Artifact [8479ef9f1a]

Artifact 8479ef9f1a7889b59a8e5cb575f08e9e6e56fc61865c6ba508885d1775587f09:

  • File New-Zip.ps1 — part of check-in [d0844c40fa] at 2018-06-10 13:10:19 on branch trunk — PowerZip – PowerShell Module that allows you to zip files (user: ChristopheCREMON size: 9539)

# encoding: ascii
# api: powershell
# title: New-Zip
# description: PowerZip – PowerShell Module that allows you to zip files
# version: 0.1
# type: function
# author: ChristopheCREMON
# license: CC0
# function: New-Zip
# x-poshcode-id: 2440
# x-derived-from-id: 3211
# x-archived: 2017-01-29T04:25:01
# x-published: 2011-01-05T05:16:00
#
# - SYNOPSIS
# Create a Zip File from any files piped in.
# - DESCRIPTION
# Requires that you have the SharpZipLib installed, which is available from
# http://www.icsharpcode.net/OpenSource/SharpZipLib/
# - NOTES
# File Name  : PowerZip.psm1 
# Author     : Christophe CREMON (uxone) – http://powershell.codeplex.com
# Requires   : PowerShell V2
# - PARAMETER Source
# Set the name of the source to zip (file or directory)
# - PARAMETER ZipFile
# Set the name of the zip file to create
# - PARAMETER Recurse
# Browse the source recursively
# - PARAMETER Include
# Include only items you specify
# - PARAMETER Exclude
# Exclude items you specify
# - PARAMETER AbsolutePaths
# Preserve the absolute path name of each item in the zip container
# - PARAMETER DeleteAfterZip
# Delete source items after successful zip
# - EXAMPLE
# New-Zip -Source C:\Temp -ZipFile C:\Archive\Scripts.zip -Include *.ps1 -DeleteAfterZip
# Copies all PS1 files from the C:\Temp directory to C:\Archive\Scripts.zip and delete them after successful ZIP
#
Function New-Zip
{
<#
.SYNOPSIS
	Create a Zip File from any files piped in.
.DESCRIPTION
	Requires that you have the SharpZipLib installed, which is available from
	http://www.icsharpcode.net/OpenSource/SharpZipLib/
.NOTES
	File Name  : PowerZip.psm1 
	Author     : Christophe CREMON (uxone) - http://powershell.codeplex.com
	Requires   : PowerShell V2
.PARAMETER Source
	Set the name of the source to zip (file or directory)
.PARAMETER ZipFile
	Set the name of the zip file to create
.PARAMETER Recurse
	Browse the source recursively
.PARAMETER Include
	Include only items you specify
.PARAMETER Exclude
	Exclude items you specify
.PARAMETER AbsolutePaths
	Preserve the absolute path name of each item in the zip container
.PARAMETER DeleteAfterZip
	Delete source items after successful zip
.EXAMPLE
	New-Zip -Source C:\Temp -ZipFile C:\Archive\Scripts.zip -Include *.ps1 -DeleteAfterZip
	Copies all PS1 files from the C:\Temp directory to C:\Archive\Scripts.zip and delete them after successful ZIP
#>
	param (
	[ValidateNotNullOrEmpty()]
		[Parameter(
    		Mandatory = $true)
    	]
			[string] $Source,
		[Parameter(
    		Mandatory = $true)
    	]
			[string] $ZipFile,
		[switch] $Recurse,
		[array] $Include,
		[array] $Exclude,
		[switch] $AbsolutePaths,
		[switch] $DeleteAfterZip )
	
	$LoadAssembly = [System.Reflection.Assembly]::LoadWithPartialName("ICSharpCode.SharpZipLib")
	if ( -not $LoadAssembly ) { throw "! Assembly not found {ICSharpCode.SharpZipLib}" }
	
	if ( $Source -match "\*" )
	{
		throw "! Please use -Recurse with -Include instead of ""*"""
	}
	
	$Source = $Source -replace "\\$|\/$",""
	
	$CheckSource = Get-Item -Path $Source -ErrorAction SilentlyContinue
	if ( -not $CheckSource ) { throw "! Source not found {$Source}" }
	else
	{
		if ( $CheckSource.psIsContainer )
		{
			$RootPath = ( Resolve-Path -Path $Source -ErrorAction SilentlyContinue ).Path
		}
		else
		{
			$RootPath = ( Resolve-Path -Path $Source -ErrorAction SilentlyContinue ).Path
			if ( $RootPath )
			{
				$RootPath = Split-Path -Path $RootPath -ErrorAction SilentlyContinue
			}
		}
	}
	
	if ( $ZipFile -notmatch "\.zip$" ) { $ZipFile = $ZipFile -replace "$",".zip" }
	if ( $ZipFile -match "\*" )
	{
		throw "! Incorrect zip file name {$ZipFile}"
	}
	if ( $Recurse -eq $true ) { $RecurseArgument = "-Recurse" }
	if ( $AbsolutePaths -eq $true ) { $AbsolutePathsArgument = "-AbsolutePaths" }
	if ( $DeleteAfterZip -eq $true ) { $DeleteAfterZipArgument = "-DeleteAfterZip" }
	if ( $Include )
	{
		$Include = $Include -join ","
		$IncludeArgument = "-Include $Include"
		$Source = $Source+"\*"
	}
	if ( $Exclude )
	{
		$Exclude = $Exclude -join ","
		$ExcludeArgument = "-Exclude $Exclude"
	}
	
	$GetCommand = "Get-ChildItem -Path '$Source' $RecurseArgument $IncludeArgument $ExcludeArgument -Force"
	$ItemsToZip = Invoke-Expression -Command $GetCommand
	$SizeBeforeZip = ( $ItemsToZip | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue ).Sum
	$SizeBeforeZipInMB = $SizeBeforeZip | ForEach-Object { "{0:N2}" -f ($_ / 1MB) }
	if ( -not $SizeBeforeZip )
	{
		Write-Output "NOTHING TO ZIP"
		return $true
		break
	}
		
	$CreateZIPContainer = New-Item -ItemType File -Path $ZipFile -Force -ErrorAction SilentlyContinue
	if ( -not $CreateZIPContainer ) { throw "! Unable to create ZIP container {$ZipFile}" }
	else { $ZipFile = ( Resolve-Path -Path $ZipFile -ErrorAction SilentlyContinue ).Path }
	
	$oZipOutputStream = New-Object -TypeName ICSharpCode.SharpZipLib.Zip.ZipOutputStream([System.IO.File]::Create($ZipFile))	
	
	[byte[]] $Buffer = New-Object Byte[] 4096
	
	$StartTime = Get-Date
	Write-Output "`n===================================`n=> Start Time : $($StartTime.ToString(""dd/MM/yyyy-HH:mm:ss""))`n"	
	Write-Output "TOTAL SIZE BEFORE ZIP : {$SizeBeforeZipInMB MB}`n"
	
	foreach ( $Item in $ItemsToZip )
	{
		if ( $Item.FullName -ne $ZipFile )
		{
			if ( Test-Path ( $Item.FullName ) -ErrorAction SilentlyContinue )
			{
				$ZipEntry = $Item.FullName
				if ( -not $AbsolutePaths )
				{
					$ReplacePath = [Regex]::Escape( $RootPath+"\" )
					$ZipEntry = $Item.FullName -replace $ReplacePath,""
				}				
				if ( $Item.psIsContainer -eq $true )
				{
					if ( $Recurse -eq $true )
					{
						Write-Output "Processing ZIP of Directory {$($Item.FullName)} ..."
						$OldErrorActionPreference = $ErrorActionPreference
						$ErrorActionPreference = "SilentlyContinue"
						$oZipEntry = New-Object -TypeName ICSharpCode.SharpZipLib.Zip.ZipEntry("$ZipEntry/")
						$oZipOutputStream.PutNextEntry($oZipEntry)
						if ( $? -ne $true )
						{
							$ItemsNotZipped += @($Item.FullName)
							$ErrorsArray += @("! Unable to ZIP Directory {$($Item.FullName)}")
						}
						$ErrorActionPreference = $OldErrorActionPreference
					}
				}
				else
				{
					Write-Output "Processing ZIP of File {$($Item.FullName)} ..."
					$OldErrorActionPreference = $ErrorActionPreference
					$ErrorActionPreference = "SilentlyContinue"
					$FileStream = [IO.File]::OpenRead($Item.FullName)
					$oZipEntry = New-Object -TypeName ICSharpCode.SharpZipLib.Zip.ZipEntry("$ZipEntry")
					$oZipOutputStream.PutNextEntry($oZipEntry)
					[ICSharpCode.SharpZipLib.Core.StreamUtils]::Copy($FileStream,$oZipOutputStream,$Buffer)
					if ( $? -ne $true )
					{
						$ItemsNotZipped += @($Item.FullName)
						$ErrorsArray += @("! Unable to ZIP File {$($Item.FullName)}")
					}
					$FileStream.Close()
				}
			}
		}
	}
	
	$oZipOutputStream.Finish()
	$oZipOutputStream.Close()
	
	if ( $? -eq $true )
	{
		$ErrorActionPreference = $OldErrorActionPreference
		if ( $DeleteAfterZip )
		{
			$ItemsToZip | Where-Object { $ItemsNotZipped -notcontains $_.FullName } | ForEach-Object {
				if ( $_.psIsContainer -ne $true )
				{
					if ( Test-Path ( $_.FullName ) -ErrorAction SilentlyContinue )
					{
						Write-Output "Processing Delete of File {$($_.FullName)} ..."
						$RemoveItem = Remove-Item -Path $_.FullName -Force -ErrorAction SilentlyContinue
						if ( $? -ne $true )
						{
							$ErrorsArray += @("! Unable to Delete File {$($_.FullName)}")
						}
					}
				}
			}
			if ( $Recurse )
			{
				$ItemsToZip | Where-Object { $ItemsNotZipped -notcontains ( Split-Path -Parent $_.FullName ) } | ForEach-Object {
					if ( $_.psIsContainer -eq $true )
					{
						if ( Test-Path ( $_.FullName ) -ErrorAction SilentlyContinue )
						{
							Write-Output "Processing Delete of Directory {$($_.FullName)} ..."
							$RemoveItem = Remove-Item -Path $_.FullName -Force -Recurse -ErrorAction SilentlyContinue
							if ( $? -ne $true )
							{
								$ErrorsArray += @("! Unable to Delete Directory {$($_.FullName)}")
							}
						}
					}
				}
			}
		}
		Write-Output "`nZIP File Created {$ZipFile} ...`n"
	}
	else
	{
		$ErrorActionPreference = $OldErrorActionPreference
		$ErrorsArray += @("! ZIP Archive {$ZipFile} Creation Failed`n")
	}
	
	$EndTime = Get-Date
	$ExecutionTime = ($EndTime-$StartTime)
	Write-Output "`nExecution Time : $ExecutionTime`n"	
	Write-Output "=> End Time : $($EndTime.ToString(""dd/MM/yyyy-HH:mm:ss""))`n=================================`n"
	
	if ( $ErrorsArray )
	{
		Write-Output "`n[ ERRORS OCCURED ]"
		$ErrorsArray
		return $false
	}
	else
	{
		$SizeAfterZip = ( Get-Item -Path $ZipFile -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue ).Sum
		$SizeAfterZipInMB = $SizeAfterZip | ForEach-Object { "{0:N2}" -f ($_ / 1MB) }
		Write-Output "`nTOTAL SIZE AFTER ZIP : {$SizeAfterZipInMB MB}`n"
		
		$Gain = ( $SizeBeforeZip - $SizeAfterZip )
		$GainInMB = $Gain | ForEach-Object { "{0:N2}" -f ($_ / 1MB) }
		if ( $Gain -gt 0 )
		{
			$GainInPercent = (($SizeBeforeZip - $SizeAfterZip) / $SizeBeforeZip) * 100 | ForEach-Object { "{0:N2}" -f $_ }
			Write-Output "GAIN : {$GainInMB MB} ($GainInPercent %)`n"
		}
		return $true
	}
}
Export-ModuleMember -Function New-Zip