1

this is hashtable in my powershell script (data extracted using Get-PSReadlineOption):

$theme = @{}
$theme["CommentForegroundColor"] = "DarkGreen"
$theme["CommentBackgroundColor"] = "Black"
$theme["KeywordForegroundColor"] = "Green"
$theme["KeywordBackgroundColor"] = "Black"

I am trying to set powershell theme colors using Set-PSReadlineOption command:

foreach ($colorTokenKey in $theme.keys) {
    $c=$theme[$colorTokenKey]
    echo "$colorTokenKey will be set to $c"
    $colorTokenArgs = $colorTokenKey.Replace("ForegroundColor"," -ForegroundColor")
    $colorTokenArgs = $colorTokenArgs.Replace("BackgroundColor"," -BackgroundColor")
    $colorTokenArgs = $colorTokenArgs.Split(" ")
    $tokenKind = $colorTokenArgs[0]
    $tokenForegroundOrBackground = $colorTokenArgs[1]
    $params = "-TokenKind $tokenKind $tokenForegroundOrBackground $c"
    echo $params
    & Set-PSReadlineOption $params
}

But when I run this, I get

CommandBackgroundColor will be set to White
-TokenKind Command -BackgroundColor White
Set-PSReadlineOption : Cannot bind parameter 'TokenKind'. Cannot convert value "-Tok
enKind Command -BackgroundColor White" to type "Microsoft.PowerShell.TokenClassifica
tion". Error: "Unable to match the identifier name -TokenKind Command -BackgroundCol
or White to a valid enumerator name. Specify one of the following enumerator names a
nd try again:
None, Comment, Keyword, String, Operator, Variable, Command, Parameter, Type, Number
, Member"
At C:\Users\...\PowerShellColors.ps1:88 char:28
+     & Set-PSReadlineOption $params

What I am doing wrong?

1 Answer 1

3

You are passing all of your arguments as a single string, which is not what you want.

What you want to do is called splatting.

Change your last lines to this:

$params = @{
    "TokenKind" = $tokenKind
    $tokenForegroundOrBackground = $c
}
Set-PSReadlineOption @params

Also, mind that you have to pass the parameters without the leading -! So you would have to change this too:

$colorTokenArgs = $colorTokenKey.Replace("ForegroundColor"," ForegroundColor")
$colorTokenArgs = $colorTokenArgs.Replace("BackgroundColor"," BackgroundColor")

(Or do maybe define it differently in the first place.)

A somewhat hacky alternative would be using Invoke-Expression, which executes the string as a command:

Invoke-Expression "Set-PSReadlineOption $params"
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! I would stumble into "splatting" (if stumble at all) in a long long time...
@Emil Just a heads-up: The syntax for this command has changed in the most recent PowerShell version. Keep this in mind if you want to update anytime soon, because you would have to change your script: learn.microsoft.com/en-us/powershell/module/psreadline/…
Ok, I will check. Thanks again!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.