PowerShell Remoting ScriptBlock Output Question

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

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #37805
    Profile photo of David Newsom
    David Newsom
    Participant

    Howdy,

    I am new to using PSRemoting and am using it in a computer lab environment. I understand how to construct a control script to run Invoke-Command but I am stuck on this. I am running this on multiple computers and I have several commands inside the scriptblock. I am looking for results like so: Display output of each computer on screen, example:

    Computer1
    command 1 results
    command 2 results
    command 3 results

    However what I am getting is this:
    Computer1
    command 1 results
    Computer2
    command 1 results

    command 2 results
    command 2 results

    command 3 results

    If I run with a throttlelimit 1
    then i get the desired results but it's slow...

    How can I get the output to be organized under each computer name and not have it all displayed out of order. Attached is a link to view screen shots. Please help me with this. I have spent 3 days searching and testing and am now going out of my mind with data overload and still can't get this to work for me the way I think it should or the way I want it to work.

    Download screenshots Link:

    https://utexas.box.com/s/kk2vsyiic65d7zw6vhyj9up6swhutegn

    Thanks a lot PS1 community.

    David

    #37807

    Hello, I think behavior you are observing is by design, you may occasionally get result in desired order, but only because it so happened (if you ever get them in desired order). You could specify -OutVariable, and after that do a quick sort by PScomputername property.

    icm server -ScriptBlock {something} -OutVariable var
    $var | sort pscomputername
    #37840
    Profile photo of Justin King
    Justin King
    Participant

    Another option is to capture the output to an arraylist so that you can sort or display it anyway you want despite the asynchronous return time from servers.

    You'd have to do a little more work on your script block so it returns data in the right format, but then you can just output the arraylist at the end in whatever order meets your fancy.

    Just make sure to define the variable upfront like: [System.Collections.ArrayList]$Example=@() otherwise PS will default to an array which is fixed length and wont let you add additional objects. Something like:

     [System.Collections.ArrayList]$Example=@() 
    $Example=+ (Invoke-Command -Session $blah -ScriptBLock {my script goes here and returns spiffy things})
    

    I find that having an arraylist is easy to dump into other cmdlets to make CSVs or other kinds of reports. Even if you don't need a formal report, each server/session ends up as it's own custom object so you can easily "see" any specific server output with something as simple as $example[0].

    #37847
    Profile photo of David Newsom
    David Newsom
    Participant

    Thanks for the suggestions. I still can't seem to get anything to work the way I want it to. The only way I can get this to work without using a foreach loop, which I know is not the recommended way when using PSRemoting, is to use the -ThrottleLimit 1 paramenter with Invoke-Command. It runs the commands slower because it's running on one PC at a time but for my computer lab I guess time doesn't matter but organized and readable output does matter. I need to know if a command failed or not and on which PC. So here is my simple PSRemoting script and desired output. This is just an example and not what I really run on the machines. I wish there was another way to get this so I didn't have to use -ThrottleLimit 1 but I just can't come up with it. I love the broadcast of the scriptblock that invoke-command does but I need organized output for each computer. I hope I am explaining all of this correctly.

    Thanks again everyone...

    # Array of Computer Names
    $ComputerName = "mode-01","mode-02","mode-16"
    
    
    # Domain Account Credentials
    $Cred = Get-Credential
    
    
    # Run Invoke-Command ScriptBlock (with Throttle 1 so it runs on each PC one at a time)
    Invoke-Command -ComputerName $ComputerName -Credential $Cred -ThrottleLimit 1 -ScriptBlock {
    
    
    Function Write-Log ($message) {$timestamp=Get-Date; Write-Output "$($timestamp): $($env:computername): $($message)"}
    
    
    Write-Host ""
    Write-Host ""
    Write-Host ""
    Write-Log "Run 'GP Update'"
    Write-Host ""
    cmd /c gpupdate /force
    
    
    Write-Host ""
    Write-Host ""
    Write-Host ""
    Write-Host "$($env:COMPUTERNAME): Removing directory c:\Temp\Test.txt" -BackgroundColor DarkRed -ForegroundColor White
    Write-Host ""
    if (Test-Path "c:\Temp\Test.txt")
    {
    Write-Host "Removing the file"
    Remove-Item -Path "c:\Temp\Test.txt" -Force
    }
    else
    {
    Write-Host "The file was not found"
    }
    
    
    } # End ScriptBlock
    
    
    04/15/2016 11:13:59: MODE-01: Run 'GP Update'
    
    Updating Policy...
    
    
    
    User Policy update has completed successfully.
    
    Computer Policy update has completed successfully.
    
    
    
    
    
    
    MODE-01: Removing directory c:\Temp\Test.txt
    
    The file was not found
    
    
    
    04/15/2016 11:14:15: MODE-02: Run 'GP Update'
    
    Updating Policy...
    
    
    
    User Policy update has completed successfully.
    
    Computer Policy update has completed successfully.
    
    
    
    
    
    
    MODE-02: Removing directory c:\Temp\Test.txt
    
    The file was not found
    
    
    #37849
    Profile photo of Jonathan Warnken
    Jonathan Warnken
    Participant

    Hove you tried running it as a Job?

    # Array of Computer Names
    $ComputerName = "mode-01","mode-02","mode-16"
    
    # Domain Account Credentials
    $Cred = Get-Credential
    
    Invoke-Command -ComputerName $ComputerName -Credential $Cred -AsJob -JobName  $ComputerName-ScriptBlock { Your Code Here}
    
    #Wait for all jobs
    Get-Job | Wait-Job
    
    #Get all job results
    Get-Job | Receive-Job
    
Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.