PSGallery and catalog files

I’ve been using catalog files associated with modules published on the PowerShellGallery the wrong way and got a warning from the PowerShell gallery administrator because my catalog files were breaking the Install-Module cmdlet experience.

As of PowerShell 5.1, you can create catalog files with the new New-FileCatalog cmdlet. Let’s quickly see what is a catalog file?

A digitally-signed catalog file (.cat) can be used as a digital signature for an arbitrary collection of files. A catalog file contains a collection of cryptographic hashes, or thumbprints. Each thumbprint corresponds to a file that is included in the collection.

(Source) May I insist on “can be used” in the above definition πŸ™„

That’s what I initially did. I was using catalog files as containers for a collection of file hashes. I didn’t use the catalog file as a digital signature and didn’t sign digitally catalog files. Catalog files allowed me to replace CSV files that I stored in my ADK repository and have a much better solution to check the integrity of each ADK files downloaded using the Test-FileCatalog cmdlet. See the following commit. The core functionality of catalog files just served very well my scenario where I just wanted to check that files downloaded match their hash.
Just a quick digression about performance. In the above scenario, using Get-AuthenticodeSignature (yes, all ADK files are digitally signed πŸ˜€ ) is the slowest (took 1 minute 28 seconds) 😦 , using Test-FileCatalog took 46 seconds πŸ™‚ and my CSV file with the Get-FileHash approach took only 28 seconds 😎 .

The code signing requirements for modules on the PowerShell gallery however are much higher than what I did with the ADK files. These requirements can be found in the PowerShellGallery Publishing Guidelines and Best Practices
modulo the fact that Save-Module doesn’t validate the catalog file (issue introduced on GH)

I’ve acquired a code signing certificate and here are the steps I use to sign a module before publishing it to the gallery.

  • Commit last changes to the module in the master branch
  • git.exe push -u origin master
    

    Copy the local github repo for the module to ~/Documents\WindowsPowerShell\Modules\$MyModule without folders like .git

    robocopy $GHRepoSource ~/Documents\WindowsPowerShell\Modules\$MyModule /R:0 /Z /S /XD .git /XD .vscode /XF README.md *.cat /NP
    
  • Use the latest version of the PSScriptAnalyzer to check if my module is compliant with coding best practices
  • # Run PSScriptAnalyzer
    Invoke-ScriptAnalyzer -Path ~/Documents\WindowsPowerShell\Modules\$MyModule -Recurse -Verbose
    
  • Sign the module and its manifest
  • # Sign the module
    $cert = Get-ChildItem Cert:\CurrentUser\My\ -CodeSigningCert | 
    Where { $_.HasPrivateKey -and ( $_.NotAfter -gt (Get-Date)) }
    
    Get-ChildItem ~/Documents\WindowsPowerShell\Modules\$MyModule -Include *.psd1,*.psm1 -Recurse |
    Set-AuthenticodeSignature -Certificate $cert -TimestampServer http://timestamp.digicert.com -Verbose -HashAlgorithm SHA256
    # at this stage only .psd1 and psm1 are signed
    Get-AuthenticodeSignature ~/Documents\WindowsPowerShell\Modules\$MyModule\*
    
  • Create the catalog file
  • # Create the catalog file
    New-FileCatalog -Path  ~/Documents\WindowsPowerShell\Modules\$MyModule -CatalogFilePath ~/Documents\WindowsPowerShell\Modules\$MyModule\MyModule.cat -CatalogVersion 2.0 -Verbose
    
  • Sign the catalog file
  • # Sign the catalog file
    Get-ChildItem ~/Documents\WindowsPowerShell\Modules\$MyModule\MyModule.cat -EA 0 |
    Set-AuthenticodeSignature -Certificate $cert -TimestampServer http://timestamp.digicert.com -Verbose -HashAlgorithm SHA256
    
  • Test the catalog file
  • # Test the catalog file
    Test-FileCatalog -Path ~/Documents\WindowsPowerShell\Modules\$MyModule -CatalogFilePath ~/Documents\WindowsPowerShell\Modules\$MyModule\MyModule.cat -Detailed 
    Get-AuthenticodeSignature ~/Documents\WindowsPowerShell\Modules\$MyModule\*
    

At this point everything is set and I can use the Publish-Module cmdlet.

Conclusion: If you want to use catalog files on PowerShellGallery, remember that you’ve to sign them digitally along with your regular module files.

Advertisements

1 thought on “PSGallery and catalog files

  1. Pingback: Dew Drop - September 20, 2017 (#2565) - Morning Dew

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.