How to get robocopy running in powershell?

Solution 1:

If the variables for $what and $options don't change, why are they variables?

$what = "/COPYALL /B /SEC /MIR" 
$options = "/R:0 /W:0 /NFL /NDL" 

This works fine for me:

robocopy   $source $dest /COPYALL /B /SEC /MIR /R:0 /W:0 /NFL /NDL

Solution 2:

Populating strings into parameters for external commands from within Powershell requires some hoop jumping if you want to be able to use variable expansion and also have the resulting command line properly understand which parameters you want to be separated and which should not. In your example you are sending the entire string as the first parameter and Robocopy is telling you that it can't find that long string as a source directory. You do want the entire Source string to be treated as one param (including spaces that may be in there), likewise for Destination but your $what and $options will fail because they will both be delivered to Robocopy as a single parameter which cannot be parsed.

There are a few ways to do this right but the following snippet is based on the way you seem to want to break out your parameters and does work for the single directory example I've used.

$source="C:\temp\source"
$dest="C:\temp\dest"

$what = @("/COPYALL","/B","/SEC","/MIR")
$options = @("/R:0","/W:0","/NFL","/NDL")

$cmdArgs = @("$source","$dest",$what,$options)
robocopy @cmdArgs

Solution 3:

Remove the quotes from the robocopy line?

i.e.

param ($configFile)

$config = Import-Csv $configFile
$what = "/COPYALL /B /SEC/ /MIR"
$options = "/R:0 /W:0 /NFL /NDL"
$logDir = "C:\Backup\"

foreach ($line in $config)
{
 $source = $($line.SourceFolder)
 $dest = $($line.DestFolder)
 $logfile =  $logDIr 
 $logfile += Split-Path $dest -Leaf
 $logfile += ".log"

 robocopy $source $dest $what $options /LOG:MyLogfile.txt
}

Solution 4:

I had the same problem. The whole command line was interpreted as the first argument.

Nothing mentioned above worked including:

invoke-expression "robocopy ""$sourceFolder"" ""$destinationFolder"" /MIR"  
invoke-expression "robocopy \`"$sourceFolder\`" \`"$destinationFolder\`" /MIR"  

Leaving out the quotes doesn't work when there's a space in the path:

invoke-expression "robocopy $sourceFolder $destinationFolder /MIR"  

After trying the tricks in http://edgylogic.com/blog/powershell-and-external-commands-done-right/, I finally got it.

robocopy "\`"$sourceFolder"\`" "\`"$destinationFolder"\`" /MIR

Maybe I should have stuck with bat files. :)

Solution 5:

I have found that the best way to execute a native command is to use the & command to execute a list of strings. Also if you want the console output to be included in a powershell transcript you will need to pipe the output to out-host. Here is an example of calling 7Zip with multiple parameters taken from a 7-Zip to Amazon S3 Powershell Script that I wrote:

$7ZipPath = "C:\Program Files\7-Zip\7z.exe" #Path to 7Zip executable
$FolderPath = "C:\Backup" #Folder to backup (no trailing slash!)
$FolderName = $FolderPath.Substring($FolderPath.LastIndexOf("\")+1) #grab the name of the backup folder
$TimeStamp = [datetime]::Now.ToString("yyyy-MM-dd_HHmm") #Create unique timestamp string
$strFile = [String]::Format("{0}\{1}_{2}.7z", "c:\",$FolderName,$TimeStamp) #Create filename for the zip
#7z options: add, type 7z, Archive filename, Files to add (with wildcard. Change \* to \prefix* or \*.txt to limit files), compression level 9, password, encrypt filenames, Send output to host so it can be logged.
& $7ZipPath "a" "-t7z" "$strFile" "$FolderPath\*" "-mx9" "-r" "-pPASSWORD" "-mhe" | out-host #create archive file
if($LASTEXITCODE -ne 0){ #Detect errors from 7Zip. Note: 7z will crash sometimes if file already exists
    Write-Error "ERROR: 7Zip terminated with exit code $LASTEXITCODE. Script halted."
    exit $LASTEXITCODE
}

Basically for your case I would try something like this (may need to break out the $what and $options parameters individually):

$robocopypath = "c:\pathtofolder\robocopy.exe"
& $robocopypath "$source" "$dest" "$what" "$options" "/LOG:MyLogfile.txt"