Function Zip-File

This topic contains 0 replies, has 1 voice, and was last updated by Profile photo of Forums Archives Forums Archives 5 years, 5 months ago.

  • Author
    Posts
  • #6081

    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/

You must be logged in to reply to this topic.