1

This code:

$username = 'Username'
$password = 'Password'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Start-Process -FilePath powershell -WorkingDirectory "$env:ALLUSERSPROFILE" -Credential $credential -WindowStyle Hidden -ArgumentList "-NoProfile -Command `"Start-Process -FilePath wscript -Verb RunAs -ArgumentList '\`"$((Get-Location).Path -replace "'", "''")\test.vbs\`" \`"/CurrentDirectory:$((Get-Location).Path -replace "'", "''")\`" \`"/AppData:$($env:APPDATA -replace "'", "''")\`"'`""

works when I run it line by line from the PowerShell command prompt.
The problem occurs both when I associate the .ps1 extension to "Windows PowerShell" and then double-click on the script, and when I compile the script in .exe through IronMan Software's "PSScriptPad".
A similar problem is present at the following link:
Powershell script executes correctly when I choose "run with powershell", but not when I "open with" powershell or double-click it
but in my case it doesn't even work with "Run with PowerShell" and perhaps the cause of the problem is the same one that also affects executables.

Another useful link is the following:
https://stackoverflow.com/a/58245206/45375

How can I solve the problem?
Windows 10 Pro 64-bit
Powershell Version: 5.1.19041.1237 (Integrated in Windows 10).

Aserre
  • 4,916
  • 5
  • 33
  • 56
Mario Palumbo
  • 693
  • 8
  • 32

1 Answers1

2

The compiled executable works correctly when it is not in a directory containing the apostrophe characters while in the case of double-clicking on a .ps1 script, the directory containing it cannot even contain spaces.
This is a useful link:
https://social.technet.microsoft.com/Forums/en-US/bf3344de-3af6-48e3-9f43-f595bb41c62d/bug-powershell-starts-w-error-when-opened-by-context-menu-in-folder-w-apostrophe-in-its-name?forum=win10itprogeneral

For the apostrophes path problem in .exe files, I sent a bug report to IronMan Software PSScriptPad, which was then taken care of.
For the problem of paths with apostrophes or consecutive whitespaces when double-clicking or doing "Run with PowerShell" on .ps1 scripts, I have solved by fixing the following registry values:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.ps1]
@="Microsoft.PowerShellScript.1"

[HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\.\\\"\""

[HKEY_CLASSES_ROOT\Directory\Shell\Powershell\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\.\\\"\""

[HKEY_CLASSES_ROOT\Drive\shell\Powershell\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit -Command \"Set-Location -LiteralPath \\\"%V\\.\\\"\""

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\DefaultIcon]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\",0"

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -Command \"if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force }; & \\\"%1\\\"\""

[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\0\Command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -Command \"if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force }; & \\\"%1\\\"\""

[HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\Edit\Command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell_ise.exe\" -File \"%1\""

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell]
"ExecutionPolicy"="RemoteSigned"
Mario Palumbo
  • 693
  • 8
  • 32
  • 1
    As for double-clicking on a `.ps1` script: [This answer](https://stackoverflow.com/a/58245206/45375) contains a run-once programmatic solution that from then on runs PowerShell script files in a stay-open PowerShell window, and paths with spaces as well as apostrophes (single-quotes, `'`) are supported too. – mklement0 Nov 05 '21 at 17:52
  • 1
    Nice - of course, this is much more comprehensive than just defining a double-click. There's a hitch, however: `HKEY_CLASSES_ROOT\Drive\shell\Powershell\command`, presumably among others, cannot be written to, at least on my Windows 10 20H2, machine due to only the `TrustedInstaller` having write permissions. Aside from that, worth pointing out that you need _elevation_ (run as admin) to write this to the registry. And (which I assume isn't a problem for you) that it is a Windows PowerShell-only solution. To be extra nice to future readers you could show how to write the file programmatically. – mklement0 Nov 09 '21 at 20:08
  • 1
    A quibble (it's not a problem as written, because nothing follows the `Set-Location` call): Since a path with a _trailing_ `\ ` (e.g. `C:\ `) is passed to the `HKEY_CLASSES_ROOT\Drive\shell\Powershell\command` command, you technically need to _escape_ that trailing `\ `. From `cmd.exe`, compare `powershell.exe -Command "write-output -LiteralPath \"C:\\"; get-date"` (broken) to `powershell.exe -Command "write-output -LiteralPath \"C:\\\"; get-date"` (OK). – mklement0 Nov 09 '21 at 20:13
  • 1
    Also in HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command, because "background" means when you right click on the "empty" part of a window of Windows Explorer, and you can easily open `C:\\` folder with GUI and right-click in a empty zone. Thank you. – Mario Palumbo Nov 09 '21 at 22:46
  • I have solved this quibble with this: `"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoExit -Command "Set-Location -LiteralPath \"%V/\"; get-date"` because are accepted also paths with slashes instead of backslashes. Also mix slashes and backslashes. Then `"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoExit -Command "Set-Location -LiteralPath \"C:\/\"; get-date"` Also multiple consecutive slashes and/or consecutive backslashes are accepted in the paths. Genial – Mario Palumbo Nov 13 '21 at 11:08
  • You may also notice a slight change in the "Set-ExecutionPolicy" command – Mario Palumbo Nov 13 '21 at 13:21
  • The trailing `/` is a clever workaround (an escaped trailing`\.` is also an option). The only remaining problem is the permissions issue with keys `HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command`,`HKEY_CLASSES_ROOT\Directory\Shell\Powershell\command`, and `HKEY_CLASSES_ROOT\Drive\shell\Powershell\command`, which I don't think can be solved with a `*.reg` file. I haven't tried to solve the problem programmatically, but interactively I had to change the keys' ownership to the Administrators group before I could give the latter full (write) access. – mklement0 Nov 13 '21 at 14:34
  • What is an escaped trailing. Can you give me some examples? – Mario Palumbo Nov 13 '21 at 14:56
  • Your `/` solution is simpler anyway, I only mentioned appending `\.` instead as a perhaps conceptually clearer alternative. By escaped I meant that you'll need to escape the `\ `, as usual. An example: `@="powershell.exe -noexit -command \"Set-Location -literalPath \\\"%V\\.\\\"\""`. This means that PowerShell will see `C:\\.` or `C:\foo\.` – mklement0 Nov 13 '21 at 15:48
  • That dot what means? – Mario Palumbo Nov 14 '21 at 01:26
  • Just like `.` in isolation refers to the current directory, `\.` at the end of an explicit directory path refers to that directory itself. E.g. `C:\temp\.` is in effect the same as `C:\temp` – mklement0 Nov 14 '21 at 02:03
  • @mklement0 `The only remaining problem is the permissions issue with keys` I have published an other topic about this, can you take a look at it? Thanks: https://stackoverflow.com/questions/70245334 – Mario Palumbo Dec 13 '21 at 15:44