Passing parameter to Start-Job

This topic contains 8 replies, has 3 voices, and was last updated by Profile photo of GS GS 3 years, 2 months ago.

  • Author
    Posts
  • #14676
    Profile photo of GS
    GS
    Participant

    Hello,

    I spent several hours trying to figure out why my function do not receive parameters when I invoke it via Start-Job

    My function (DoCleanup accepts single [string] parameter)
    I call it in code below and yet parameter is $null inside the function. What am I missing?

    
    $func = {function DoCleanup 
    	{		(
    			[parameter(Mandatory=$true,ValueFromPipeline=$true)]
    			[string]$computerName)
    			Write-Output "Starting to clean up space on $computerName"
    }
    
    foreach ($computerName in $computerNames)
    	{
    		Start-Job -ScriptBlock {DoCleanup $args[0]} -ArgumentList $computerName -Name "$computerName" -InitializationScript $func
    	}
    
    
  • #14677
    Profile photo of Don Jones
    Don Jones
    Keymaster

    The docs describe -ArgumentList as only applying to the -FilePath parameter.

    However, Invoke-Command (when used with -AsJob) does more or less the same thing (albeit via Remoting). it works like this:


    Invoke-Command -ScriptBlock { param($one,$two) do-something -param1 $one -param2 $two } -Argument 'a','b'

    The arguments are attached to the variables in the Param() block.

  • #14706
    Profile photo of GS
    GS
    Participant

    Thanks,

    How do I create a job with a Name (like -Name parameter in Start-Job cmdlet). I'm really surprised that Start-Job does not provide a way to pass arguments to scriptblock.

  • #14707
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Using Invoke-Command?

    -AsJob -JobName WHATEVER

    All in the help file 😉

  • #14723
    Profile photo of GS
    GS
    Participant

    Thanks, somehow I missed that part.
    I still trying to figure out how to use Start-job directly (Invoke-Command use in this case seems to be a "hack" rather then clean instantiation of the job).
    Is documentation for Start-Job is wrong or why following snippet works fine below and passing ArgumentList just fine to scriptblock even though documentation state that -ArgumentList is used only in case -FilePath parameter is used?

    Start-Job -ScriptBlock {Write-Host $args[0]} -ArgumentList "3"

  • #14724
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Invoke-Command isn't a "hack." It's the preferred way to start a job that will deal with one or more remote computers; it's also completely normal to use it against the local computer. Start-Job isn't particularly more or less "clean."

    Because I tend to administer more than just the local computer, I tend to rely on Invoke-Command a lot. So, I haven't played with Start-Job much. I tend to stick with what I know, and what I know works, rather than beat myself up making other stuff work. I find Invoke-Command's argument-passing to be a lot more declarative and a lot cleaner, too.

  • #14725
    Profile photo of GS
    GS
    Participant

    I understand what you are saying but documentation is in fact wrong about ArgumentList. In fact it's filed as a bug

    https://connect.microsoft.com/PowerShell/feedback/details/563695/argumentlist-parameter-to-start-job-incomplete

  • #14737
    Profile photo of GS
    GS
    Participant

    Thanks, that was it.
    Not sure why Microsoft did not catch up with help file being wrong on -ArgumentList usage

  • #14735
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Your problem isn't with passing arguments to the job. The problem is that your function is malformed (missing one closing curly brace, and the "param" keyword). This revision works fine for me:

    $computerNames = @('.')
    
    $func = {
        function DoCleanup 
        {
            param (
                [parameter(Mandatory=$true,ValueFromPipeline=$true)]
                [string]$computerName
            )
    			
            Write-Output "Starting to clean up space on $computerName"
        }
    }
    
    foreach ($computerName in $computerNames)
    {
        Start-Job -ScriptBlock {DoCleanup $args[0]} -ArgumentList $computerName -Name “$computerName” -InitializationScript $func
    }
    

You must be logged in to reply to this topic.