如何让robocopy在powershell中运行?

Mar*_*son 32 powershell robocopy

我正在尝试在 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"
}
Run Code Online (Sandbox Code Playgroud)

该脚本接收一个包含源目录和目标目录列表的 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 !
Run Code Online (Sandbox Code Playgroud)

知道我需要做什么来修复吗?

谢谢,马克。

Hel*_*ick 26

如果您希望能够使用变量扩展并让生成的命令行正确理解您想要分隔哪些参数,哪些不应该分隔,那么从 Powershell 中将字符串填充到外部命令的参数中需要进行一些跳跃。在您的示例中,您将整个字符串作为第一个参数发送,而 Robocopy 告诉您它找不到作为源目录的长字符串。您确实希望将整个 Source 字符串视为一个参数(包括其中可能存在的空格),对于 Destination 也是如此,但您的 $what 和 $options 将失败,因为它们都将作为单个参数传递给 Robocopy,而不能是解析。

有几种方法可以正确执行此操作,但以下代码段基于您似乎想要分解参数的方式,并且适用于我使用的单目录示例。

$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
Run Code Online (Sandbox Code Playgroud)

  • +1。这绝对是这里的问题。我觉得有趣的是人们如何不断尝试使用 PowerShell,就好像它是一个旧的基于文本的 shell 一样;-) (3认同)
  • @DidierA.:当然。特别是当对象存在来描述您与之交互的事物时,例如文件、进程、服务等。但即使您只有本机应用程序和字符串输出,您也可以只使用常用的字符串运算符,例如“-match”和“-replace” ` 以及过滤/投影 cmdlet 来处理它。在这方面它通常设计得很好(大多数“*-Object”命令是正交的,它们都可以应用于任何对象)。 (2认同)

小智 14

如果变量$what$options不改变,为什么它们是变量?

$what = "/COPYALL /B /SEC /MIR" 
$options = "/R:0 /W:0 /NFL /NDL" 
Run Code Online (Sandbox Code Playgroud)

这对我来说很好用:

robocopy   $source $dest /COPYALL /B /SEC /MIR /R:0 /W:0 /NFL /NDL
Run Code Online (Sandbox Code Playgroud)

  • 我知道这是一篇旧帖子,但我认为值得一提的是,将这些作为变量是向脚本的未来读者发出的信号,即这些是脚本的可配置部分。这样做的原因是它恰好修复了原始 $what 中的错字。 (7认同)
  • /sec 不是 /sec/ 在这里也很关键 (3认同)
  • 即使某些内容没有改变,变量封装也可以帮助减少脚本的复杂性。如果事实证明我稍后需要再次引用该变量,它会使脚本更加动态 (2认同)