0

I have this script with a scriptblock:

$RoboArgs = @{
  Source = '01'
  Target = '02'
  ExtraArgs = '/e', '/purge'
}
Write-Host @RoboArgs
Start-ThreadJob -InputObject $RoboArgs -ScriptBlock {
  . robocopy_invoke.ps1
  Write-Host @input
} | Receive-Job -Wait -AutoRemoveJob

I want to call a function defined in the robocopy_invoke.ps1 module using the input parameter (Invoke-Robocopy @RoboArgs), but the input parameter's contents somehow get changed once it enters the scriptblock. Here's the output:

-Target: 02 -ExtraArgs: /e /purge -Source: 01
System.Management.Automation.Runspaces.PipelineReader`1+<GetReadEnumerator>d__20[System.Object]

Why is the output different for the two Write-Host calls? How can I make the second one like the first one?

gargoylebident
  • 373
  • 1
  • 2
  • 12

1 Answers1

2

You use '-InputObject' to pipe objects into the job (retrieve using $input). So Start-ThreadJob -InputObject $RoboArgs -ScriptBlock {} is equivalent to $RoboArgs | Start-ThreadJob -ScriptBlock {}

What you need instead is '-ArgumentList' (retrieve using $args):

$RoboArgs = @{
  Source = '01'
  Target = '02'
  ExtraArgs = '/e', '/purge'
}
$RoboArgs

Start-ThreadJob -ArgumentList $RoboArgs -ScriptBlock {
  $args
} | Receive-Job -Wait -AutoRemoveJob

Example 2 (unpack $args arrays)

$RoboArgs = @{
  Source = '01'
  Target = '02'
  ExtraArgs = '/e', '/purge'
}
Write-Host @RoboArgs

Start-ThreadJob -ArgumentList $RoboArgs -ScriptBlock {
  $robo = $args[0]
  Write-Host @robo
} | Receive-Job -Wait -AutoRemoveJob

Example 3 (explicitly define parameters instead of using $args)

$RoboArgs = @{
    Source    = '01'
    Target    = '02'
    ExtraArgs = '/e', '/purge'
}
Write-Host @RoboArgs


Start-ThreadJob -ArgumentList $RoboArgs -ScriptBlock {
    param ( $myRoboArgs )
    Write-Host @myRoboArgs
} | Receive-Job -Wait -AutoRemoveJob
MikeSh
  • 352
  • 1
  • 5
  • They're still different when using `-ArgumentList`. `Write-Host @RoboArgs` returns `-Target: 02 -ExtraArgs: /e /purge -Source: 01` while `Write-Host @args` now returns `System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry`. Just calling the variable (`@input`) worked with `-InputObject` as well so I don't see how `args` helps. – gargoylebident Feb 17 '22 at 11:50
  • 1
    @gargoylebident, $args is an array of arguments. In this case, array of one argument. if you want to see exactly the same output using Write-Host , then use $args[0] - see updated answer – MikeSh Feb 17 '22 at 11:57
  • 1
    if you are not comfortable with $args, then you can explicitly define parameters in your scriptblock (the same syntax as function). see addtional example – MikeSh Feb 17 '22 at 12:05