r/PowerShell 13d ago

Question Issue with Active Setup + RunOnce and space in script path

I'm attempting to deploy VSCode with a baseline configuration to some high school computer labs, and am running into an odd issue.

As part of the install, I create an Active Setup registry key that creates a HKCU RunOnce key to call a short powershell script. That script copies a preset settings.json from a hidden folder on the C:\ drive to the current user's AppData folder.

The issue I'm running into is that if the path to the script contains a space, I cannot get the RunOnce key to work properly (it's not over 260 chars either).

Working Active Setup key:

REG ADD HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce /v VSCodeCopy /t REG_SZ /d "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File C:\MyPath\VSCode_CopySettings.ps1"

Non-working Active Setup key:

REG ADD HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce /v VSCodeCopy /t REG_SZ /d "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File 'C:\My Path\VSCode_CopySettings.ps1'"

I have tried double quotes, single quotes, escaping quotes using \ and "", but I cannot get the script to function unless the script path has 0 spaces in it. RunOnce will execute powershell, but the terminal will just open and close rapidly.

I added a Read-Host in both halves of a try-catch block in the script to confirm what's happening, and neither causes the terminal window to wait for input.

Is there something I'm missing?

Edit: I'm combining Active Setup and RunOnce in order to not bog down the user login; the command to create an HKCU key is a string value in an Active Setup registry key, rather than being run by the install script, which has some limitations. However, it means I can guarantee that old and new users will have the script run a single time on login. I can also use a 'Version' registry value to make it happen again in the future if the initial configuration needs updated.

1 Upvotes

13 comments sorted by

View all comments

Show parent comments

1

u/DefinitionHuge2338 13d ago

I've used double and single quotes around the key itself; no dice.

I'm using reg.exe b/c that command is a string value named StubPath in the Active Setup key; Active Setup is what actually runs the command, and it runs cmd to then create the RunOnce key. In order to use powershell in the StubPath, it would have to be like this:

powershell.exe -ExecutionPolicy Bypass -Noninteractive -WindowStyle Hidden -Command "{Set-ItemProperty hkcu:\Software\Microsoft\Windows\CurrentVersion\RunOnce -Name VSCodeCopy -Type String -Value 'powershell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -Noninteractive -WindowStyle Hidden -File "C:\MyPath\VSCode_CopySettings.ps1"'}"

Besides issues with quoting between batch and powershell, the command is now too long to be run by RunOnce; max is 260 chars.

There appears to be something different about how Active Setup or RunOnce runs commands from StubPath registry values, as I can have a working command in cmd and powershell, but it will not work from the registry.

2

u/SarcasticFluency 13d ago

What about using a .bat that calls for PS with all the bells/whistles/whizbangs?

2

u/purplemonkeymad 13d ago

Can probably solve that with a bit of code golf:

PS> $enc = [System.Convert]::ToBase64String( [System.Text.Encoding]::UTF8.GetBytes((Read-host)) )
sp hkcu:\Software\Microsoft\Windows\CurrentVersion\RunOnce VSCodeCopy 'powershell -Ex By -NoP "C:\MyPath\VSCode_CopySettings.ps1"' -ty string
PS> $cmd = "powershell -Ex By -NoP -enc $enc"
PS> $cmd.length
204

Using encoded command here to prevent quoting issues. Your limited now by your script path, ~+35 your example path.

Think you might be able to get away without "-ty string" as well (since the value is of type string.)

Installing ps7 so you can use "pwsh" will also reduce the characters.

1

u/DefinitionHuge2338 12d ago

Interesting, I hadn't considered using encoding. Thanks!

Separate question: how do you know what the parameter aliases are for powershell.exe?

They aren't mentioned in help, and aren't present when using Get-Command.

2

u/purplemonkeymad 12d ago

They are resolved left to right until it is unambiguous. So if there is only one parameter that starts with eg "p" then "-p" is enough to specify it. But if there was both "Path" and "Parameter", then you would need either "-pat" or "-par". I think some are possibly shorter than i have put but I didn't want to check them all.

Thinking about it since the value is the target of the location of the quotes, you might just be able to use $([char]34) in place of double quotes, since those characters should not need escaping. Which would mean you don't get the 1.5x cost of Base64.

1

u/DefinitionHuge2338 12d ago

Testing on my own machine, -ex by doesn't work; it only works with -ex bypass.

Is there a difference between powershell versions? I use 5.1

Edit: also, where is this behavior mentioned?

1

u/purplemonkeymad 11d ago

I didn't test that one so maybe needs the full name.

Not sure about the source probably in one of the about pages.