134 lines
4.7 KiB
PowerShell
134 lines
4.7 KiB
PowerShell
$psver = $PSVersionTable.psversion.Major
|
|
if ($psver -eq '2') {
|
|
Write-Output "Powershell version 3 required"
|
|
}
|
|
function New-ZipFile {
|
|
#.Synopsis
|
|
# Create a new zip file, optionally appending to an existing zip...
|
|
[CmdletBinding()]
|
|
param(
|
|
# The path of the zip to create
|
|
[Parameter(Position=0, Mandatory=$true)]
|
|
$ZipFilePath,
|
|
|
|
# Items that we want to add to the ZipFile
|
|
[Parameter(Position=1, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
|
|
[Alias("PSPath","Item")]
|
|
[string[]]$InputObject = $Pwd,
|
|
|
|
# Append to an existing zip file, instead of overwriting it
|
|
[Switch]$Append,
|
|
|
|
# The compression level (defaults to Optimal):
|
|
# Optimal - The compression operation should be optimally compressed, even if the operation takes a longer time to complete.
|
|
# Fastest - The compression operation should complete as quickly as possible, even if the resulting file is not optimally compressed.
|
|
# NoCompression - No compression should be performed on the file.
|
|
[System.IO.Compression.CompressionLevel]$Compression = "Optimal"
|
|
)
|
|
begin {
|
|
Add-Type -As System.IO.Compression.FileSystem
|
|
# Make sure the folder already exists
|
|
[string]$File = Split-Path $ZipFilePath -Leaf
|
|
[string]$Folder = $(if($Folder = Split-Path $ZipFilePath) { Resolve-Path $Folder } else { $Pwd })
|
|
$ZipFilePath = Join-Path $Folder $File
|
|
# If they don't want to append, make sure the zip file doesn't already exist.
|
|
if(!$Append) {
|
|
if(Test-Path $ZipFilePath) { Remove-Item $ZipFilePath }
|
|
}
|
|
$Archive = [System.IO.Compression.ZipFile]::Open( $ZipFilePath, "Update" )
|
|
}
|
|
process {
|
|
foreach($path in $InputObject) {
|
|
foreach($item in Resolve-Path $path) {
|
|
# Push-Location so we can use Resolve-Path -Relative
|
|
Push-Location (Split-Path $item)
|
|
# This will get the file, or all the files in the folder (recursively)
|
|
foreach($file in Get-ChildItem $item -Recurse -File -Force | % FullName) {
|
|
# Calculate the relative file path
|
|
$relative = (Resolve-Path $file -Relative).TrimStart(".\")
|
|
# Add the file to the zip
|
|
$null = [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($Archive, $file, $relative, $Compression)
|
|
}
|
|
Pop-Location
|
|
}
|
|
}
|
|
}
|
|
end {
|
|
$Archive.Dispose()
|
|
Get-Item $ZipFilePath
|
|
}
|
|
}
|
|
|
|
|
|
function Expand-ZipFile {
|
|
#.Synopsis
|
|
# Expand a zip file, ensuring it's contents go to a single folder ...
|
|
[CmdletBinding()]
|
|
param(
|
|
# The path of the zip file that needs to be extracted
|
|
[Parameter(ValueFromPipelineByPropertyName=$true, Position=0, Mandatory=$true)]
|
|
[Alias("PSPath")]
|
|
$FilePath,
|
|
|
|
# The path where we want the output folder to end up
|
|
[Parameter(Position=1)]
|
|
$OutputPath = $Pwd,
|
|
|
|
# Make sure the resulting folder is always named the same as the archive
|
|
[Switch]$Force
|
|
)
|
|
process {
|
|
$ZipFile = Get-Item $FilePath
|
|
$Archive = [System.IO.Compression.ZipFile]::Open( $ZipFile, "Read" )
|
|
|
|
# Figure out where we'd prefer to end up
|
|
if(Test-Path $OutputPath) {
|
|
# If they pass a path that exists, we want to create a new folder
|
|
$Destination = Join-Path $OutputPath $ZipFile.BaseName
|
|
} else {
|
|
# Otherwise, since they passed a folder, they must want us to use it
|
|
$Destination = $OutputPath
|
|
}
|
|
|
|
# The root folder of the first entry ...
|
|
$ArchiveRoot = ($Archive.Entries[0].FullName -Split "/|\\")[0]
|
|
|
|
Write-Verbose "Desired Destination: $Destination"
|
|
Write-Verbose "Archive Root: $ArchiveRoot"
|
|
|
|
# If any of the files are not in the same root folder ...
|
|
if($Archive.Entries.FullName | Where-Object { @($_ -Split "/|\\")[0] -ne $ArchiveRoot }) {
|
|
# extract it into a new folder:
|
|
New-Item $Destination -Type Directory -Force
|
|
[System.IO.Compression.ZipFileExtensions]::ExtractToDirectory( $Archive, $Destination )
|
|
} else {
|
|
# otherwise, extract it to the OutputPath
|
|
[System.IO.Compression.ZipFileExtensions]::ExtractToDirectory( $Archive, $OutputPath )
|
|
|
|
# If there was only a single file in the archive, then we'll just output that file...
|
|
if($Archive.Entries.Count -eq 1) {
|
|
# Except, if they asked for an OutputPath with an extension on it, we'll rename the file to that ...
|
|
if([System.IO.Path]::GetExtension($Destination)) {
|
|
Move-Item (Join-Path $OutputPath $Archive.Entries[0].FullName) $Destination
|
|
} else {
|
|
Get-Item (Join-Path $OutputPath $Archive.Entries[0].FullName)
|
|
}
|
|
} elseif($Force) {
|
|
# Otherwise let's make sure that we move it to where we expect it to go, in case the zip's been renamed
|
|
if($ArchiveRoot -ne $ZipFile.BaseName) {
|
|
Move-Item (join-path $OutputPath $ArchiveRoot) $Destination
|
|
Get-Item $Destination
|
|
}
|
|
} else {
|
|
Get-Item (Join-Path $OutputPath $ArchiveRoot)
|
|
}
|
|
}
|
|
|
|
$Archive.Dispose()
|
|
}
|
|
}
|
|
|
|
# Add the aliases ZIP and UNZIP
|
|
new-alias zip new-zipfile
|
|
new-alias unzip expand-zipfile
|