Signed scripts fail in PS3, work in ps2

I already posted this on the MS forum but did not (yet) get any replies. Perhaps someone here knows what is going on.

I use a valid code signing certificate to sign various scripts, PS1, Infopath and such. … For powershell, this always worked like a charm, the policy is in place and the trusted publisher is also set up using domain policies. for the last 2 years , no problemos. I recently tried to upgrade our scripting server too powershell 3.0 since i like the new features but none of the signed scripts worked after that.

Error: Executable script code found in signature block

I don’t think the issue is the signature or the way it is signed, i feel that this is a bug or perhaps an issue on my side with code execution policies, even after using “drunken sailor mode” (Unrestricted) it spawned the error!

i use the following in an automated and semi-automated process.

$f = file
$cert=(dir cert:currentuser\my\ -CodeSigningCert)
Set-AuthenticodeSignature $f $cert -TimestampServer

Any help is appreciated !

ps: the semi-automated script only runs in PowerGui and the fully automated one runs in native PS.

Best Regards

Searching for that error message turned up this funny little gem. I don’t know if there are other comments that trigger the same bug, or if this is what’s affecting you, but I can reproduce it by sticking “# organizational unit filter” into a script.

On a side note, as soon as I type that comment into my script, the ISE makes this obvious by putting the red squiggly underline beneath any code following the comment. It should help you troubleshoot this issue in your scripts; just open them in the PowerShell 3.0 ISE and see what it complains about.

Thank you for the ISE typ. I did that and no issues with the actual SIG block where detected.
I started looking in the ps profile and the enterprise PS profile uses a invoke-expression to load default scripts.

I adapted the profile and the issues are gone…

$lib_home = “\server\PSFunctions$”
Get-ChildItem “${lib_home}*.ps1” | %{
Write-Host loading $_
.$_ }
Write-Host “Company PowerShell Environment Loaded” -foreground yellow

Any clue why invoke expression was ‘ok’ in ps2 but not in ps3 ?

Original profile

#Load functions from \\server $i=0 $lib_home = "\\server\PSFunctions$" New-PSDrive -Name scripts -PSProvider filesystem -root $lib_home -ErrorAction SilentlyContinue | Out-Null Write-Host "Loading the following functions for use..." -foreground yellow Write-Host "Location:" -noNewLine -foreground yellow Write-Host " $lib_home" -foreground cyan Get-ChildItem -Path scripts: -Recurse | Where { $_.attributes -ne "directory" } | ForEach-Object { [string]::Join([environment]::NewLine, (Get-Content -Path $_.fullname)) | Invoke-Expression Write-Host ("{0:0#}" -f $i)".. " -noNewLine -foreground magenta Write-Host $ -foreground magenta $i++ }

I’m not sure why it didn’t give the same error in PowerShell 2.0, but it makes more sense (to me) for that to fail than for it to work. When you tell PowerShell to execute a file, the engine knows to treat that entire file as one entity, with an optional signature block that is associated with the rest of the file. Piping instructions to Invoke-Expression one at a time seems to create a situation where the engine sees a script like this:

Some code

Some code from a "called" script
# a Signature block

More code

Which is not a legal file format in PowerShell scripts; there must be only one signature block, at the very end of the file.

Sometimes the behaviour of cmdlets change with a new PowerShell version. Microsoft may have the intention to correct known errors or misbehaviours by that, which is good. But the result is that a script that run fine suddenly fails. I had such trouble with cmdlets like Get-Credential or Export-Clixml in combination with System.Security.Securestring-objects and wrote a post about my experiences:

Maybe this helps. At least you are aware now of that such issues exists.