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

This topic contains 5 replies, has 3 voices, and was last updated by Profile photo of Liang Cui Liang Cui 2 months, 4 weeks ago.

  • Author
    Posts
  • #53994
    Profile photo of Liang Cui
    Liang Cui
    Participant

    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]}

  • #54002
    Profile photo of Hermann Lüpfert
    Hermann Lüpfert
    Participant

    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

  • #54012
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    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}
  • #54014
    Profile photo of Liang Cui
    Liang Cui
    Participant

    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

  • #54026
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    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.

    • This reply was modified 2 months, 4 weeks ago by Profile photo of Curtis Smith Curtis Smith.

You must be logged in to reply to this topic.