Using start-job -scriptblock to run script; need help using parameters

Отвечено Using start-job -scriptblock to run script; need help using parameters

  • Friday, March 01, 2013 7:34 PM
     
     

    I've written a couple of PowerShell scripts to collect performance data from a group of servers.  GetPerfCounters.ps1 reads a text file with a list of servers and collects and outputs the counters.  StartPerfJobs.psq uses start-job to run multiple instances of GetPerfCounters.psq so I can split the work.  Here's the portion of the script that uses start-job:

    function StartJobs {
        param ([string] $ServerList, [string] $Path)
       
        Start-Job -ScriptBlock { c:\PerfData\GetPerfCounters.ps1 $args[0] $args[1] } -ArgumentList @($ServerList, $Path);
    }

    This is working great and gives me what I'm looking for.  Now, what I'd like to do is replace the path (c:\PerfData) in the scriptblock with the value being passed in, $Path, so that it would look something like this:

    function StartJobs {
        param ([string] $ServerList, [string] $Path)
       
        Start-Job -ScriptBlock { $args[1]\GetPerfCounters.ps1 $args[0] $args[1] } -ArgumentList @($ServerList, $Path);
    }
    I've tried various ways, but can't get it to work.  Any suggestions would be appreciated.

All Replies

  • Friday, March 01, 2013 7:47 PM
    Moderator
     
     Answered Has Code

    Passing arguments can get clumsy.

    When it starts getting complicated, I usually resort to just creating the scriptblock from an expandable string:

    $sb = [scriptblock]::create("$Path\GetPerfCounters.ps1 $ServerList $Path")
    Start-Job -ScriptBlock $sb
    



    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    • Marked As Answer by ButchW Monday, March 04, 2013 4:24 PM
    •  
  • Monday, March 04, 2013 1:31 PM
    Moderator
     
      Has Code

    Using named parameters with your job will also lessen the complexity that you will find by trying to use $args in the scriptblock.

    function StartJobs {
        param ([string] $ServerList, [string] $Path)    
        Start-Job -ScriptBlock { 
            Param ($ServerList,$Path)
            ."$path\GetPerfCounters.ps1 $ServerList $Path" 
        } -ArgumentList $ServerList, $Path 
    }


    Boe Prox
    Blog | PoshWSUS | PoshPAIG | PoshChat

  • Monday, March 04, 2013 4:23 PM
     
     

    Thanks for both of the replies.

    Boe, I had tried something like that before without success.  I tried it again and got this error:

    The term 'c:\PerfData\GetPerfCounters.ps1 c:\PerfData\PerfServerList1.txt c:\PerfData' 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.
        + CategoryInfo          : ObjectNotFound: (c:\PerfData\Get...txt c:\PerfData:String) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException

    I read somewhere that PowerShell can't run a string as a command, so tied adding the & operator, but still got an error.

    Rob's solution with the [scriptblock]::create suggestion works.

    Again, thanks to both of you for expanding my PowerShell knowledge.

    Butch WEber

  • Monday, March 04, 2013 6:45 PM
    Moderator
     
      Has Code

    That is correct, instead of using "." or the ampersand "&", you would need to use Invoke-Expression to run a string like a command. This may work better.

    function StartJobs {
        param ([string] $ServerList, [string] $Path)    
        Start-Job -ScriptBlock { 
            Param ($ServerList,$Path)
            Invoke-Expression "$path\GetPerfCounters.ps1 $ServerList $Path" 
        } -ArgumentList $ServerList, $Path 
    }


    Boe Prox
    Blog | PoshWSUS | PoshPAIG | PoshChat