2015-04-10 15 views
6

Próbuję napisać skrypt, który wykorzystuje robocopy Gdybym tylko to robić ręcznie, moja komenda będzie:?.

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

ale kiedy robię to z PowerShell, jak:

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

robocopy $source $destination $fileLIst $robocopyOptions 

uzyskać:

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

Jednak jeśli zmienię komendy robocopy do

robocopy $source $destination $fileLIst /NJH /NJS 

wszystko przebiega pomyślnie.

Więc moje pytanie brzmi: w jaki sposób można przekazać ciąg jako moich opcji poleceń robocopy (i, w szerszym znaczeniu, to samo dla każdej komendy zewnętrznej)

Odpowiedz

9

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

+0

dziękuję, Anton. – weloytty

+0

"Rozpocznij proces" jest OK, jeśli nie masz nic przeciwko oddzielnemu oknu konsoli. –

+1

użyj argumentów '-NoNewWindow -PassThru -Wait' aby uniknąć oddzielnego okna konsoli –

4

nie można używać ciąg przekazać opcje w ten sposób, ponieważ kiedy piszesz

robocopy $source $destination $fileList $robocopyOptions 

PowerShell oceni ostatnią zmienną ($robocopyOptions) jako pojedynczy ciąg i będzie go zacytować. Oznacza to, że robocopy otrzyma "/NJH /NHS" (pojedynczy ciąg, cytowany) w wierszu poleceń. (. Oczywiście nie intencją)

Szczegółowe informacje na temat sposobu obejścia tego rodzaju problemów, zobacz tutaj:

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

Artykuł zawiera następującą funkcję:

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

ten Funkcja pozwala uruchomić plik wykonywalny w bieżącym oknie konsoli, a także pozwala zbudować tablicę parametrów łańcuchowych, które zostaną do niego przesłane.

Więc w twoim przypadku można skorzystać z tej opcji coś takiego:

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

obsługi tablic, Luke. Jeśli podasz tablicę wartości, PowerShell automatycznie rozszerzy je na osobne parametry. Z mojego doświadczenia wynika, że ​​jest to najbardziej niezawodna metoda. I nie wymaga bałagania z cmdletem Start-Process, co moim zdaniem jest przesadą dla takich zadań.

Ta sztuczka pochodzi z najlepszego artykułu, które widziałem na temat zachowania PowerShell w kierunku zewnętrznych plików wykonywalnych: PowerShell and external commands done right.

Przykład:

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

$CmdLine = @($source, $destination, $fileList) + $robocopyOptions 
& 'robocopy.exe' $CmdLine 
Powiązane problemy