Last active
March 4, 2021 15:19
-
-
Save bryanvine/a43fb13c8e23db6aa892a472d1d54157 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
BV-ZipUtility.ps1 | |
http://www.bryanvine.com/2017/03/powershell-script-7zipunzip-powershell.html | |
Author: Bryan Vine | |
Last updated: 03/27/2017 | |
Description: This collection of functions can be used as a module or imported in other | |
modules to replace most of the functionality of 7zip.exe and unzip.exe. | |
#> | |
#Requires -version 3 | |
Function Test-DotNet{ | |
<# | |
.SYNOPSIS | |
Checks for a specific .NET framework | |
.DESCRIPTION | |
Uses registry keys to find all installed versions of .NET framework and check that the highest version is | |
greater than or equal to a minimum level. Returns true if it is, false if it isn't. | |
.PARAMETER MinLevel | |
Minimum level of .NET framework required to return true. | |
.EXAMPLE | |
Test-DotNet | |
This will return true if .NET 4.5 or greater is installed. | |
.EXAMPLE | |
Test-DotNet -MinLevel 4.0 | |
This will return true if .NET 4.0 or greater is installed. | |
.LINK | |
http://www.bryanvine.com/2017/03/powershell-script-7zipunzip-powershell.html | |
.NOTES | |
Author: Bryan Vine | |
Last updated: 03/27/2017 | |
#> | |
[cmdletbinding()] | |
Param( | |
$MinLevel = 4.5 | |
) | |
((Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | | |
Get-ItemProperty -name Version -ErrorAction SilentlyContinue | | |
Where {$_.PSChildName -match '^(?!S)\p{L}'} | | |
Select -ExpandProperty Version -Unique | | |
Sort -Descending | Select -First 1) -ge $MinLevel) | |
} | |
function Compress-toZip{ | |
<# | |
.SYNOPSIS | |
Compresses files and folders into a zip archive. | |
.DESCRIPTION | |
Creates new a new archive or updates an existing archive from either an array of files or a directory (or array of directories). | |
Requires powershell v3+ and .NET 4.5 framework. | |
.PARAMETER Zipfile | |
Output name of new zip archive or existing name of archive. Full local path or UNC path prefered for best results. | |
.PARAMETER Source | |
Input File(s) or Directory/Directories which are to be compressed into the archive | |
.PARAMETER CompressionLevel | |
Amount of compression to apply. Greatest to least: 'Optimal','Fastest','NoCompression' | |
.PARAMETER IncludeBaseDirectory | |
Specifies when creating new zip archive to include the base folder when specifying an input directory. | |
.PARAMETER OverwriteZip | |
If an existing output zip archive exists, it will delete it first before creating a new one. | |
.EXAMPLE | |
Compress-toZip -Zipfile 'test.zip' -Source 'Backup' | |
This will create a new zip file called test.zip in the current directory with the contents of the Backup folder. | |
.EXAMPLE | |
Compress-toZip -Zipfile 'c:\temp\test.zip' -Source '\\server1\Backup' | |
This will create a new zip file called test.zip in c:\temp with the contents of the Backup share from Server1. | |
.LINK | |
http://www.bryanvine.com/2017/03/powershell-script-7zipunzip-powershell.html | |
.NOTES | |
Author: Bryan Vine | |
Last updated: 03/27/2017 | |
#> | |
[cmdletbinding()] | |
Param( | |
[ValidateNotNullorEmpty()][Parameter(Position=0,Mandatory)][String]$Zipfile, | |
[ValidateScript({Test-Path $_})][Parameter(Position=1,Mandatory)][String[]]$Source, | |
[Validateset('Optimal','Fastest','NoCompression')]$CompressionLevel = 'Optimal', | |
[switch]$IncludeBaseDirectory, | |
[switch]$OverwriteZip | |
) | |
#Check for .NET 4.5+ | |
if(!(Test-DotNet)){ | |
Write-Error "ERROR: Unable to perform zip operation, .NET 4.5+ not detected!" | |
return 1 | |
} | |
[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null | |
#Input Normalization | |
if($Zipfile -notlike '*.zip'){$Zipfile += '.zip'} | |
if($Zipfile -notlike '*\*'){$Zipfile = $pwd.Path + '\' + $Zipfile} | |
if($Zipfile -like '.\*'){$Zipfile = $pwd.Path + $Zipfile.Substring(1)} | |
#Update existing Zip | |
if((Test-Path $Zipfile) -and !$OverwriteZip){ | |
Write-Verbose "Updating existing zip file" | |
$zip = [System.IO.Compression.ZipFile]::Open($Zipfile,"Update") | |
#Remove existing files which will be updated in zip | |
$SourceFiles = dir -Recurse $Source |?{$_.mode -notlike "d*"}| select -ExpandProperty fullname | |
$Overlapfiles = $SourceFiles | %{$_.replace(($Source + '\'),'')} | |
$duplicates = $zip.Entries | ?{$Overlapfiles -contains $_.FullName} | |
$duplicates | %{$_.Delete()} | |
$SourceFiles | %{ | |
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($Zip, $_, ($_.replace(($Source + '\'),'')), | |
($CompressionLevel)) | Out-Null | |
} | |
$zip.dispose() | |
#New or overwrite zip completely | |
}else{ | |
#Overwrite | |
if($OverwriteZip){Remove-Item $Zipfile -Verbose} | |
#Source is a directory | |
if(test-path $Source -PathType Container){ | |
$Source = dir $Source | select -First 1 -ExpandProperty PSParentPath | %{$_.Replace('Microsoft.PowerShell.Core\FileSystem::','')} | |
[System.IO.Compression.ZipFile]::CreateFromDirectory($Source, $Zipfile, | |
([System.IO.Compression.CompressionLevel]::$CompressionLevel), $IncludeBaseDirectory) | |
#Source is a single file | |
}else{ | |
$zip = [System.IO.Compression.ZipFile]::Open($Zipfile,"Update") | |
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($Zip, $Source, (dir $Source|select -ExpandProperty name), | |
($CompressionLevel)) | |
$zip.dispose() | |
} | |
} | |
} | |
function Expand-fromZip{ | |
<# | |
.SYNOPSIS | |
Expands files and folders from a zip archive. | |
.DESCRIPTION | |
Extracts files and folders from a zip file to a selected destination folder. UNC paths work also. | |
Requires powershell v3+ and .NET 4.5 framework. | |
.PARAMETER Zipfile | |
Output name of new zip archive or existing name of archive. Full local path or UNC path prefered for best results. | |
.PARAMETER Destination | |
Extration folder or path. UNC also supported. If the destination path doesn't exist, it will be created. | |
.EXAMPLE | |
Expand-fromZip -Zipfile 'test.zip' -Destination 'Restored_Backup' | |
This will extra the contents from test.zip into the folder Restored_Backup. If the folder doesn't exist, it will be created. | |
.EXAMPLE | |
Expand-fromZip -Zipfile 'c:\temp\test.zip' -Destination '\\server1\Backup' | |
This will extract the contents of the zip file called test.zip in c:\temp to the Backup share from Server1. | |
.LINK | |
http://www.bryanvine.com/2017/03/powershell-script-7zipunzip-powershell.html | |
.NOTES | |
Author: Bryan Vine | |
Last updated: 03/27/2017 | |
#> | |
[cmdletbinding()] | |
Param( | |
[ValidateScript({Test-Path $_})][Parameter(Position=0,Mandatory)][String]$Zipfile, | |
[Parameter(Position=1)][String]$Destination | |
) | |
#Check for .NET 4.5+ | |
if(!(Test-DotNet)){ | |
Write-Error "ERROR: Unable to perform zip operation, .NET 4.5+ not detected!" | |
return 1 | |
} | |
[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null | |
if(!($Destination)){ | |
$Destination = $PWD | |
} | |
if(!(Test-Path $Destination)){ | |
$Destination = (New-Item $Destination -ItemType Directory).FullName | |
} | |
if($Destination -notlike "*\*" -or $Destination -like ".\*"){ | |
$Destination = dir $PWD | ?{$_.name -like $Destination -or $_.name -like $Destination.replace('.\','')} | select -ExpandProperty FullName | |
#select -First 1 -ExpandProperty PSParentPath | %{$_.Replace('Microsoft.PowerShell.Core\FileSystem::','')} | |
} | |
[System.IO.Compression.ZipFile]::ExtractToDirectory($Zipfile, $Destination) | |
} | |
Function Invoke-SevenZip{ | |
<# | |
.SYNOPSIS | |
Wrapper function which calls both Compress-toZip and Expand-fromZip | |
.DESCRIPTION | |
This function effectively translates the parameters that overlap with both 7z.exe and unzip.exe. | |
Using the set-alias cmdlets, you can assign this function to '7z' and 'unzip' for easy substitution. | |
.PARAMETER CommandMode | |
Specifies which operation to apply. 'u' or 'a' specify compress, 'x' or 'e' specify expand. | |
.PARAMETER CompressionLevel | |
This sets the level of compression. The native .NET extensions only support 3 levels of compression. | |
.PARAMETER ZipFile | |
Specifies the zip file name to extract from or compress to. | |
.PARAMETER Directory | |
Specifies the directory (or source file) to compress from or extract to. | |
.PARAMETER Recurse | |
This switch enables recursion for compressing a target directory. | |
.EXAMPLE | |
Invoke-SevenZip a 'c:\temp\test.zip' '\\server\share\data' -m 3 | |
This example compresses the contents of the data folder on server using the highest compression into the test.zip file locally. | |
.EXAMPLE | |
Invoke-SevenZip x 'c:\temp\test.zip' '.\bob' | |
This extracts the contents of test.zip into a folder named bob in the current directory. | |
.LINK | |
http://www.bryanvine.com/2017/03/powershell-script-7zipunzip-powershell.html | |
.LINK | |
Compress-toZip | |
.LINK | |
Expand-fromZip | |
.NOTES | |
Author: Bryan Vine | |
Last updated: 03/27/2017 | |
#> | |
[cmdletbinding()] | |
Param( | |
[Validateset('a','e','u','x')][Parameter(Position=0,Mandatory)][String]$CommandMode, | |
[Parameter(Position=1,Mandatory)][String]$ZipFile, | |
[Parameter(Position=2)][String[]]$Directory, | |
[Validateset('5','4','3','2','1','0','Optimal','Fastest','NoCompression')][Alias("m")]$CompressionLevel = 'Optimal', | |
[Alias("r")][Switch]$Recurse | |
) | |
switch($CompressionLevel){ | |
"5" {$CompressionLevel = 'Optimal'} | |
"4" {$CompressionLevel = 'Optimal'} | |
"3" {$CompressionLevel = 'Optimal'} | |
"2" {$CompressionLevel = 'Optimal'} | |
"1" {$CompressionLevel = 'Fastest'} | |
"0" {$CompressionLevel = 'NoCompression'} | |
} | |
if(!($Directory)){ | |
$Directory = $PWD | |
} | |
if($CommandMode -like 'u' -or $CommandMode -like 'a'){ | |
Compress-toZip -Zipfile $ZipFile -Source $Directory -CompressionLevel $CompressionLevel | |
} | |
if($CommandMode -like 'e' -or $CommandMode -like 'x'){ | |
Expand-fromZip -Zipfile $ZipFile -Destination $Directory | |
} | |
} | |
Set-Alias -Name '7z' -Value 'Invoke-SevenZip' | |
Set-Alias -Name 'Unzip' -Value 'Invoke-SevenZip' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment