Author Posts

April 21, 2014 at 1:14 pm

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
	}

April 21, 2014 at 2:21 pm

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.

April 22, 2014 at 1:34 pm

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.

April 22, 2014 at 1:35 pm

Using Invoke-Command?

-AsJob -JobName WHATEVER

All in the help file 😉

April 23, 2014 at 7:03 am

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"

April 23, 2014 at 7:13 am

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.

April 23, 2014 at 7:29 am

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

April 23, 2014 at 10:03 am

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
}

April 23, 2014 at 10:21 am

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