Prof. Powershell

Function Junction: Running Functions with PowerShell Remote

Here's how to launch a function when you're not physically at the intended system.

One of the great things about remoting in PowerShell is that you can run a script on remote computers and the script doesn't have to be on the remote computer. The script can live locally and its contents are executed remotely. But what about functions that you might have loaded into your current session? How can you run those with PowerShell remoting?

One way might be to modify the script file that defines the function so that it also runs the function and then execute that remotely. But I don't like having to modify working scripts for no good reason. So here is another technique. I'm going to use this function which has been loaded into my PowerShell session as an example

Function Get-RecycleBin {
Param([string]$Drive="C:\")
$path = Join-Path -Path $Drive -ChildPath '$Recycle.bin'
dir -literalpath $path -hidden  | dir -Recurse -file
measure-object -property length -Sum |
Select @{Name="Path";Expression={$Drive}},
Count,Sum,@{Name="Computername";Expression={$env:Computername}}
}

It doesn't matter how the function got into my console. The point is that I can see it in the Function PSDrive.

PS C:\> dir Function:\Get-RecycleBin

CommandType     Name                                    ModuleName
-----------     ----                                    ----------
Function        Get-RecycleBin

In the Function drive, my command is an object and one of its properties is called ScriptBlock.

PS C:\> dir Function:\Get-RecycleBin | select -expand scriptblock

Param([string]$Drive="C:\")
$path = Join-Path -Path $Drive -ChildPath '$Recycle.bin'
dir -literalpath $path -hidden | dir -Recurse -file |
measure-object -property length -Sum |
Select @{Name="Path";Expression={$Drive}},
Count,Sum,@{Name="Computername";Expression={$env:Computername}}

As you can see, this is the body of my function. To use this function remotely, all I need to do is grab this scriptblock.

PS C:\> invoke-command -scriptblock (get-item Function:\Get-RecycleBin).scriptblock -computername chi-win8-01 -hidecomputername

Path         : C:\
Count        : 35
Sum          : 1685322
Computername : CHI-WIN8-01
RunspaceId   : b4c7cc45-fe8f-4fec-a9c7-1c44a7b6a513

Invoke-Command grabbed the function contents and ran it remotely. Since my function already includes the computername, I told Invoke-Command to hide the computername it automatically displays. If you find yourself needing to repeat this, it might be easier to save the function scriptblock to a variable.

PS C:\> $grb = (get-item Function:\Get-RecycleBin).scriptblock
PS C:\> invoke-command -ScriptBlock $grb -ComputerName $computers -Credential globomantics\jeff -hidecomputername | Sort Sum –Descending | Format-Table Sum,Count,Computername -Autosize

Sum Count Computername
--- ----- ------------
1685322    35 CHI-WIN8-01
9370     6 CHI-WIN81  
3233     3 CHI-FP01   

In the long run, if this is a function I find myself needing to run remotely, it might be worth revising it to include that capability. But in the short term, this is a handy technique I think you might find valuable.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular