I am trying to use Start-Job to launch a new Powershell script. The new script has several parameters (some optional, some not), so I want to make a hashtable and splat them. However, one of these parameters is itself a hash table. I am trying to start the job like this:
$MyStringParam = "string1"
$MyHashParam = @{}
$MyHashParam.Add("Key1", "hashvalue1")
$arguments = @{MyStringParam=$MyStringParam;MyHashParam=$MyHashParam}
Start-Job -Name "MyJob" -ScriptBlock ([scriptblock]::create("C:\myscript.ps1 $(&{$args} @arguments)"))
Whereupon I get this error in the new job:
Cannot process argument transformation on parameter 'arguments'.
Cannot convert the "System.Collections.Hashtable" value of
type "System.String" to type "System.Collections.Hashtable".
Looks like it's treating the value I want to pass in as a hash table as a string. For the life of me I can't figure out how to get around this. Can anyone help?
You will need to pass the variable into the scriptblock as a parameter of the scriptblock, and then splat that parameter to your second script. Something like this should work for you:
Start-Job -Name "MyJob" -ScriptBlock {Param($PassedArgs);& "C:\myscript.ps1" @PassedArgs} -ArgumentList $Arguments
I created the following script and saved it to C:\Temp\TestScript.ps1
Param(
[String]$InString,
[HashTable]$InHash
)
ForEach($Key in $InHash.keys){
[pscustomobject]@{'String'=$InString;'HashKey'=$Key;'HashValue'=$InHash[$Key]}
}
I then ran the following:
$MyString = "Hello World"
$MyHash = @{}
$MyHash.Add("Green","Apple")
$MyHash.Add("Yellow","Banana")
$MyHash.Add("Purple","Grapes")
$Arguments = @{'InString'=$MyString;'InHash'=$MyHash}
$MyJob = Start-Job -scriptblock {Param($MyArgs);& "C:\Temp\testscript.ps1" @MyArgs} -Name "MyJob" -ArgumentList $Arguments | Wait-Job | Receive-Job
Remove-Job -Name 'MyJob'
$MyJob | Select * -ExcludeProperty RunspaceId | Format-Table
It produced the expected results:
String HashKey HashValue
------ ------- ---------
Hello World Yellow Banana
Hello World Green Apple
Hello World Purple Grapes
The process of running the job will add a RunspaceId property to any objects returned, that is why I had to exclude that.