Author Posts

January 1, 2012 at 12:00 am

by TeewsNek at 2013-04-25 10:38:19

My Zip-Files function...

Because of the way Zip files are handled using the "Shell.Application" there are some limits as to what this function can and can not do.

Just wrote this as an exampled or some friends to show them some the advanced features and how to use them.

#Region Function Zip-File
Function Zip-File () {
< #
.SYNOPSIS
Add, Removes, and Extracts files and folders to a Zip Archive
.DESCRIPTION
Add, Removes, and Extracts files and folders to a Zip Archive
.PARAMETER ZipFile
Name of Zip Archive
.PARAMETER Add
Names of Files or Folders to Add to Zip Archive
Will not overwrite existing Files in the Zip Archive
.PARAMETER Recurse
Will Reclusively add Files to the Zip Archive
.PARAMETER Remove
Names of Files or Folders to Remove from Zip Archive
If "Display Delete Confirmation" is enable you will be prompted confirm to Remove each File
.PARAMETER Extract
Names of Files or Folders to Extract from Zip Archive
Recreates Folders structure when extracting Files, even Folders that have no Matching Files to Extract
.PARAMETER Destination
Destination Folder to Extract Files or Folders to
.PARAMETER Folders
Add, Remove, or Extract Folders instead of Files from the Zip Archive
.PARAMETER List
List the Contents of the Zip Archive
.INPUTS
.OUTPUTS
.NOTES
Written by TeewsNek CopyRight (c) 2012
Add, Removes, and Extracts files and folders to a Zip Archive
.EXAMPLE
Zip-File -ZipFile "C:\Test.zip" -Add "C:\Temp\Temp_01.txt", "C:\Temp\Temp_02.txt"
.EXAMPLE
Zip-File -ZipFile "C:\Test.zip" -Add "C:\Temp_01", "C:\Temp_02" -Folders
.EXAMPLE
Zip-File -ZipFile "C:\Test.zip" -Remove "*.xls", "*.xlsx"
.EXAMPLE
Zip-File -ZipFile "C:\Test.zip" -Remove "Temp_01" -Folders
.EXAMPLE
Zip-File -ZipFile "C:\Test.zip" -Extract "*.doc", "*.docx"-Destination "C:\Temp"
.EXAMPLE
Zip-File -ZipFile "C:\Test.zip" -Extract "Temp_02" -Destination "C:\Temp" -Folders
.EXAMPLE
Zip-File -ZipFile "C:\Test.zip" -List
.LINK
TeewsNek Rules the MultiVerse
#>
[CmdletBinding(DefaultParameterSetName="Add")]
Param(
[Parameter(Mandatory=$True, ParameterSetName="Add")]
[Parameter(Mandatory=$True, ParameterSetName="Remove")]
[Parameter(Mandatory=$True, ParameterSetName="Extract")]
[Parameter(Mandatory=$True, ParameterSetName="List")]
[String]$ZipFile,
[Parameter(Mandatory=$True, ParameterSetName="Add")]
[String[]]$Add,
[Parameter(Mandatory=$False, ParameterSetName="Add")]
[Switch]$Recurse,
[Parameter(Mandatory=$True, ParameterSetName="Remove")]
[String[]]$Remove,
[Parameter(Mandatory=$True, ParameterSetName="Extract")]
[String[]]$Extract,
[Parameter(Mandatory=$False, ParameterSetName="Extract")]
[String]$Destination=$PWD,
[Parameter(Mandatory=$False, ParameterSetName="Add")]
[Parameter(Mandatory=$False, ParameterSetName="Remove")]
[Parameter(Mandatory=$False, ParameterSetName="Extract")]
[Switch]$Folders,
[Parameter(Mandatory=$True, ParameterSetName="List")]
[Switch]$List
)
DynamicParam {
if ($ZipFile -match ".*Zip\\.*") {
$NewAttrib = New-Object -TypeName System.Management.Automation.ParameterAttribute
$NewAttrib.ParameterSetName = "List"
$NewAttrib.Mandatory = $True
$AttribCollection = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute]
$AttribCollection.Add($NewAttrib)
$DynamicParam = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter("Path", [String], $AttribCollection)
$paramDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary
$paramDictionary.Add("Path", $DynamicParam)
return $ParamDictionary
}
}
Begin {
$Shell = New-Object -ComObject Shell.Application
if (![System.IO.File]::Exists($ZipFile) -and ($PSCmdlet.ParameterSetName -eq "Add")) {
Try {
[System.IO.File]::WriteAllText($ZipFile, $("PK" + [Char]5 + [Char]6 + $("$([Char]0)" * 18)))
}
Catch {
Throw "Error Creating Zip Archive"
}
}
$ZipArchive = $Shell.NameSpace($ZipFile)
if ($PSCmdlet.ParameterSetName -eq "Add") {
$TempFolder = "$([System.IO.Path]]::GetRandomFileName())"
if (![System.IO.Directory]::Exists($TempFolder)) {
[Void][System.IO.Directory]::CreateDirectory($TempFolder)
}
}
}
Process {
Switch ($PSCmdlet.ParameterSetName) {
"Add" {
Try {
if ($Folders) {
ForEach ($File in $Add) {
$SearchPath = [System.IO.Path]::GetDirectoryName($File)
$SearchName = [System.IO.Path]::GetFileName($File)
$DirList = [System.IO.Directory]::GetDirectories($SearchPath, $SearchName)
$Total = $ZipArchive.Items().Count
ForEach ($Dir in $DirList) {
$ParseName = $ZipArchive.ParseName([System.IO.Path]::GetFileName($Dir))
if ([String]::IsNullOrEmpty($ParseName)) {
if (!$Recurse) {
Write-Host "Adding Folder: $Dir"
}
$ZipArchive.CopyHere($Dir, 0x14)
Do {
[System.Threading.Thread]::Sleep(100)
} While ($ZipArchive.Items().Count -eq $Total)
} else {
if (!$Recurse) {
Write-Host "Folder Exists in Archive: $Dir"
}
}
}
}
} else {
ForEach ($File in $Add) {
$SearchPath = [System.IO.Path]::GetDirectoryName($File)
$SearchName = [System.IO.Path]::GetFileName($File)
$FileList = [System.IO.Directory]::GetFiles($SearchPath, $SearchName)
$Total = $ZipArchive.Items().Count
ForEach ($File in $FileList) {
$ParseName = $ZipArchive.ParseName([System.IO.Path]::GetFileName($File))
if ([String]::IsNullOrEmpty($ParseName)) {
Write-Host "Adding File: $File"
$ZipArchive.CopyHere($File, 0x14)
Do {
[System.Threading.Thread]::Sleep(100)
} While ($ZipArchive.Items().Count -eq $Total)
} else {
Write-Host "File Exists in Archive: $File"
}
}
if ($Recurse) {
$DirList = [System.IO.Directory]::GetDirectories($SearchPath)
ForEach ($Dir in $DirList) {
$NewFolder = [System.IO.Path]::GetFileName($Dir)
if (!$ZipArchive.ParseName($NewFolder)) {
[Void][System.IO.Directory]::CreateDirectory("$TempFolder\$NewFolder")
[System.IO.File]::WriteAllText("$TempFolder\$NewFolder\.Dir", "")
Zip-File -ZipFile $ZipFile -Add "$TempFolder\$NewFolder" -Folders -Recurse
}
$NewAdd = @()
ForEach ($Item in $Add) {
$NewAdd += "$([System.IO.Path]]::GetFileName($Item))"
}
Zip-File -ZipFile "$ZipFile\$NewFolder" -Add $NewAdd -Recurse:$Recurse
}
}
}
}
}
Catch {
Throw "Error Adding Files to Zip Archive"
}
Break
}
"Remove" {
Try {
ForEach ($File in $Remove) {
if ($Folders) {
$($ZipArchive.Items() | Where-Object -FilterScript { $_.IsFolder -and (($_.Name -eq $File) -or ($_.Name -match $File.Replace('.', '\.').Replace('*', '.*'))) }) | ForEach-Object -Process { Write-Host "Removing Folder: $($_.Name)"; $_.InvokeVerbEx("Delete", 0x14) }
} else {
$($ZipArchive.Items() | Where-Object -FilterScript { !$_.IsFolder -and (($_.Name -eq $File) -or ($_.Name -match $File.Replace('.', '\.').Replace('*', '.*'))) }) | ForEach-Object -Process { Write-Host "Removing File: $($_.Name)"; $_.InvokeVerbEx("Delete", 0x14) }
}
}
ForEach ($Folder in $($ZipArchive.Items() | Where-Object -FilterScript { $_.IsFolder })) {
Zip-File -ZipFile "$ZipFile\$($Folder.Name)" -Remove $Remove -Folders:$Folders
}
}
Catch {
Throw "Error Removing Files from Zip Archive"
}
Break
}
"Extract" {
Try {
if (![System.IO.Directory]::Exists($Destination)) {
[Void][System.IO.Directory]::CreateDirectory($Destination)
}
$DestFolder = $Shell.NameSpace($Destination)
ForEach ($File in $Extract) {
if ($Folders) {
$($ZipArchive.Items() | Where-Object -FilterScript { $_.IsFolder -and (($_.Name -eq $File) -or ($_.Name -match $File.Replace('.', '\.').Replace('*', '.*'))) }) | ForEach-Object -Process { Write-Host "Extracting Folder: $($_.Name) to $Destination"; $DestFolder.CopyHere($_, 0x14) }
} else {
$($ZipArchive.Items() | Where-Object -FilterScript { !$_.IsFolder -and (($_.Name -eq $File -and $_.Name -ne ".Dir") -or ($_.Name -match $File.Replace('.', '\.').Replace('*', '.*'))) }) | ForEach-Object -Process { Write-Host "Extracting File: $($_.Name) to $Destination"; $DestFolder.CopyHere($_, 0x14) }
}
}
ForEach ($Folder in $($ZipArchive.Items() | Where-Object -FilterScript { $_.IsFolder })) {
Zip-File -ZipFile "$ZipFile\$($Folder.Name)" -Extract $Extract -Destination "$Destination\$($Folder.Name)" -Folders:$Folders
}
}
Catch {
Throw "Error Extracting Files from Zip Archive"
}
Break
}
"List" {
Try {
$ZipArchive.Items() | Where-Object -FilterScript { !$_.IsFolder -and $_.Name -ne ".Dir" } | Select-Object -Property "Name", "Size", "ModifyDate", "Type", @{"Name"="Path";"Expression"={$(if ($($PSCmdlet.MyInvocation.BoundParameters["Path"])) {$($PSCmdlet.MyInvocation.BoundParameters["Path"])} else {"\"})}}
ForEach ($Folder in $($ZipArchive.Items() | Where-Object -FilterScript { $_.IsFolder })) {
Zip-File -ZipFile "$ZipFile\$($Folder.Name)" -List -Path "$(if ($($PSCmdlet.MyInvocation.BoundParameters["Path"])) {$($PSCmdlet.MyInvocation.BoundParameters["Path"])})\$($Folder.Name)"
}
}
Catch {
Throw "Error Listing Files in Zip Archive"
}
Break
}
}
}
End {
$Shell = $Null
$ZipArchive = $Null
if ($PSCmdlet.ParameterSetName -eq "Add") {
if ([System.IO.Directory]::Exists($TempFolder)) {
[Void][System.IO.Directory]::Delete($TempFolder, $True)
}
}
}
}
#EndRegion

by poshoholic at 2013-04-25 12:20:16

Thanks for sharing. Have you seen the PoshCode website? That might be a better location for you to share a script, because it allows others to improve upon it, and you can go back to earlier versions, etc. Sharing a function by itself in here, it might get lost more easily.

Here's the link to PoshCode: http://poshcode.org/