web-dev-qa-db-ja.com

Robocopyを使用したPowershellと引数の受け渡し

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コマンドオプションとして文字列を渡すにはどうすればよいですか(そして、より広い意味では、特定の外部コマンドに対して同じことを行います)

9
weloytty

_Start robocopy -args "$source $destination $fileLIst $robocopyOptions"_
または
robocopy $source $destination $fileLIst $robocopyOptions.split(' ')

15
Anton Z

ルーク、アレイを使用してください。値の配列を指定すると、PowerShellはそれらを個別のパラメーターに自動的に展開します。私の経験では、これが最も信頼できる方法です。また、Start-Processコマンドレットをいじる必要はありません。これは、そのようなタスクにはやり過ぎだと私は考えています。

このトリックは、外部実行可能ファイルに対するPowerShellの動作について私が見た中で最高の記事からです PowerShellと外部コマンドは正しく実行されました

例:

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

$CmdLine = @($source, $destination, $fileList) + $robocopyOptions
& 'robocopy.exe' $CmdLine
7
beatcracker

文字列を使用してそのようにオプションを渡すことはできません。

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
5
Bill_Stewart