我试图在PowerShell中使用robocopy镜像我的家用机器上的一些目录。 这是我的脚本:
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" }
该脚本接收一个带有源目录和目标目录列表的csv文件。 当我运行脚本时,我得到这些错误:
------------------------------------------------------------------------------- ROBOCOPY :: Robust File Copy for Windows ------------------------------------------------------------------------------- Started : Sat Apr 03 21:26:57 2010 Source : P:\ C:\Backup\Photos \COPYALL \B \SEC\ \MIR \R:0 \W:0 \NFL \NDL \LOG:MyLogfile.txt\ Dest - Files : *.* Options : *.* /COPY:DAT /R:1000000 /W:30 ------------------------------------------------------------------------------ ERROR : No Destination Directory Specified. Simple Usage :: ROBOCOPY source destination /MIR source :: Source Directory (drive:\path or \\server\share\path). destination :: Destination Dir (drive:\path or \\server\share\path). /MIR :: Mirror a complete directory tree. For more usage information run ROBOCOPY /? **** /MIR can DELETE files as well as copy them !
任何想法我需要做什么来解决?
谢谢,马克。
如果$what
和$options
的variables不变,为什么它们是variables?
$what = "/COPYALL /B /SEC /MIR" $options = "/R:0 /W:0 /NFL /NDL"
这对我来说很好:
robocopy $source $dest /COPYALL /B /SEC /MIR /R:0 /W:0 /NFL /NDL
从Powershell中将string填充到外部命令的参数中,如果您希望能够使用variables扩展,并且使得生成的命令行能够正确理解哪些参数要分隔,哪些不应该分隔,则需要进行一些循环跳转。 在你的例子中,你发送整个string作为第一个参数,Robocopy告诉你它不能find这个长string作为源目录。 您希望整个Sourcestring被视为一个参数(包括可能在那里的空格),同样对于Destination,但是您的$ what和$ options将会失败,因为它们都将作为单个parameter passing给Robocopy,parsing。
有几种方法可以做到这一点,但下面的代码片段是基于你想要突破你的参数,并为我使用的单个目录示例工作。
$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
从robocopy行删除引号?
即
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 }
我有同样的问题。 整个命令行被解释为第一个参数。
上面没有提到的工作包括:
invoke-expression "robocopy ""$sourceFolder"" ""$destinationFolder"" /MIR" invoke-expression "robocopy \`"$sourceFolder\`" \`"$destinationFolder\`" /MIR"
当path中存在空格时,省略引号不起作用:
invoke-expression "robocopy $sourceFolder $destinationFolder /MIR"
在http://edgylogic.com/blog/powershell-and-external-commands-done-right/尝试了技巧后,我终于明白了。
robocopy "\`"$sourceFolder"\`" "\`"$destinationFolder"\`" /MIR
也许我应该坚持使用bat文件。 🙂
我发现执行本地命令的最好方法是使用&命令来执行一个string列表。 另外,如果你想把控制台输出包含在一个PowerShell脚本中,你将需要将输出pipe道输出到外部主机。 下面是一个使用从7-Zip到Amazon S3 Powershell脚本的多个参数调用7Zip的示例,我写道:
$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 }
基本上你的情况下,我会尝试这样的事情(可能需要分开$ what和$ options参数):
$robocopypath = "c:\pathtofolder\robocopy.exe" & $robocopypath "$source" "$dest" "$what" "$options" "/LOG:MyLogfile.txt"
invoke-expression "robocopy $source $dest $what $options /LOG:MyLogfile.txt"
这将内插所有的variables,然后调用结果string。 现在你已经有了这个方法,看起来robocopy正在引用所有的选项,比如robocopy“c:\ src c:\ dst blah meh”。 这被解释为单个参数。
这对我有用,并允许日志文件位置的dynamicinput。 &符号只是告诉PowerShell文本是我想要运行的一行代码。
$source = "E:\BackupToRestore\" $destination = "E:\RestoreMe\" $logfile = "E:\robocopyLogFile.txt" $switches = ("/B", "/MIR", "/XJ", "/FFT", "/R:0", "/LOG:$logfile") & robocopy $source $destination $roboCopyString $switches
#Important to send to log for error checking Start-Process robocopy -ArgumentList "$SourcePath $DestinationPath $OptionsRBC" -NoNewWindow -Wait -RedirectStandardOutput C:\temp\test3.txt