admin管理员组

文章数量:1435859

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.

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.

Share Improve this question asked Nov 15, 2024 at 20:34 mehmeh 756 bronze badges 2
  • 1 Why do you escape dollars with Grave Accent inside the -CommandWithArgs single-quoted string? – JosefZ Commented Nov 16, 2024 at 20:14
  • @JosefZ: This need arises due to the PowerShell CLI call being passed to gsudo.exe; however, such an invocation is suboptimal and best avoided: in a PowerShell session, you can pass a piece of PowerShell code directly to gsudo.exe, and it is best to use a script block. – mklement0 Commented Nov 16, 2024 at 21:42
Add a comment  | 

1 Answer 1

Reset to default 1

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:

  • more convenient
  • avoids escaping headaches
  • supports returning typed data, within the usual constraints of PowerShell's cross-process serialization infrastructure (see this answer for background information)

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.

    • E.g., gsudo pwsh -c ' `$HOME + """!"""; Get-Date ' works (but note the obscure escaping requirements),
      whereas the equivalent 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.

本文标签: