Run Local Function Remotely with Arguments Unordered

Tagged: 

This topic contains 9 replies, has 3 voices, and was last updated by Profile photo of Dan Potter Dan Potter 4 months ago.

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #40519
    Profile photo of Duffney
    Duffney
    Participant

    Is it possible to execute a local function remotely and specify the argument order? See example

    function myfunction ($param1,$param2){
         get-dscresource -module $param2 -name $param1
    }
    
    invoke-command server -scriptblock ${function:myfunction} -argumentslist $param1,$param2 #< -- does not work
    invoke-command server -scriptblock ${function:myfunction} -argumentslist $param2,$param1 #<-- works
    

    The reason I'm asking is because several functions that I'd like to execute remotely do not have sequential parameters and it appears to only feed in mandatory parameters.

    #40592
    Profile photo of Dan Potter
    Dan Potter
    Participant

    Yes, try splatting. Define named parameters inside the function.

    #40607
    Profile photo of Dan Potter
    Dan Potter
    Participant

    Here are two options.

    
    $splat = @{
    
    fore = 'red'
    back = 'white'
    
    }
    
    icm -scriptblock {write-host "this is splatting" @splat} -argumentlist $splat 
    
    
    
    
    
    function myfunction{
      
    
    param(
    
    [parameter(mandatory=$true)]
    [string]$fore,
    
    [parameter(mandatory=$true)]
    [string]$back
    
    )
    
     icm -scriptblock {write-host "this is text" -fore $fore -back $back } -argumentlist $fore,$back
    
    }
    
    
    
    #40625
    Profile photo of Duffney
    Duffney
    Participant

    That works when running a normal script block, but for some reason when you use the local function method it runs the arguments in sequences and provides the variables to the mandatory parameters in that order. As a work around I'm just entering the session running the script from ISE into the remote server session and executing the function I need.

    Below works

    function MyFunction ($ModuleName,$Name)
    {
        Get-DscResource -Module $ModuleName -Name $Name
    }
    
    $Module = 'xAdcsDeployment'
    $Name = 'xAdcsWebEnrollment'
    
    icm -ComputerName cert -ScriptBlock ${Function:MyFunction} -ArgumentList $Module,$Name
    

    Below does not work because it attempts to use $Name for the -Module parameter

    function MyFunction ($ModuleName,$Name)
    {
        Get-DscResource -Module $ModuleName -Name $Name
    }
    
    $Module = 'xAdcsDeployment'
    $Name = 'xAdcsWebEnrollment'
    
    icm -ComputerName cert -ScriptBlock ${Function:MyFunction} -ArgumentList $Name,$Module
    

    I attempted to use splatting, but it doesn't seem to allow you to use the -parameter name to specify which parameter to use with which variable...

    function MyFunction ($ModuleName,$Name)
    {
        Get-DscResource -Module $ModuleName -Name $Name
    }
    
    $splat = @{
    Module = 'xadcsdeployment'
    Name = 'xAdcsWebEnrollment'
    }
    
    icm -ComputerName cert -ScriptBlock ${Function:MyFunction} -ArgumentList $splat
    
    #40643
    Profile photo of Dan Potter
    Dan Potter
    Participant

    It hurts when I do this doc:-)

    #40657
    Profile photo of Michael Willis
    Michael Willis
    Participant

    Perhaps something like this:

    function MyFunction
    {
        [CmdletBinding()]
        param
        (
            [Parameter()]
            [ValidateNotNullOrEmpty()]
            [PSTypeName('DSCResource')]$DSCResource
        )
    
    
        Get-DscResource -Module $DSCResource.ModuleName -Name $DSCResource.Name
    }
    
    
    $resource = [pscustomobject]@{
        PSTypeName = 'DSCResource'
        ModuleName = 'xPSDesiredStateConfiguration'
        Name = 'MSFT_xArchive'
    }
    
    icm -ComputerName servername -ScriptBlock ${Function:MyFunction} -ArgumentList $resource
    
    #40677
    Profile photo of Michael Willis
    Michael Willis
    Participant

    It's a start, but here is an example of interchangeable parms.

    function MyFunction
    {
        [CmdletBinding()]
        param
        (
            [Parameter()]
            [ValidateNotNullOrEmpty()]
            $ModuleName,
            
            [Parameter()]
            [ValidateNotNullOrEmpty()]
            $Name
        )
    
        if(Get-Module -ListAvailable | Where-Object { $_.name -eq $ModuleName }) 
        {
            Write-Verbose "Module-Name Order"
            Get-DscResource -Module $ModuleName -Name $Name
        }
        elseif(Get-Module -ListAvailable | Where-Object { $_.name -eq $Name }) 
        {
            Write-Verbose "Name-Module Order"
            Get-DscResource -Module $Name -Name $ModuleName
        }
        else
        {
            Write-Verbose "Module Doesn't Exist"
        }
    }
    
    
    $server = 'servername'
    
    # Proper Order
    icm -ComputerName $server -ScriptBlock ${Function:MyFunction} -ArgumentList 'xPSDesiredStateConfiguration', 'MSFT_xArchive'
    
    # Flipped Order
    icm -ComputerName $server -ScriptBlock ${Function:MyFunction} -ArgumentList 'MSFT_xArchive', 'xPSDesiredStateConfiguration'
    
    # Bogus
    icm -ComputerName $server -ScriptBlock ${Function:MyFunction} -ArgumentList 'xxx','yyy'
    
    #40679
    Profile photo of Duffney
    Duffney
    Participant

    How do you mean Dan? Never hurts to reply, I always appreciate all and any replies on my posts 🙂

    Michael,

    I'll give that a try and update the function I'm working on to include that logic, I'm also thinking I can modify it to specify the param order in the function. I'll post once I've got it working 🙂

    Thanks!

    #40704
    Profile photo of Duffney
    Duffney
    Participant

    Got it working! By using the Position option for parameters I was able to move them around, so if you just use that to move around the position you can pass them in ordered and get it to work.

    function MyFunction
    {
        [CmdletBinding()]
        Param
        (
            # Param1 help description
            [Parameter(Position=0)]
            $Name,
    
            # Param2 help description
            [Parameter(Position=1)]
            $Module
        )
    
        Get-DscResource -Module $Module -Name $Name
    
    }
    
    $Module = 'xAdcsDeployment'
    $Name = 'xAdcsWebEnrollment'
    
    icm -ComputerName cert -ScriptBlock ${Function:MyFunction} -ArgumentList $Name,$Module
    
    #40716
    Profile photo of Dan Potter
    Dan Potter
    Participant

    A man goes to the Doc and says 'Doc, it hurts when I do this' and the doctor says 'Then don't do that':-)

    It'd still be beneficial to put the command within the function. Use another argument to accept array of computers.

Viewing 10 posts - 1 through 10 (of 10 total)

You must be logged in to reply to this topic.