Powershell 5.x OK, but switching to PS Core 7 - It fails

Script file: %PowerShellScripts%\Replacefiles.ps1
Script Args:-source '%StagingExeBuild%\%CI_PROJ_DIRNAME%' -target '\\app100213\Staging\Trunk' -filename ("PSD_Server.exe") -alwayscopy -verbose

This works if PS Version is set to Default and Using is set to PowerShell.Default
It fails if PS Version is set to 7 and Using is set to PowerShell.Core.7

16.06.54  Stage: Copy files
16.06.54  	Server To Agent Workspace Sync - Iteration #1
16.06.54  		Started syncing files from the server 'localhost' to the agent 'devapp668wms001'
16.07.11  		Finished syncing files from the server 'localhost' to the agent 'devapp668wms001'.
16.07.11  	Copy to app100213\Staging\Trunk - Iteration #1
16.07.11  		Parameters
16.07.11  			Working Directory: c:\src\PowerShell\Tools
16.07.11  			Executable: C:\Program Files\PowerShell\7\pwsh.exe
16.07.11  			Arguments: -NonInteractive -Command "try { [string]$pathToScript = 'c:\src\PowerShell\Tools\Replacefiles.ps1'; [string]$arg1 = 'C:\Shared\ContinuaCI\PSD_bin\Win32\Executables\Development'; [string]$arg2 = '\\app100213\Staging\Trunk'; invoke-expression -Command '& $pathToScript -source $arg1 -target $arg2 -filename (""PSD_Server.exe"""") -alwayscopy -verbose'; exit $lastexitcode } catch { $Error[0]; exit 1}"
16.07.11  			Environment Variables (user-defined)
16.07.11  				No environment variables specified
16.07.11  		Output
16.07.13  			e[91mInvoke-Expression: 
16.07.13  			e[96mLine |
16.07.13  			e[96m   1 | e[0m . ing\Trunk'; e[96minvoke-expression -Command '& $pathToScript -source $arg1e[0m .
16.07.13  			e[96m     | e[91m               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16.07.13  			e[91me[96m     | e[91mThe string is missing the terminator: ".
16.07.13  			e[0m
16.07.13  	Agent To Server Workspace Sync - Iteration #1

I can successfully run the script from PS 7 shell, with the same user as the Agent is logged in as, which leads me to think that the first issue is a Continua CI/PS 7 integration issue.

The second issue is the weird format of the logging. PS 7 runs Unicode by default. It looks like Continua processes it as ANSI?.

As for the encoding of the output file you can configure it here:

Check “Encoding Name”

1 Like

Unfortunately, it didn’t solve the problem, nor did it make the log any more beautiful.

Hi Lars,

The PowerShell command is failing due to the parameter -filename ("PSD_Server.exe"). It should work if you change the double quotes to single quotes. e.g. -filename ('PSD_Server.exe').

The error is happening due to the way we wrap the arguments in a try-catch block so that we can get the exit code from PowerShell. See the following line in the log.

Arguments: -NonInteractive -Command "try { [string]$pathToScript = 'c:\src\PowerShell\Tools\Replacefiles.ps1'; [string]$arg1 = 'C:\Shared\ContinuaCI\PSD_bin\Win32\Executables\Development'; [string]$arg2 = '\\app100213\Staging\Trunk'; invoke-expression -Command '& $pathToScript -source $arg1 -target $arg2 -filename (""PSD_Server.exe"""") -alwayscopy -verbose'; exit $lastexitcode } catch { $Error[0]; exit 1}"

The duplicate end doubles quotes for the filename argument is strangely required for PS5 and lower, but causes a failure in PS6+. We’re looking into what we can do to automatically deal with arguments of this type today.

We’re still looking into the character encoding issue. There appears to have been some changes to output encoding from PowerShell Core 6 to 7. We’ll let you know once we’ve figured out what needs to be done.

1 Like

Hi Dave,
Ouch - that PS 5 to 7 quoting discrepancy makes for quite the conundrum, particularly if one wants to pass a parameter where PS is supposed to do the substitution, f.x. if you want fetch something from “$ENV:ProgramData\MySpecialFolder” or “$ENV:CommonProgramFiles” or similar.

Not my call, but the massaging of quoting characters could be done during validation when switching between PS versions, instead of during execution. I mean, once you settle on a PS version, you are not likely to go back, right?

That shouldn’t be an issue - those variables will still get passed to PowerShell as is.

Not sure what difference that would make? We only need to correct the syntax - e.g. not add duplicate double quotes for PowerShell core versions. We can’t really validate whether the arguments are acceptable to PowerShell without running PowerShell.

BTW the e[91m characters in the log output are colour codes rather encoding issues. We’re looking for a way to turn them off, but we may need to strip them out with regular expressions.

1 Like

Looks like you will need to strip the escapes for now

Ref PS disabling color escapes - it is under consideration for PS 7.1

The SO case below has some related info.

Hi Lars,

We’ve already implemented code to strip out the VT codes. This will be included the next version. This method has the advantage of allowing us to mark the log entry as an error when we detect the red colour code.

1 Like

Thanks, Dave.

Note that the colors cannot be guaranteed to be constant - i.e. the error color can be something else.than red on black.

See $host.PrivateData

PS C:> $Host.PrivateData

FormatAccentColor       : Green
ErrorAccentColor        : Cyan
ErrorForegroundColor    : Red
ErrorBackgroundColor    : Black
WarningForegroundColor  : Yellow
WarningBackgroundColor  : Black
DebugForegroundColor    : Yellow
DebugBackgroundColor    : Black
VerboseForegroundColor  : Yellow
VerboseBackgroundColor  : Black
ProgressForegroundColor : Yellow
ProgressBackgroundColor : DarkCyan

Yes, good point - there’ll be settings…