Powershell内でrobocopyを使用して、ホームマシンの一部のディレクトリをミラーリングしようとしています。これが私のスクリプトです:
param ($configFile)
$config = Import-Csv $configFile
$what = "/COPYALL /B /SEC/ /MIR"
$options = "/R:0 /W:0 /NFL /NDL"
$logDir = "C:\Backup\"
foreach ($line in $config)
{
$source = $($line.SourceFolder)
$dest = $($line.DestFolder)
$logfile = $logDIr
$logfile += Split-Path $dest -Leaf
$logfile += ".log"
robocopy "$source $dest $what $options /LOG:MyLogfile.txt"
}
スクリプトは、ソースディレクトリと宛先ディレクトリのリストを含むcsvファイルを受け取ります。スクリプトを実行すると、次のエラーが発生します。
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : Sat Apr 03 21:26:57 2010
Source : P:\ C:\Backup\Photos \COPYALL \B \SEC\ \MIR \R:0 \W:0 \NFL \NDL \LOG:MyLogfile.txt\
Dest -
Files : *.*
Options : *.* /COPY:DAT /R:1000000 /W:30
------------------------------------------------------------------------------
ERROR : No Destination Directory Specified.
Simple Usage :: ROBOCOPY source destination /MIR
source :: Source Directory (drive:\path or \\server\share\path).
destination :: Destination Dir (drive:\path or \\server\share\path).
/MIR :: Mirror a complete directory tree.
For more usage information run ROBOCOPY /?
**** /MIR can DELETE files as well as copy them !
修正するために何をする必要があるか?
ありがとう、マーク。
$what
および$options
の変数が変更されない場合、なぜそれらは変数なのですか?
$what = "/COPYALL /B /SEC /MIR"
$options = "/R:0 /W:0 /NFL /NDL"
これは私にとってはうまくいきます:
robocopy $source $dest /COPYALL /B /SEC /MIR /R:0 /W:0 /NFL /NDL
Powershell内から外部コマンドのパラメーターに文字列を設定するには、変数展開を使用できるようにしたい場合や、結果として得られるコマンドラインで、分離するパラメーターと分離しないパラメーターを適切に理解する場合に、多少のフープジャンプが必要です。あなたの例では、最初のパラメータとして文字列全体を送信しており、Robocopyはソースディレクトリとしてその長い文字列を見つけることができないことを通知しています。 Destinationの場合と同様に、Source文字列全体を1つのパラメーター(そこに含まれる可能性のあるスペースを含む)として処理する必要がありますが、$ whatと$ optionsは両方ともRobocopyに配信できないため、失敗します。解析された。
これを正しく行うにはいくつかの方法がありますが、次のスニペットは、パラメーターを分割する方法に基づいており、私が使用した1つのディレクトリの例で機能します。
$source="C:\temp\source"
$dest="C:\temp\dest"
$what = @("/COPYALL","/B","/SEC","/MIR")
$options = @("/R:0","/W:0","/NFL","/NDL")
$cmdArgs = @("$source","$dest",$what,$options)
robocopy @cmdArgs
同じ問題がありました。コマンドライン全体が最初の引数として解釈されました。
上記の何も機能しませんでした:
invoke-expression "robocopy ""$sourceFolder"" ""$destinationFolder"" /MIR"
invoke-expression "robocopy \`"$sourceFolder\`" \`"$destinationFolder\`" /MIR"
パスにスペースがある場合、引用符を省略しても機能しません。
invoke-expression "robocopy $sourceFolder $destinationFolder /MIR"
http://edgylogic.com/blog/powershell-and-external-commands-done-right/ のトリックを試した後、ようやく手に入れました。
robocopy "\`"$sourceFolder"\`" "\`"$destinationFolder"\`" /MIR
たぶん私はバットファイルにこだわっていたはずです。 :)
Robocopy行から引用符を削除しますか?
つまり.
param ($configFile)
$config = Import-Csv $configFile
$what = "/COPYALL /B /SEC/ /MIR"
$options = "/R:0 /W:0 /NFL /NDL"
$logDir = "C:\Backup\"
foreach ($line in $config)
{
$source = $($line.SourceFolder)
$dest = $($line.DestFolder)
$logfile = $logDIr
$logfile += Split-Path $dest -Leaf
$logfile += ".log"
robocopy $source $dest $what $options /LOG:MyLogfile.txt
}
ネイティブコマンドを実行する最良の方法は、&コマンドを使用して文字列のリストを実行することです。また、コンソール出力をPowerShellトランスクリプトに含める場合は、出力をout-Hostにパイプする必要があります。以下は、私が書いた 7-Zip to Amazon S3 Powershell Script から取得した複数のパラメーターを使用して7Zipを呼び出す例です。
$7ZipPath = "C:\Program Files\7-Zip\7z.exe" #Path to 7Zip executable
$FolderPath = "C:\Backup" #Folder to backup (no trailing slash!)
$FolderName = $FolderPath.Substring($FolderPath.LastIndexOf("\")+1) #grab the name of the backup folder
$TimeStamp = [datetime]::Now.ToString("yyyy-MM-dd_HHmm") #Create unique timestamp string
$strFile = [String]::Format("{0}\{1}_{2}.7z", "c:\",$FolderName,$TimeStamp) #Create filename for the Zip
#7z options: add, type 7z, Archive filename, Files to add (with wildcard. Change \* to \prefix* or \*.txt to limit files), compression level 9, password, encrypt filenames, Send output to Host so it can be logged.
& $7ZipPath "a" "-t7z" "$strFile" "$FolderPath\*" "-mx9" "-r" "-pPASSWORD" "-mhe" | out-Host #create archive file
if($LASTEXITCODE -ne 0){ #Detect errors from 7Zip. Note: 7z will crash sometimes if file already exists
Write-Error "ERROR: 7Zip terminated with exit code $LASTEXITCODE. Script halted."
exit $LASTEXITCODE
}
基本的にあなたの場合のために私はこのようなことを試みます($ whatと$ optionsパラメータを個別に分割する必要があるかもしれません):
$robocopypath = "c:\pathtofolder\robocopy.exe"
& $robocopypath "$source" "$dest" "$what" "$options" "/LOG:MyLogfile.txt"
これは私にとってはうまくいき、ログファイルの場所を動的に入力することができます。 &記号は、テキストが実行したいコード行であることをPowerShellに通知するだけです。
$source = "E:\BackupToRestore\"
$destination = "E:\RestoreMe\"
$logfile = "E:\robocopyLogFile.txt"
$switches = ("/B", "/MIR", "/XJ", "/FFT", "/R:0", "/LOG:$logfile")
& robocopy $source $destination $roboCopyString $switches
誰かに役立つかもしれないので、これに私の2セントを追加します...以下のコードには、コピーするファイルを取得するためにcsvを読み取る「ループ」部分がありません
# first we setup an array of possible robocopy status
$RobocopyErrors="NO ERRORS",
"OKCOPY",
"XTRA",
"OKCOPY + XTRA",
"MISMATCHES",
"OKCOPY + MISMATCHES",
"MISMATCHES + XTRA",
"OKCOPY + MISMATCHES + XTRA",
"FAIL",
"OKCOPY + FAIL",
"FAIL + XTRA",
"OKCOPY + FAIL + XTRA",
"FAIL + MISMATCHES& goto end",
"OKCOPY + FAIL + MISMATCHES",
"FAIL + MISMATCHES + XTRA",
"OKCOPY + FAIL + MISMATCHES + XTRA",
"***FATAL ERROR***"
#setting some variables with the date
$DateLogFile=get-date -format "yyyyddMMhh"
#this commands below one usually goes into a loop
$DateLog=get-date -format "yyyyddMMhhmmss"
#adding options and command arg as described in previous post
$options = @("/R:0","/W:0")
$cmdArgs = @("$Source","$Destination",$File,$options)
#executing Robocopy command
robocopy @cmdArgs
# We capture the lastexitcode of the command and use to confirm if all was good or not
$errorlevel=$LASTEXITCODE
# I output the status to a log file
"$DateLog`t::$($RobocopyErrors[$errorlevel])::`"$file`"`t`"$Source`" -> `"$Destination`"" | out-file "$scriptPath\Logs\$DateLogFile.log" -append
if ($errorlevel -lt 8) {
#error below 8 = all is good
}
else {
# something bad happened ..
}
invoke-expression "robocopy $source $dest $what $options /LOG:MyLogfile.txt"
これにより、すべての変数が補間され、結果の文字列が呼び出されます。現在の方法では、robocopyはすべてのオプションを引用符で囲んで呼び出されているようです。つまり、robocopy "c:\ src c:\ dst blah meh"です。これは単一のパラメーターとして解釈されます。