2015-04-10 16 views
6

Sto cercando di scrivere uno script che utilizza robocopy Se fossi solo facendo questa operazione manualmente, il mio ordine sarebbe:?.

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

MA, quando faccio questo da PowerShell, come:

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

robocopy $source $destination $fileLIst $robocopyOptions 

ottengo:

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

Tuttavia, se cambio il comando robocopy per

robocopy $source $destination $fileLIst /NJH /NJS 

tutto viene eseguito correttamente.

Quindi, la mia domanda è: come faccio a passare una stringa come le mie opzioni di comando robocopy (e, in un senso più ampio, fare lo stesso per qualsiasi comando esterno)

risposta

9

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

+0

ringraziamento, Anton. – weloytty

+0

'Start-Process' è OK se non ti interessa la finestra della console separata. –

+1

usa gli argomenti '-NoNewWindow -PassThru -Wait' per evitare la finestra della console separata –

4

non è possibile utilizzare una stringa per passare le opzioni in questo modo perché quando si scrive

robocopy $source $destination $fileList $robocopyOptions 

PowerShell valuterà l'ultima variabile ($robocopyOptions) come una singola stringa e lo citerà. Ciò significa che robocopy riceverà "/NJH /NHS" (stringa singola, quotata) sulla sua riga di comando. (. Ovviamente non l'intento)

Per i dettagli su come risolvere questi tipi di problemi, vedere qui:

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

L'articolo include le seguenti funzioni:

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

Questo la funzione ti consente di eseguire un eseguibile nella finestra della console corrente e ti consente anche di creare una serie di parametri di stringa da passare ad essa.

Quindi nel tuo caso è possibile utilizzare questa funzione di qualcosa di simile:

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

utilizzare le matrici, Luke. Se si specifica una matrice di valori, PowerShell li espanderà automaticamente in parametri separati. Nella mia esperienza, questo è il metodo più affidabile. E non richiede di incasinare con il cmdlet Start-Process, che a mio parere è eccessivo per tali attività.

Questo trucco deriva dal miglior articolo che ho visto sul comportamento di PowerShell verso gli eseguibili esterni: PowerShell and external commands done right.

Esempio:

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

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