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

One 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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s