1

I am making attempting to fix an app which has recently broken the ls command, using a Powershell wrapper script. My wrapper must have the same name as the command it is invoking, so I'm using invoke-command to call the original command.

# yarn broke 'ls'
function yarn() {
    $modifiedArgs = @()
    foreach ( $arg in $args ) {
        if ( $arg -cmatch '^ls$' ) {
            $arg = 'list'
        }
        $modifiedArgs = $modifiedArgs + $arg
    }
    invoke-command yarn -ArgumentList @modifiedArgs
}

However invoke-command fails with

Invoke-Command : Parameter set cannot be resolved using the specified named parameters

How can I run the original command with the modified parameters?

Edit: I've also tried -ArgumentList (,$modifiedArgs) per Passing array to another script with Invoke-Command and I still get the same error.

Edit: Looks like invoke-command is remoting only. I've also tried Invoke-Expression "& yarn $modifiedArgs" but that runs the function itself.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
  • You want to write a "proxy function". There is some good information on this at [Microsoft's Scripting Guy column](https://blogs.technet.microsoft.com/heyscriptingguy/2011/03/01/proxy-functions-spice-up-your-powershell-core-cmdlets/), [Microsoft TechNet's Script Center Repository](https://gallery.technet.microsoft.com/scriptcenter/New-ProxyCommand-a-simple-9735745e), and [PowerShell With a Purpose (Windows ITPro)](http://windowsitpro.com/blog/powershell-proxy-functions#). If you want more info, [this Google search](https://www.google.com/search?q=Proxy+command+powershell) may be useful. – Jeff Zeitlin Sep 28 '17 at 13:02
  • Thanks @JeffZeitlin but this is a binary command: I'm not wrapping other powershell. Even if it was, extracting the code of the original function per the Scripting Guy column seems like using a sledgehammer to crack a walnut here. – mikemaccana Sep 28 '17 at 13:06

2 Answers2

1

Per the powershell docs the & operator works:

# yarn broke 'ls'
function yarn() {
    $modifiedArgs = @()
    foreach ( $arg in $args ) {
        if ( $arg -cmatch '^ls$' ) {
            $arg = 'list'
        }
        $modifiedArgs += $arg
    }
    & 'C:\Program Files (x86)\Yarn\bin\yarn.cmd' $modifiedArgs
}

Still happy to accept other answers that don't involve specifying the command path explicitly.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
1

I belive you can get around needing to specify the full path to the command if you scope the wrapper function to Private:

# yarn broke 'ls'
function Private:yarn() {
    $modifiedArgs = @()
    foreach ( $arg in $args ) {
        if ( $arg -cmatch '^ls$' ) {
            $arg = 'list'
        }
        $modifiedArgs += $arg
    }
    & yarn $modifiedArgs
}

This will prevent the function from being visible to child scopes, and it will revert back to using the application.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
mjolinor
  • 66,130
  • 7
  • 114
  • 135