Start-Job and Group-Object

This topic contains 3 replies, has 2 voices, and was last updated by  Kris Brewster 1 year, 11 months ago.

  • Author
    Posts
  • #32313

    Kris Brewster
    Participant

    I am running a command that groups a list of files by length.

     
    $f = Get-Childitem -recurse -file -path c:\documents
    $v = $f | Group-Object -property Length | Where {$_.Count -gt 1}
    
    This works fine but I would like to run this command with start-job.
    
    Using the variable $f 
    
    
    Start-job -scriptblock {param($value)  $value | Group-Object -property Length | Where {$_.Count -gt 1} } -Name GrpLength -Argumentlist $f
    
    $duplicates = Receive-job -name GrpLength
    

    My problem is that this does not return any values.

  • #32315

    Dave Wyatt
    Moderator

    Are you waiting for the job to complete first? There's really no advantage to using Start-Job if you're just going to immediately try to fetch the results.

    Just for giggles, try adding a unary comma when calling Start-Job:

    $scriptBlock = {param($value)  $value | Group-Object -property Length | Where {$_.Count -gt 1} }
    
    Start-job -scriptblock $scriptBlock -Name GrpLength -ArgumentList ,$f
    

    This is because the -ArgumentList parameter accepts an array. If your $f variable contains multiple objects, and you don't use the comma, then only the first element of the array will be bound to your $value parameter (and the rest would show up in the automatic $args array.) By using the unary comma, $value will be equal to $f (the entire contents of the array).

    Or, in this case, you could just not bother with a param block and use the automatic $args variable:

    $scriptBlock = {$args | Group-Object -property Length | Where {$_.Count -gt 1} }
    Start-job -scriptblock $scriptBlock -Name GrpLength -ArgumentList $f
    
  • #32316

    Kris Brewster
    Participant

    Thank you, I was unaware of the automatic $args variable.

  • #32317

    Kris Brewster
    Participant

    Dave,
    You had asked if I was waiting for the job to finish. Sorry I did not include that in the original question. I am using Start-job to use a progress bar so the tech using the script will not think that it has stopped on large directory/files. Here is the rest of the section you helped me with.

    		$ScriptBlock = {$args | Group-Object -Property Length | where {$_.Count -GT 1}} 
    		Start-Job -ScriptBlock $ScriptBlock -Name GrpLength -ArgumentList $ddup
    		$i = 0		
    		do {Write-Progress -Activity "Grouping files by length Please Wait " -Status "$i Time elapsed in Seconds"
    			sleep 1
    			$i++
    			$job2 = Get-Job -Name GrpLength 
    			} 
    		while ($job2.state -eq "Running")
    		$ddup1 = Receive-Job -Name GrpLength -Keep
    

You must be logged in to reply to this topic.