Ever needed a function you have created local, inside a remote session or a ForEach-Object -Parallel? Look no further, I may have what you need.

Let’s say we have a created a function called Get-LocalVariables:

Function Get-LocalVariables {
    Write-Output "Computername: $env:COMPUTERNAME"
    Write-Output "Processor Count: $env:NUMBER_OF_PROCESSORS"
    Write-Output "Processor Architecture: $env:PROCESSOR_ARCHITECTURE"
}

Now we need to run this function inside an remote session:

$ServerList = "Server01", "Server02"

Invoke-Command -ComputerName $ServerList -ScriptBlock { Get-LocalVariables }

ObjectNotFound: The term 'Get-LocalVariables' is not recognized as the name of a cmdlet, function, script file, 
or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct 
and try again.
ObjectNotFound: The term 'Get-LocalVariables' is not recognized as the name of a cmdlet, function, script file, 
or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct
and try again.

The code above won’t work because the function Get-LocalVariables is not available on those computers. We could copy the contents of the function inside of the scriptblock instead of the function. But when we change the function, we also need to revisit this script. Not the best way of doing things.

Instead of the above, we can also dynamically read the contents of the function and then rebuild the function within the remote session.

$LocalVarFunction = ${Function:Get-LocalVariables}.ToString()
Invoke-Command -ComputerName $ServerList -ScriptBlock {
    ${Function:Get-LocalVariables} = [scriptblock]::Create($Using:LocalVarFunction)

    Get-LocalVariables
}
Computername: Server01
Processor Count: 2
Processor Architecture: AMD64
Computername: Server02
Processor Count: 2
Processor Architecture: AMD64

We can also do this for ForEach-Object -Parallel:

$LocalVarFunction = ${Function:Get-LocalVariables}.ToString()
1..10 | ForEach-Object -Parallel {
    ${Function:Get-LocalVariables} = [scriptblock]::Create($Using:LocalVarFunction)

    Get-LocalVariables
}
Computername: LocalMachine
Processor Count: 6
Processor Architecture: AMD64
Computername: LocalMachine
Processor Count: 6
Processor Architecture: AMD64
Computername: LocalMachine
.......

Leave a Reply

Your email address will not be published. Required fields are marked *