Search code examples
powershellzipfilepath

How to fetch the filename of a specific file inside a zip archive using Powershell?


I have a zip archive that I need to inspect. I need to find the file name of a specific file with the file extension .serverrevision using Powershell.

There will only be one file with this file extension in the zip archive. The file name will be something like "2.1.4.serverrevision". I need to extract the version number, i.e. 2.1.4 in this example.

I know that I can use the following method to list the contents of the zip archive:

[IO.Compression.ZipFile]::OpenRead($ziparchive.FullName).Entries.FullName | %{ "$ziparchive`:$_" }

But I cannot figure out how to search for that file extension in that list that the function returns and then bring out the filename. The file name could be something like 2.1.4.serverrevision.

Any suggestions?


Solution

  • Use a combination of the .Where() and .ForEach() array methods: .Where() to filter and .ForEach() to transform (extract the name part of interest):

    [IO.Compression.ZipFile]::OpenRead($ziparchive.FullName).Entries.FullName.
      Where({ [IO.Path]::GetExtension($_) -eq '.serverrevision' }, 'First').
      ForEach({ [IO.Path]::GetFileNameWithoutExtension($_) } 
    

    Note:

    • You could achieve the same with the analogous Where-Object and ForEach-Object cmdlets, although with collections that are already in memory or easily fit into memory, the methods are faster.

      • However, the 'First' parameter, which stops processing once the first match is found - an important performance optimization - is currently not available with Where-Object; GitHub issue #v suggests bringing those features currently exclusive to the .Where() method to the cmdlet as well.
    • In PowerShell (Core) 7+, an alternative to calling the [IO.Path] methods is to use the Split-Path cmdlet, which now offers -Extension and -LeafBase switches (not available in Windows PowerShell).