locked
Start-Job using a foreach loop RRS feed

  • Question

  • I am trying to execute multiple jobs with a for each loop inside the script block of the start-job cmdlet similar to the below.

    $users1=Get-ADUser -Filter {samaccountname -eq 'user1' -or samaccountname -eq 'user2'}
    
    $Users2=Get-ADUser -Filter {samaccountname -eq 'user3' -or samaccountname -eq 'user4'}
    
    $job1 = Start-Job -ScriptBlock {foreach($a in $users1){Get-ADUser $a}}
    
    $job2 = Start-Job -ScriptBlock {foreach($b in $users2){Get-ADUser $b}}

    But the jobs complete instantly and have no objects in them. clearly missing some important piece of this. (I know this is a bit silly in terms of gathering the same users twice but humor me please )



    • Edited by escott0699 Wednesday, November 6, 2019 8:21 PM
    Wednesday, November 6, 2019 8:17 PM

Answers

  • Withing the script block of the job, it's a different scope.  You'd have to use the using: scope.  Also only set $users1 to a plain list of names, not the whole objects.  I would say pass in the array as a parameter to the script block, but that seems to be an issue.  Note that PS 5 doesn't have the background operator (&).


    $users1 = (Get-ADUser -Filter {samaccountname -eq 'user1' -or
      samaccountname -eq 'user2'}).samaccountname
    $job1 = Start-Job -ScriptBlock {foreach($a in $using:users1){Get-ADUser $a}}

    Wednesday, November 6, 2019 9:38 PM

All replies

  • Please read the documentation for Start-Job and pay close attention to the rules, requirements and examples of usage.

    help start-job -online

    Try all of the examples until you understand how the command works.

    Always read the help for the CmdLets that you are having an issue with before you attempt to post in a forum. Why ask others to read the help for you. It is inefficient and you are likely to get bad answers to most of your new user questions.


    \_(ツ)_/

    Wednesday, November 6, 2019 8:45 PM
  • Withing the script block of the job, it's a different scope.  You'd have to use the using: scope.  Also only set $users1 to a plain list of names, not the whole objects.  I would say pass in the array as a parameter to the script block, but that seems to be an issue.  Note that PS 5 doesn't have the background operator (&).


    $users1 = (Get-ADUser -Filter {samaccountname -eq 'user1' -or
      samaccountname -eq 'user2'}).samaccountname
    $job1 = Start-Job -ScriptBlock {foreach($a in $using:users1){Get-ADUser $a}}

    Wednesday, November 6, 2019 9:38 PM
  • Withing the script block of the job, it's a different scope.  You'd have to use the using: scope.  Also only set $users1 to a plain list of names, not the whole objects.  I would say pass in the array as a parameter to the script block, but that seems to be an issue.  Note that PS 5 doesn't have the background operator (&).


    $users1 = (Get-ADUser -Filter {samaccountname -eq 'user1' -or
      samaccountname -eq 'user2'}).samaccountname
    $job1 = Start-Job -ScriptBlock {foreach($a in $using:users1){Get-ADUser $a}}

    What happens when the first command returns two users?

    Example:

    1..4 |Where{$_ -eq 2 -or $_ -eq 3}


    \_(ツ)_/


    • Edited by jrv Thursday, November 7, 2019 2:16 AM
    Thursday, November 7, 2019 2:14 AM
  • An array works fine with "using:".  But this way it becomes a problem.  It will only use the first element:

    start-job { param ($myarray) $myarray } -ArgumentList 1,2,3


    Here's the workaround for this case:

    start-job { param ($myarray) $myarray } -ArgumentList (,(1,2,3)) |
      receive-job -wait -AutoRemoveJob

    • Edited by JS2010 Thursday, November 7, 2019 1:44 PM
    Thursday, November 7, 2019 4:23 AM
  • That works perfectly.

    Thanks!

    Thursday, November 7, 2019 3:54 PM