Powershell Zip Folders Contents

I know that a lot has been extended to zipping files using Powershell, but I cannot find a method that does exactly what I need.

I want the zip folder AND the files in the .zip folder without the parent folder inside the zip. So, for example, I have a folder named STUFF that contains files / folders, I want to put it in the STUFF.zip folder. This folder structure will then be STUFF.zip> files / folders NOT STUFF.zip> STUFF> files / folders, as I am currently getting this code ...

function CountZipItems( [__ComObject] $zipFile) { If ($zipFile -eq $null) { Throw "Value cannot be null: zipFile" } Write-Host ("Counting items in zip file (" + $zipFile.Self.Path + ")...") [int] $count = CountZipItemsRecursive($zipFile) Write-Host ($count.ToString() + " items in zip file (" ` + $zipFile.Self.Path + ").") return $count } function CountZipItemsRecursive( [__ComObject] $parent) { If ($parent -eq $null) { Throw "Value cannot be null: parent" } [int] $count = 0 $parent.Items() | ForEach-Object { $count += 1 If ($_.IsFolder -eq $true) { $count += CountZipItemsRecursive($_.GetFolder) } } return $count } function IsFileLocked( [string] $path) { If ([string]::IsNullOrEmpty($path) -eq $true) { Throw "The path must be specified." } [bool] $fileExists = Test-Path $path If ($fileExists -eq $false) { Throw "File does not exist (" + $path + ")" } [bool] $isFileLocked = $true $file = $null Try { $file = [IO.File]::Open( $path, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::None) $isFileLocked = $false } Catch [IO.IOException] { If ($_.Exception.Message.EndsWith( "it is being used by another process.") -eq $false) { Throw $_.Exception } } Finally { If ($file -ne $null) { $file.Close() } } return $isFileLocked } function GetWaitInterval( [int] $waitTime) { If ($waitTime -lt 1000) { return 100 } ElseIf ($waitTime -lt 5000) { return 1000 } Else { return 5000 } } function WaitForZipOperationToFinish( [__ComObject] $zipFile, [int] $expectedNumberOfItemsInZipFile) { If ($zipFile -eq $null) { Throw "Value cannot be null: zipFile" } ElseIf ($expectedNumberOfItemsInZipFile -lt 1) { Throw "The expected number of items in the zip file must be specified." } Write-Host -NoNewLine "Waiting for zip operation to finish..." Start-Sleep -Milliseconds 1000 # ensure zip operation had time to start [int] $waitTime = 0 [int] $maxWaitTime = 60 * 1000 # [milliseconds] while($waitTime -lt $maxWaitTime) { [int] $waitInterval = GetWaitInterval($waitTime) Write-Host -NoNewLine "." Start-Sleep -Milliseconds $waitInterval $waitTime += $waitInterval Write-Debug ("Wait time: " + $waitTime / 1000 + " seconds") [bool] $isFileLocked = IsFileLocked($zipFile.Self.Path) If ($isFileLocked -eq $true) { Write-Debug "Zip file is locked by another process." Continue } Else { Break } } Write-Host If ($waitTime -ge $maxWaitTime) { Throw "Timeout exceeded waiting for zip operation" } [int] $count = CountZipItems($zipFile) If ($count -eq $expectedNumberOfItemsInZipFile) { Write-Debug "The zip operation completed succesfully." } ElseIf ($count -eq 0) { Throw ("Zip file is empty. This can occur if the operation is" ` + " cancelled by the user.") } ElseIf ($count -gt $expectedCount) { Throw "Zip file contains more than the expected number of items." } } function ZipFolder( [IO.DirectoryInfo] $directory) { If ($directory -eq $null) { Throw "Value cannot be null: directory" } Write-Host ("Creating zip file for folder (" + $directory.FullName + ")...") [IO.DirectoryInfo] $parentDir = $directory.Parent [string] $zipFileName If ($parentDir.FullName.EndsWith("\") -eq $true) { # eg $parentDir = "C:\" $zipFileName = $parentDir.FullName + $directory.Name + ".zip" } Else { $zipFileName = $parentDir.FullName + "\" + $directory.Name + ".zip" #$zipFileName = $directory.Name + ".zip" #$zipFileName = $parentDir.FullName + ".zip" } If (Test-Path $zipFileName) { Throw "Zip file already exists ($zipFileName)." } Set-Content $zipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) $shellApp = New-Object -ComObject Shell.Application $zipFile = $shellApp.NameSpace($zipFileName) If ($zipFile -eq $null) { Throw "Failed to get zip file object." } [int] $expectedCount = (Get-ChildItem $directory -Force -Recurse).Count $expectedCount += 1 # account for the top-level folder $zipFile.CopyHere($directory.FullName) #Get-ChildItem $directory | foreach {$zipFile.CopyHere($_.fullname)} # wait for CopyHere operation to complete WaitForZipOperationToFinish $zipFile $expectedCount Write-Host -Fore Green ("Successfully created zip file for folder (" ` + $directory.FullName + ").") } 

Using

 Remove-Item "H:\STUFF.zip" [IO.DirectoryInfo] $directory = Get-Item "H:\STUFF" ZipFolder $directory 

Complete the loan here for this code. I really appreciate any help I get, this ability is critical to my project! Unfortunately, I cannot use the community extension module, because this module is not installed on the other PC on which it will be launched.

Thanks!

+6
source share
4 answers

According to @mjolinor "H: \ Stuff \", if you have .NET 4.5 installed, you can run the following:

 $src = "H:\Stuff\" $dst = "H:\Stuff.zip" [Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" ) [System.IO.Compression.ZipFile]::CreateFromDirectory($src, $dst) 
+14
source

If you are using the PSCX Module , you will use the line code below to get what you need:

 write-zip h:\Stuff\* myzipfile.zip 
+6
source

A new solution is available with WMF 5 (well, not so, new ^^)

 Compress-Archive -Path H:\stuff\* -DestinationPath H:\stuff.zip -Force 
+1
source

I am developing a simple module in Powershell, in more detail https://github.com/julianosaless/powershellzip

0
source

All Articles