Search code examples
powershellinvoke-commandstart-job

Unable to start scriptblock as background or remote job, works fine executing directly


I have a scriptblock I would like to run as a background job. Below is the command I would like to run:

Get-ChildItem -Recurse $source |  Get-DfsrFileHash | Export-csv -Append C:\Temp\Test_Source_Checksum.csv

If I run this command it goes through successfully with no issues.

I have tried the following for 'Start-Job'

Start-Job -ScriptBlock { Get-ChildItem -Recurse $source |  Get-DfsrFileHash | Export-csv -Append C:\Temp\Test_Source_Checksum.csv } 

This results in 'Get-Job' displaying as completed, when it actually hasnt, or doesnt appear to have judging by the missing file: 'Test_Source_Checksum.csv'

I have also tried using the following for 'Invoke-Command'

Invoke-Command -AsJob -ComputerName ($env:COMPUTERNAME) -ScriptBlock { Get-ChildItem -Recurse $source |  Get-DfsrFileHash | Export-csv -Append C:\Temp\Test_Source_Checksum.csv } 

This results in 'Get-Job' displaying failed.

If I display the failure using:

(get-job -name Job38).JobStateInfo.Reason

I get nothing back...

Am I using Start-Job/Invoke-Command incorrectly here?

The reason I would like to run this as a background job is, im trying to copy large amounts of data and checksum it (for a DFS Migration). I would like to copy the data in smaller subsets, then checksum the data which has been copied whilst its copying the next batch over...rinse and repeat

Thanks,

Chris

EDIT: Here is a copy of the whole script:

##----------------------------------------------------------------------------------##
$source="E:\DFSR_Migration_Test_Prod"
$dest="F:\DFSR_Migration_Test_Prod"
$what = @("/COPYALL","/B","/SEC","/E","/xd","dfsrprivate")
$options = @("/R:6","/tee","/MT:32")
$cmdArgs = @("$source","$dest",$what,$options)
##----------------------------------------------------------------------------------##
robocopy @cmdArgs
Write-Output "Prod_Copied @" (get-date) | Out-File C:\Temp\File_Copy.txt -Encoding ascii -Append -NoClobber
Write-Output "Initiating Prod Source Checksum @" (get-date) | Out-File C:\Temp\File_Copy.txt -Encoding ascii -Append -NoClobber
Start-Job -ScriptBlock { Get-ChildItem -Recurse $source | Get-DfsrFileHash | Export-csv C:\Temp\Prod_Source_Checksum.csv }
Write-Output "Initiating Prod Destination Checksum @" (get-date) | Out-File C:\Temp\File_Copy.txt -Encoding ascii -Append -NoClobber
Start-Job -ScriptBlock { Get-ChildItem -Recurse $dest | Get-DfsrFileHash | Export-csv C:\Temp\Prod_Destination_Checksum.csv }

Solution

  • How are you passing $source? Because if you're doing nothing other than writing the variable name it'll be null, and if it's null you'll be executing Get-ChildItem for $pwd.Path on the remote system.

    The simplest solution is to make $source into $using:Source.

    Invoke-Command -AsJob -ComputerName ($env:COMPUTERNAME) -ScriptBlock { Get-ChildItem -Recurse $using:source |  Get-DfsrFileHash | Export-csv -Append C:\Temp\Test_Source_Checksum.csv }