Powershell: Feature Request - Invoke-Command should support passing parameters as a hashtable

Created on 6 Feb 2019  路  8Comments  路  Source: PowerShell/PowerShell

Summary of the new feature/enhancement

Simply put, rather than:

Invoke-Command $sb -ArgumentList $arg1, $arg2

I would like to be able to do:

Invoke-Command $sb -Parameters @{NamedArg = $value1; Switch = $true}

(note that currently it's _impossible_ to call a scriptblock with a [switch] parameter as they cannot be passed positionally; this would serve to resolve that, effectively, while permitting more complex functions)

This would enable a function to do something _very_ amusing, like so:

Invoke-Command -ComputerName testPC -Scriptblock $MyInvocation.MyCommand.ScriptBlock -Parameters $PSBoundParameters

Not that that's really my use case, just thought it was fun! I'm mostly interested in giving Invoke-Command more robust function calling capability so we can call local functions in a remote session more easily, a la:

Invoke-Command -ScriptBlock ${function:Test-Function} -Parameters $Params -ComputerName RemotePC
Issue-Enhancement

Most helpful comment

I am having this issue too and splatting is not the issue... Not accepting named arguments is the issue.

All 8 comments

Something like this might already be possible with splatting:

% $Params=@{"LiteralPath" = "C:\"; "Hidden" = $true;}; invoke-command -ScriptBlock { Get-ChildItem @Params }


C:\

d--hs-        2/13/2017  10:23 PM                $RECYCLE.BIN
d--h--         2/3/2019   3:23 PM                $WINDOWS.~BT
d--hs-         2/4/2019   5:07 PM                Config.Msi
d--hsl        8/25/2016   8:17 PM                Documents and Settings
d--h--       11/17/2018   6:36 PM                ProgramData
d--h--        9/18/2018   5:32 PM                Recovery
d--hs-        9/22/2017   5:53 PM                System Volume Information
-a-hs-         2/4/2019   4:54 PM     6840606720 hiberfil.sys
-a-hs-         2/4/2019   4:54 PM     2550136832 pagefile.sys
-a-hs-         2/4/2019   4:54 PM       16777216 swapfile.sys

Your last example might be possible by pasting the body of the function into a new function on the other end and splatting args against the _new_ remote function. I tried to get that working, but in the limited time I allocated to prototyping I couldn't.

Yes @DHowett this can be done, but the syntax for doing so is _decidedly_ more irritating to use!

Example:

$Parameters = @{Param1 = $Value; Switch = $true}
Invoke-Command -ComputerName RemotePC -ScriptBlock {
    New-Item Function:\TempFunc -Value ${using:function:my-function} > $null
    TempFunc @using:Parameters
}

Being how relatively easy this is to accomplish in any case, Invoke-Command should just support it out of the box in my opinion.

@iSazonov yeah, I've been following along with that one.

This is less about splatting itself and more about how Invoke-Command doesn't support passing parameters to its script block by name, only by position with -ArgumentList.

The RFC targets "Splatting in method invocations" too. If it doesn't resolve your request we need to enhance the RFC I believe.

That portion of the RFC is designed to be used specifically with .NET methods. For example:

[System.IO.File]::ReadAllBytes@@{Path = 'C:\test.txt' }

The fact that Invoke-Command as a Cmdlet itself only supports passing positional arguments to the script block parameter when it invokes is a separate issue.

I am having this issue too and splatting is not the issue... Not accepting named arguments is the issue.

Hey Guys, This is a real issue with scripts as it is easy to get the order of parameters wrong and write bad scripts. The ideal solution, to me, would look like this

$args = @{
    P1 = 1
    P3 = 3
    P2 = 2
}

Invoke-Command -ScriptBlock{
    param($P1, $P2, $P3)
    Write-Host "$P1 $P2 $P3"
} -ArgumentList @args -Session $somesession

if you have a script with lots of parameters you want to call on another session, you are in for ugly brittle code ;-)
also maybe

Invoke-Command -FilePath d:\scripts\someFile.ps1 -ArgumentList @args -Session $somesession
Was this page helpful?
0 / 5 - 0 ratings