Expand-Zip.ps1
function Expand-Zip { <# .Synopsis Expands the contents of a Zip file .Description Expands the contents of a Zip file that was compressed with Out-Zip. .Example dir $home\Documents\WindowsPowerShell\Modules\Pipeworks -Recurse | Out-Zip -ZipFile $home\Pipeworks.zip Expand-Zip $home\Pipeworks.zip -OutputPath $psHome\Modules\Pipeworks .Link Out-Zip #> [OutputType([Nullable])] param( # The path of the zip file [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] [Alias('Fullname', 'Filename', 'ZipFile')] [string] $ZipPath, # The output directory. By default, this will be the name of the zip file. [string] $OutputPath ) begin { Add-Type -AssemblyName WindowsBase } process { $fullPAth = "$($ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($ZipPath))" $file = Get-Item $fullPAth if (-not $fullpath) { return } $package = [IO.Packaging.Package]::Open($fullpath, "Open", "Read") if (-not $package) { return } $relationships = $package.GetRelationships() $parts = $package.GetParts() if (-not $outputPath) { $OutputPath = Join-Path $pwd $file.Name.Replace(".zip", "") } if (-not (Test-Path $OutputPath)) { $null = New-Item -ItemType Directory -path $OutputPath -Force } $partCount = @($parts).Count $pc = 0 if ($parts.Count -gt 0) { $extractedParts = foreach ($p in $parts) { $pStream = $p.GetStream("Open", "Read") $byteArray = New-Object Byte[] $pStream.Length $readCount = $pStream.Read($byteArray, 0, $pStream.Length) $file = New-Object PSObject -Property @{ Uri = $p.Uri ContentType = $p.ContentType Content = $byteArray } $outputFileName = Join-Path (Resolve-path $OutputPath) $file.Uri $parentDir = $outputFileName | Split-Path if (-not (Test-Path $parentDir)) { $null = New-Item -ItemType Directory -Path $parentDir -Force } #$partDict[$p.Uri] = "$strWrite" $pStream.Close() $perc = $pc * 100 / $partCount $pc++ Write-Progress "Extracting Files" "$($file.Uri.ToString().Replace("/", "\"))" -PercentComplete $perc [IO.File]::WriteAllBytes($outputFileName, $byteArray) } $package.Close() #$openXmlDocument.Parts = $extractedParts #$openXmlDocument.Relationships = $relationships #New-Object PSObject -Property $openXmlDocument } else { $package.Close() $tempPath = [IO.path]::GetTempPath() $resolvedFile = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($zipPath) $tempPath = Join-Path $tempPath "$(Get-Random)_Expand_Zip" $newItem = New-ITem -itemType Directory -path $tempPath -Force $psCmd = [Powershell]::Create().AddScript({ param($path, $zipPath) $shell = new-object -com Shell.Application $destFolder = $shell.NameSpace("$Path") $destFolder.CopyHere(($shell.NameSpace($zipPath).Items())) }).AddArgument("$newItem").AddArgument("$resolvedFile") $psCmd.Invoke() $psCmd.Dispose() Get-ChildItem $tempPath -Recurse -Force | Where-Object { -NOT $_.PSISCONTAINER } | ForEach-Object { $source = $_ $relativePAth = $_.Fullname.Replace($tempPath, "") $nfPath = Join-Path $OutputPath $RelativePath $nf = New-Item -ItemType File -Path $nfPath -Force $BYTES = [IO.File]::ReadAllBytes($source.FullName) [IO.FILE]::WriteAllBytes($nf.FullName, $BYTES) Remove-Item -LiteralPath $SOURCE.FullName } Remove-Item $tempPath -Recurse -Force #Get-ChildItem $path -Recurse -Force } return } } |