Author Posts

May 27, 2016 at 2:23 am

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.

May 27, 2016 at 12:38 pm

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

May 27, 2016 at 1:39 pm

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

}


May 27, 2016 at 1:54 pm

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

May 27, 2016 at 2:10 pm

It hurts when I do this doc:-)

May 27, 2016 at 2:27 pm

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

May 27, 2016 at 3:14 pm

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'

May 27, 2016 at 3:38 pm

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!

May 27, 2016 at 5:13 pm

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


	
			
	

May 27, 2016 at 5:51 pm

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.