Powershell with Robocopy and Arguments Passing

[亡魂溺海] 提交于 2019-11-30 03:51:25

问题


I'm trying to write a script that uses robocopy. If I were just doing this manually, my command would be:

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

BUT, when I do this from powershell, like:

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

robocopy $source $destination $fileLIst $robocopyOptions

I get:

-------------------------------------------------------------------------------
   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 "

However, if I change the robocopy command to

robocopy $source $destination $fileLIst  /NJH /NJS 

everything runs successfully.

So, my question is, how can I pass a string as my robocopy command options (and, in a larger sense, do the same for any given external command)


回答1:


Start robocopy -args "$source $destination $fileLIst $robocopyOptions"
or
robocopy $source $destination $fileLIst $robocopyOptions.split(' ')




回答2:


Use the arrays, Luke. If you specify an array of values, PowerShell will automatically expand them into separate parameters. In my experience, this is the most reliable method. And it doesn't require you to mess with the Start-Process cmdlet, which is in my opinion is overkill for such tasks.

This trick is from the best article I've seen on the PowerShell behavior towards external executables: PowerShell and external commands done right.

Example:

$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:


You can't use a string to pass options in that way because when you write

robocopy $source $destination $fileList $robocopyOptions

PowerShell will evaluate the last variable ($robocopyOptions) as a single string and it will quote it. This means robocopy will get "/NJH /NHS" (single string, quoted) on its command line. (Obviously not the intent.)

For details on how to work around these kinds of issues, see here:

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

The article includes the following function:

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
  }
}

This function will let you run an executable in the current console window and also let you build an array of string parameters to pass to it.

So in your case you could use this function something like this:

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


来源:https://stackoverflow.com/questions/29562598/powershell-with-robocopy-and-arguments-passing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!