gerardog/gsudo

Issue: Function `Invoke-Gsudo` breaks on `pwsh v7.3`: Filename Syntax Incorrect

mattcargile opened this issue · 7 comments

Issue Description

I'm scratching my head on this one. Hopefully, I haven't missed something simple. I'm using pwsh v7.3.0 and the Invoke-Gsudo function within your gsudoModule. Normally I quickly run the exe to run quick admin tasks and I love it and use it every day.

I'm getting The filename, directory name, or volume label syntax is incorrect. on usage like invoke-gsudo { ps }. My pwd and [System.Environment]::CurrentDirectory are the same and are my $env:USERPROFILE directory.

Steps to Reproduce

  1. Invoke-gsudo { 'hello world' }
    The kicker seems to be PowerShell Core versus Desktop.

Screenshots

Exception             :
    Type        : System.Management.Automation.RemoteException
    ErrorRecord :
        Exception             :
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : The filename, directory name, or volume label syntax is incorrect.
            HResult : -2146233087
        CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : RuntimeException
    Message     : The filename, directory name, or volume label syntax is incorrect.
    HResult     : -2146233087
TargetObject          : The filename, directory name, or volume label syntax is incorrect.
CategoryInfo          : NotSpecified: (The filename, direc…yntax is incorrect.:String) [Write-Error], RemoteException
FullyQualifiedErrorId : NativeCommandError
InvocationInfo        :
    MyCommand        :
        Set-StrictMode -Off #within this scope

        ForEach ($item in $result)
        {
                if (
                $item.psobject.Properties['Exception'] -and
                ($item.Exception.SerializedRemoteException.WasThrownFromThrowStatement -or
                 $item.Exception.WasThrownFromThrowStatement)
                )
                {
                        throw $item
                }
                if ($item -is [System.Management.Automation.ErrorRecord])
                {
                        Write-Error $item
                }
                else
                {
                        Write-Output $item;
                }
        }

    ScriptLineNumber : 184
    OffsetInLine     : 1
    HistoryId        : 38
    Line             : & {

    PositionMessage  : At line:184 char:1
                       + & {
                       + ~~~
    InvocationName   : &
    CommandOrigin    : Internal
ScriptStackTrace      : at Invoke-Gsudo, <No file>: line 180
                        at <ScriptBlock>, <No file>: line 1

Context:

  • Windows version: Win10 21H1
  • gsudo version: 2.0.2

Hi Matt!

❯ .\Invoke-gsudo.ps1 -debug {whoami} 
...
Debug: Command Line: -d --LogLevel Error --debug "\"C:\Program" "Files\PowerShell\7\pwsh.exe\"" -NoProfile "" -nologo -NonInteractive -OutputFormat Xml -InputFormat Text -encodedCommand IAAoACQAaQBuAHAAdQB0ACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAKQAgAHwAIABpAGUAeAAgAA==

The way I quote pwsh.exe breaks with Pwsh 7.3.0

❯ scoop install pwsh@7.2.7
WARN  Given version (7.2.7) does not match manifest (7.3.0)
WARN  Attempting to generate manifest for 'pwsh' (7.2.7)
Autoupdating pwsh
Installing 'pwsh' (7.2.7) [64bit]
PowerShell-7.2.7-win-x64.zip (103,7 MB) [=====================================================================] 100%
Checking hash of PowerShell-7.2.7-win-x64.zip ... ok.
Extracting PowerShell-7.2.7-win-x64.zip ... done.
Running pre_install script...
Linking ~\scoop\apps\pwsh\current => ~\scoop\apps\pwsh\7.2.7
Creating shim for 'pwsh'.
Creating shortcut for PowerShell Core (pwsh.exe)
Persisting Microsoft.PowerShell_profile.ps1
Persisting profile.ps1
Running post_install script...
'pwsh' (7.2.7) was installed successfully!

❯ C:\Users\gerar\scoop\apps\pwsh\7.2.7\pwsh.exe
PowerShell 7.2.7
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

   A new PowerShell stable release is available: v7.3.0
   Upgrade now, or check out the release page at:
     https://aka.ms/PowerShell-Release?tag=v7.3.0

Loading personal and system profiles took 4067ms.

❯ .\Invoke-gsudo.ps1 { whoami.exe }
desktop\gerar

Invoke-gsudo.ps1 is doing:

$arguments = "-d --LogLevel Error $user$dbg$pwsh $sNoProfile -nologo -NonInteractive -OutputFormat Xml -InputFormat Text -encodedCommand IAAoACQAaQBuAHAAdQB0ACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAKQAgAHwAIABpAGUAeAAgAA==".Split(" ")

$result = $remoteCmd | & gsudo.exe $arguments *>&1

That .Split(" ") may be part of the problem... I need to split but respecting quoted args...

Some more info on Pwsh v7.3 breaking change:
https://stackoverflow.com/questions/59036580/pwsh-command-is-removing-quotation-marks/59036879#59036879

Also this part: You need to manually \-escape " instances was needed before v7.3 and was implemented here:

.ReplaceOrdinal("\"", "\\\"")

... and now needs to be suppressed if Pwsh>=v7.3

As a sidenote, currently this syntax is working and may in some circunstances it performs better:

  • gsudo { whoami.exe }

You can try to replace the file with https://github.com/gerardog/gsudo/blob/Fix.InvokeGsudoOnPwshv7.3/src/gsudo.Wrappers/Invoke-gsudo.ps1

Works great! I just popped the file into my folder and tried. Thanks for the quick work on it! I didn't realize Invoke-Gsudo.ps1 had gotten much more complicated!

Fixed in v2.0.3