【问题标题】:Powershell with Robocopy and Arguments Passing带有 Robocopy 和参数传递的 Powershell
【发布时间】:2015-06-16 05:47:38
【问题描述】:

我正在尝试编写一个使用robocopy 的脚本。如果我只是手动执行此操作,我的命令将是:

robocopy c:\hold\test1 c:\hold\test2 test.txt /NJH /NJS

但是,当我从 powershell 执行此操作时,例如:

$source = "C:\hold\first test"
$destination = "C:\hold\second test"
$robocopyOptions = " /NJH /NJS "
$fileList = "test.txt"

robocopy $source $destination $fileLIst $robocopyOptions

我明白了:

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Robust File Copy for Windows
-------------------------------------------------------------------------------

  Started : Fri Apr 10 09:20:03 2015

   Source - C:\hold\first test\
     Dest - C:\hold\second test\

    Files : test.txt

  Options : /COPY:DAT /R:1000000 /W:30

------------------------------------------------------------------------------

ERROR : Invalid Parameter #4 : " /NJH /NJS "

但是,如果我将 robocopy 命令更改为

robocopy $source $destination $fileLIst  /NJH /NJS 

一切顺利。

所以,我的问题是,如何将字符串作为我的 robocopy 命令选项传递(并且,在更大的意义上,对任何给定的外部命令执行相同的操作)

【问题讨论】:

    标签: powershell command-line-arguments robocopy


    【解决方案1】:

    Start robocopy -args "$source $destination $fileLIst $robocopyOptions"

    robocopy $source $destination $fileLIst $robocopyOptions.split(' ')

    【讨论】:

    • 如果您不介意单独的控制台窗口,Start-Process 也可以。
    • 使用-NoNewWindow -PassThru -Wait 参数来避免单独的控制台窗口
    • IIRC,Start-Process 不会更新 $LASTEXITCODE。在某些情况下,这可能很重要。
    【解决方案2】:

    使用数组,卢克。如果您指定一个值数组,PowerShell 会自动将它们展开为单独的参数。根据我的经验,这是最可靠的方法。而且它不需要你弄乱Start-Process cmdlet,我认为这对于此类任务来说是多余的。

    这个技巧来自我看过的关于 PowerShell 对外部可执行文件的行为的最佳文章:PowerShell and external commands done right

    例子:

    $source = 'C:\hold\first test'
    $destination = 'C:\hold\second test'
    $robocopyOptions = @('/NJH', '/NJS')
    $fileList = 'test.txt'
    
    $CmdLine = @($source, $destination, $fileList) + $robocopyOptions
    & 'robocopy.exe' $CmdLine
    

    【讨论】:

    【解决方案3】:

    您不能使用字符串以这种方式传递选项,因为当您编写时

    robocopy $source $destination $fileList $robocopyOptions
    

    PowerShell 会将最后一个变量 ($robocopyOptions) 评估为单个字符串并引用它。这意味着 robocopy 将在其命令行上获得 "/NJH /NHS"(单字符串,带引号)。 (显然不是本意。)

    有关如何解决此类问题的详细信息,请参阅此处:

    http://windowsitpro.com/powershell/running-executables-powershell

    文章包含以下功能:

    function Start-Executable {
      param(
        [String] $FilePath,
        [String[]] $ArgumentList
      )
      $OFS = " "
      $process = New-Object System.Diagnostics.Process
      $process.StartInfo.FileName = $FilePath
      $process.StartInfo.Arguments = $ArgumentList
      $process.StartInfo.UseShellExecute = $false
      $process.StartInfo.RedirectStandardOutput = $true
      if ( $process.Start() ) {
        $output = $process.StandardOutput.ReadToEnd() `
          -replace "\r\n$",""
        if ( $output ) {
          if ( $output.Contains("`r`n") ) {
            $output -split "`r`n"
          }
          elseif ( $output.Contains("`n") ) {
            $output -split "`n"
          }
          else {
            $output
          }
        }
        $process.WaitForExit()
        & "$Env:SystemRoot\system32\cmd.exe" `
          /c exit $process.ExitCode
      }
    }
    

    这个函数可以让你在当前控制台窗口中运行一个可执行文件,还可以让你构建一个字符串参数数组来传递给它。

    所以在你的情况下,你可以像这样使用这个函数:

    Start-Executable robocopy.exe $source,$destination,$fileList,$robocopyOptions
    

    【讨论】:

      【解决方案4】:

      将选项放在单独的参数中对我有用。使用 Robocopy 进行复制,不包括任何 CSV 文件。

      $roboCopyPath = $env:ROBOCOPY_PATH
      $otherLogsPath = [System.IO.Path]::Combine($basePath, "Logs-Other")
      $atrTestResults = [System.IO.Path]::Combine($Release, $BuildNumber)
      $ResultsSummary = [System.IO.Path]::Combine($basePath, "Result")
      
      $robocopyOptions = @("/log:$otherLogsPath\robocopy.log", '/xf', '*.csv')
      $CmdLine = @($atrTestResults, $ResultsSummary) + $robocopyOptions 
      &$roboCopyPath $CmdLine
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-27
        • 2021-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-25
        • 1970-01-01
        相关资源
        最近更新 更多