Powershell:use invoke-command with custom function to execute at remote computer

I am struggling with invoke-Command to execute custom function remotely and display the output at the local host. I’ve read many posts regarding invoke-Command online but I haven’t find a way to resolve this problem.

First the custom function is working. It’s called get-openfiles. The code is provided below:

 
function get-openfiles{                                                                                  
 param(                                                                                                   
 $computername=@($env:computername),                                                                      
 $verbose=$false)                                                                                         
 $collection = @()                                                                                        
 foreach ($computer in $computername){                                                                    
 $netfile = [ADSI]"WinNT://$computer/LanmanServer"                                                        

 $netfile.Invoke("Resources") | foreach {                                                                 
 try{                                                                                                     
 $collection += New-Object PsObject -Property @{                                                          
 Id = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)                                  
 itemPath = $_.GetType().InvokeMember("Path", 'GetProperty', $null, $_, $null)                            
 UserName = $_.GetType().InvokeMember("User", 'GetProperty', $null, $_, $null)                            
 LockCount = $_.GetType().InvokeMember("LockCount", 'GetProperty', $null, $_, $null)                      
 Server = $computer                                                                                       
 }                                                                                                        
 }                                                                                                        
 catch{                                                                                                   
 if ($verbose){write-warning $error[0]}                                                                   
 }                                                                                                        
 }                                                                                                        
 }                                                                                                        
 Return $collection                                                                                       
 }

I have used following methods but none of them working. Some of example below will work for built-in function but my condition is that I have to use the custom function.

NOT WORKING #1

$s = New-PSSession -ComputerName remote-STL
$CifServer = “fs-STL-01”
function get-openfiles{…}
invoke-command -Session $s -ScriptBlock ${function:get-openfiles} -ArgumentList $CifServer

NOT WORKING #2

$s = New-PSSession -ComputerName remote-STL
$CifServer = “fs-STL-01”
invoke-command -Session $s -ScriptBlock {Import-Module C:\scripts\grp-functions.psm1}
invoke-command -Session $s -ScriptBlock {get-openfiles -computername $args[0]} -ArgumentList $CifServer

Not working #3

$s = New-PSSession -ComputerName remote-STL
$CifServer = “fs-STL-01”
invoke-command -Session $s -ScriptBlock {Import-Module C:\scripts\grp-functions.psm1}
invoke-command -Session $s -ScriptBlock { param($CifServer) get-openfiles -computername $Cifserver } -ArgumentList $CifServer

Not working #4

$CifServer = “fs-STL-01”
function get-openfiles{…}
invoke-command -ComputerName remote-STL -ScriptBlock ${function:get-openfiles} -ArgumentList $CifServe

not working #5

$CifServer = “fs-STL-01”
invoke-command -ComputerName remote-STL -ScriptBlock {get-openfiles -computername $args[0]}

Hei,

I don’t have the answer but I’d try to find the answer here https://www.gitbook.com/book/devopscollective/secrets-of-powershell-remoting/details.

Hermann

Hi Liang,
I confused as to your need to use invoke-command here. The script is written to allow you to supply the computername you want to return the results for.

get-openfiles -computername "fs-STL-01"

However, if you want to use invoke-command for some reason, you can do it this way.

invoke-command -ComputerName "fs-STL-01" -ScriptBlock ${function:get-openfiles}

Hi Curtis, the reason I can’t use invoke-command directly to fs-stl-01 is that is one of data storage units (not a real Window Server). I CAN use

 get-openfiles -computername “fs-STL-01” 
but the fs-STL-01 is located at St. Louise Datacenter. The performance will suffer greatly because the computer I am using for powershell is located in Seattle. Therefore, I have to use remote-STL server which it is at the same location with fs-STL-01. The script I am writing will execute from one location and if it found out the data located at remote datacenter, it will use invoke-command to execute remotely from local Windows server and return the result back to the host computer (the one in Seattle).

Thanks for look into it.

-Liang

Hey Liang,
It appears you are running into the classic “Second Hop” issue with PowerShell remoting. This is disallowed by default.

Check out “Secrets of PowerShell Remoting” in the eBooks link above in the site menu. It discusses this issue and much more.

Thanks for the advice, Curtis AND Hermann. I have started looking for answer from this link: GitBook - Where software teams break knowledge silos..

If I figured out the correct codes/syntax. I will post back to this thread.