PSAzureSignTool.psm1
function Select-FilesToSign() { [CmdletBinding()] Param( [Alias("pa")] [ValidateNotNullOrEmpty()] [ValidateScript({Test-Path $_})] [string]$Path, [Alias("inf")] [ValidateNotNullOrEmpty()] [string]$Includes = ".*", [Alias("exf")] [ValidateNotNullOrEmpty()] [string]$Excludes = "^$", [Alias("ext")] [ValidateNotNullOrEmpty()] [string]$Extensions = ".exe,.dll,.ocx,.cab", [Alias("ofl")] [ValidateNotNullOrEmpty()] [string]$OutputFileList ) [string[]]$ToSign = @() [string[]]$ArrExtensions = $Extensions -split "," New-Item -Path (Split-Path -Path $OutputFileList -Parent) -ItemType Directory -Force | Out-Null Get-ChildItem -Path $Path -File -Recurse ` | Where {($_.FullName -match $Includes) ` -and ($_.FullName -notmatch $Excludes) ` -and ($_.Extension -in $ArrExtensions)} ` | ForEach-Object { $signStatus = (Get-AuthenticodeSignature -FilePath $_.FullName).Status if($signStatus -ne "Valid") { [string]$ToAdd = Get-Item $_.FullName Write-Host "$signStatus - $ToAdd" $ToSign += $ToAdd } } if($ToSign) { Write-Host "`nList of files to sign saved to $OutputFileList `n" $ToSign | Out-File -FilePath $OutputFileList -Encoding utf8 -Force } else { throw "No files found to sign." } } function Start-CodeSign() { [CmdletBinding()] Param( [Alias("kvu")] [ValidateNotNullOrEmpty()] [string]$AzureKeyVaultUrl, [Alias("kvi")] [ValidateNotNullOrEmpty()] [string]$AzureKeyVaultClientId, [Alias("kvs")] [ValidateNotNullOrEmpty()] [string]$AzureKeyVaultClientSecret, [Alias("kvc")] [ValidateNotNullOrEmpty()] [string]$AzureKeyVaultCertificate, [Alias("ifl")] [ValidateNotNullOrEmpty()] [string]$InputFileList, [Alias("tr")] [string]$TimestampUrl ) try { AzureSignTool Write-Host "AzureSignTool is installed." } catch { Write-Host "AzureSignTool is not available, installing..." dotnet tool install --global AzureSignTool } [string[]]$SignArguments = @( 'sign', '-v', '-fd',"sha256", '-kvu',$AzureKeyVaultUrl, '-kvi',$AzureKeyVaultClientId, '-kvs',$AzureKeyVaultClientSecret, '-kvc',$AzureKeyVaultCertificate, '-ifl',$InputFileList ) if($TimestampUrl) { $SignArguments += @('-tr',$TimestampUrl) } else { Write-host "Warning: TimestampUrl is not provided, only digital signature will be applied to assemblies." } $pscore = $false try{ if ((pwsh -version)){ $pscore = $true } } catch{} if($pscore){ pwsh -Command "& AzureSignTool $SignArguments" } else{ powershell -Command "& AzureSignTool $SignArguments" } } function Test-AuthenticodeSignature() { [CmdletBinding()] Param( [Alias("ifl")] [ValidateNotNullOrEmpty()] [string]$InputFileList ) [string[]]$SigErrors = @() Write-Host "`nStarting validation..." $ToSignArray = ((Get-Content $InputFileList) -join ',') -split ',' Get-AuthenticodeSignature -FilePath $ToSignArray | ForEach-Object { if ($_.Status.ToString() -ne 'Valid') { $ErrMsg = "Signature invalid: $($_.Path)" $SigErrors += $ErrMsg Write-Host $ErrMsg } elseIf ($TimestampUrl -and (!$_.TimeStamperCertificate)) { $ErrMsg = "Timestamp certificate missing: $($_.Path)" $SigErrors += $ErrMsg Write-Host $ErrMsg } else { Write-Host ("Signature/timestamp valid: {0}" -f $_.Path) } } if($SigErrors -gt 0) { throw "`nValidation failed." } else { Write-Host "`nValidation completed successfully!" } } Export-ModuleMember -Function Select-FilesToSign, ` Start-CodeSign, ` Test-AuthenticodeSignature |