I made a script to unlock bitlocker volumes using the password manager autotype feature instead of the clipboard. It uses gsudo and needs some features available only in 7.4.
$DriveLetter = Read-Host "Drive letter"
$DriveLetter = ($DriveLetter + ":")
$EncUserCredential = Read-Host "Enter Password" -AsSecureString | ConvertFrom-SecureString
gsudo pwsh.exe -CommandWithArgs '`$parm1 = ConvertTo-SecureString -String `$args[1]; Unlock-Bitlocker -MountPoint `$args[0] -Password `$parm1' $DriveLetter $EncUserCredential
When I run the script directly in a 7.4.6 shell I get:
Drive letter: w
Enter Password: ********************
Unlock-BitLocker: Cannot process argument transformation on parameter 'Password'. Cannot convert the value of type "System.String" to type "System.Security.SecureString".
Conversely, if I run it in 5.1 (7.4 is invoked later in the script) it works, why? This forces me to keep 5.1 as the default powershell for my terminal, not a big deal but still... Also, the policy for unsigned scripts is only applied to 5.1, it seems to me that this makes the setting somewhat less relevant.
From a PowerShell session, gsudo
offers convenient syntax for invoking PowerShell commands directly, using a script block ({ ... }
) and optional arguments, which can be passed as an array to the -Args
parameter:
gsudo {
$parm1 = ConvertTo-SecureString -String $args[1]
Unlock-Bitlocker -MountPoint $args[0] -Password $parm1
} -Args $DriveLetter, $EncUserCredential
Compared to your attempt to call pwsh
, the PowerShell (Core) 7 CLI, explicitly, the above is:
As for what you tried:
By passing an explicit pwsh
CLI call to gsudo
, you're complicating the escaping needs even further (compared to passing just a single argument containing PowerShell code as a string) and, for reasons unknown to me, the -Command
(-c
) parameter behaves differently from the (v7.4+) -CommandWithArgs
(-cwa
) parameter.
gsudo pwsh -c ' `$HOME + """!"""; Get-Date '
works (but note the obscure escaping requirements),gsudo pwsh -cwa ' `$HOME + """!"""; Get-Date '
does not (note the missing !
in the output).If you were to pass the command string alone - in which case no extra escaping is required - things would be simpler (e.g., gsudo ' $HOME + "!"; Get-Date '
), but then you couldn't pass arguments separately, the way you tried via -CommandWithArgs
However, given the simpler and more robust alternative based on script blocks shown at the top, this isn't a problem that needs solving.