windowspowershellencryptionzipsystem.io.compression

Can I check the contents of encrypted zip-archive without using password?


I've encrypted .zip archive with some files. Later archive contents must be checked by someone who doesn't know encryption password. Is there any way to do this in powershell?

Ubuntu has zip -sf myfile.zip command but I couldn't find any simular in powershell.


Solution

  • If you're just looking to list the zip contents, then this function will do. As for extracting the Zip contents, ZipArchive does not support encrypted Zips as of today. There are third party PowerShell Modules as well as libraries that can do this though.

    function Get-ZipContent {
        [CmdletBinding()]
        param(
            [Parameter(ParameterSetName = 'Path', Position = 0, Mandatory, ValueFromPipeline)]
            [string[]] $Path,
    
            [Parameter(ParameterSetName = 'LiteralPath', Mandatory, ValueFromPipelineByPropertyName)]
            [Alias('PSPath')]
            [string[]] $LiteralPath,
    
            [Parameter()]
            [switch] $Force
        )
    
        begin {
            Add-Type -AssemblyName System.IO.Compression
        }
        process {
            try {
                $arguments = switch($PSCmdlet.ParameterSetName) {
                    Path { $Path, $Force.IsPresent, $false }
                    LiteralPath { $LiteralPath, $Force.IsPresent, $true }
                }
    
                foreach($item in $ExecutionContext.InvokeProvider.Item.Get.Invoke($arguments)) {
                    try {
                        $fs  = $item.OpenRead()
                        $zip = [IO.Compression.ZipArchive]::new($fs, [IO.Compression.ZipArchiveMode]::Read)
                        foreach($entry in $zip.Entries) {
                            $entry.PSObject.Properties.Add([psnoteproperty]::new('Source', $item.FullName))
                            $entry
                        }
                    }
                    catch {
                        $PSCmdlet.WriteError($_)
                    }
                    finally {
                        $zip, $fs | ForEach-Object Dispose
                    }
                }
            }
            catch {
                $PSCmdlet.WriteError($_)
            }
        }
    }
    

    Usage:

    PS ..\pwsh> Get-ZipContent path\to\myfolder\*.zip
    PS ..\pwsh> Get-ChildItem path\to\things -Recurse -Filter *.zip | Get-ZipContent 
    

    To further expand the usage since it seems not quite clear:

    # load the function in memory:
    PS ..\pwsh> . ./theFunctionisHere.ps1
    
    # call the function giving it a path to a zip:
    PS ..\pwsh> Get-ZipContent ./thing.zip
    
    Source             : path/to/pwsh/thing.zip
    Archive            : System.IO.Compression.ZipArchive       
    Crc32              : 0
    IsEncrypted        : True
    CompressedLength   : 165
    ExternalAttributes : 32
    Comment            : 
    FullName           : other thing.txt
    LastWriteTime      : 10/29/2022 10:31:30 AM -03:00
    Length             : 446
    Name               : other thing.txt
    
    Source             : path/to/pwsh/thing.zip
    Archive            : System.IO.Compression.ZipArchive
    Crc32              : 0
    IsEncrypted        : True
    CompressedLength   : 165
    ExternalAttributes : 32
    Comment            : 
    FullName           : thing.txt
    LastWriteTime      : 10/29/2022 10:31:30 AM -03:00
    Length             : 446
    Name               : thing.txt
    

    Note: An improved version of the function above is available as part of the PSCompression Module.