I am a SysAdmin and whenever I need to type interactive commands I use ISE because I can work simultaneously on several servers from several script panes.
However, when I write scripts, functions or modules I use VSCode. Unfortunately, at the time of this writing, in VSCode there is no builtin feature, nor extension to assist us in signing PowerShell code.
There is an open feature request on Github, but “this is currently not a priority”…
If you are interested in this feature, you can upvote the issue or leave a comment so that the team in charge of VSCode knows that this point is important for the community.
https://github.com/PowerShell/vscode-powershell/issues/548
However, meanwhile, I need something to help me to sign my scripts without too much repetitive work. That’s why I have added a function to my profile. And now I can quickly and easily sign my script:
Set-Signature -FilePath MyScript.ps1
And because I have added the ValueFromPipeline attribute, the pipeline can be used:
Get-ChildItem *.ps1 | Set-Signature
And because I have added an alias and also a positional parameter, the command line can be very minimal:
sig MyScript.ps1
By adding the function to the profile, it automatically loads whenever your profile is loaded. But if you don’t need it that often, you can add the function to a .psm1 file and load it only when you need it with the Import-Module
cmdlet.
Here is the function:
function Set-Signature { [CmdletBinding()] [Alias('sig')] param( [Parameter( Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName )] [ValidateScript({Test-Path -Path $PSItem})] [ValidateNotNullOrEmpty()] [string[]]$FilePath ) begin{ $Certificate = Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert | Where-Object -Property NotAfter -GT (Get-Date) | Sort-Object -Property NotAfter -Descending | Select-Object -First 1 } process{ foreach ($Path in $FilePath) { $TimeStampServer = @( 'http://timestamp.verisign.com/scripts/timstamp.dll' 'http://timestamp.globalsign.com/scripts/timstamp.dll' 'http://timestamp.comodoca.com/authenticode' ) | Get-Random $Params = @{ Certificate = $Certificate TimestampServer = $TimeStampServer HashAlgorithm = 'SHA256' FilePath = $Path Verbose = $True } Set-AuthenticodeSignature @Params } } }
For those who are wondering, what a timestamp server is, it is a server that garantees the validity of your signature even when you certificate has expired.
Feel free to adapt this function to your needs.
And if you know other ways to assist us when signing scripts in VSCode please share them in the comments below…
you could create task in VS Code that takes currently open file and gives it to your script
LikeLike
Oh great! I am currently not a pro of VScode.
I am going to dig deeper into this task method…
Thanks Meelis!
LikeLike
Great write up. Thank you.
LikeLike