Brad
Brad

Reputation: 2185

Copying files from one source to multiple destinations in parallel

I'm attempting to write a microsoft powershell script which copies files from a single source to multiple destinations in parallel based on a config file. The config file is a CSV file which looks like this:

Server,Type
server1,Production
server2,Staging

My script is called with one argument (.\myscript.ps1 buildnumber) but it doesn't seem to actually do any deleting or copying of files.

I'm sure my copy-item and remove-item code works as I have tested them independently but I think its either an issue with how I am using script blocks or perhaps how I am using start-job.

Could anyone help me understand why this isn't working?

Thanks Brad

<#  
File Deployment Script
#>
#REQUIRES -Version 2

param($build)
$sourcepath = "\\server\software\$build\*" 

$Config = import-csv -path C:\config\serverlist.txt 

$scriptblock1 = {
    $server = $args[0]
    $destpath1 = "\\$server\share\Software Wizard\"
    $destpath2 = "\\$server\share\Software Wizard V4.9XQA\"

    remove-item "$destpath1\*" -recurse -force
    remove-item "$destpath2\*" -recurse -force

    copy-item $sourcepath -destination $destpath1 -recurse -force
    copy-item $sourcepath -destination $destpath2 -recurse -force
}

$scriptblock2 = {
    $server = $args[0]
    $destpath = "\\$server\share\Software Wizard\"
    #remove-item "$destpath\*" -recurse -force 
    copy-item $sourcepath -destination $destpath -recurse -force
}

foreach ($line in $Config) {
    $server = $line.Server
    $type = $line.Type

    if ($type -match "Staging") {

    Write-Host "Kicking job for $server off"
    start-job -scriptblock $scriptblock2 -ArgumentList $server
}


if ($type -match "Production") {
            Write-Host "Kicking job for $server off"
    start-job -scriptblock $scriptblock2 -ArgumentList $server

}
}

Upvotes: 2

Views: 6034

Answers (2)

Emperor XLII
Emperor XLII

Reputation: 13422

To elaborate on Jamey's answer, you can see that the $sourcepath variable declared in the caller scope is not available within the job by comparing the output of the two calls below:

$sourcepath = 'source path'
$scriptblock = { Write-Host "sourcepath = $sourcepath; args = $args" }

& $scriptblock 'server name'
Start-Job $scriptblock -ArgumentList 'server name' | Wait-Job | Receive-Job


To fix this, simply pass the outer variable as part of the argument list:

$scriptblock2 = {
  param($sourcepath, $server)

  $destpath = ...
  Copy-Item $sourcepath -Destination $destpath -Recurse -Force
}

...
Start-Job -Scriptblock $scriptblock2 -ArgumentList $sourcepath,$server

Upvotes: 0

Jamey
Jamey

Reputation: 1633

Your script block doesn't have access to variables declared outside of it when it's called from start-job. So $scriptblock1 and $scriptblock2 can't see $sourcepath.

Upvotes: 1

Related Questions