$from = "\\something\1 XLS\2010_04_22\*"
$to = "c:\out\1 XLS\2010_04_22\"
copy-item $from $to -Recurse
これは、c:\out\1 XLS\2010_04_22\
が存在する場合に機能します。 c:\out\1 XLS\2010_04_22\
が存在しない場合は、1つのコマンドで作成できますか?
はい、-Force
パラメーターを追加します。
copy-item $from $to -Recurse -Force
PowerShell 2.0では、コピー先アイテムフォルダーを作成するためにCopy-Itemコマンドレットを取得することはまだできません。次のようなコードが必要です。
$destinationFolder = "C:\My Stuff\Subdir"
if (!(Test-Path -path $destinationFolder)) {New-Item $destinationFolder -Type Directory}
Copy-Item "\\server1\Upgrade.exe" -Destination $destinationFolder
Copy-Itemで-Recurseを使用すると、宛先にソース構造のすべてのサブフォルダーが作成されますが、-Forceを使用しても実際の宛先フォルダーは作成されません。
PowerShell 3以降では、Copy-ItemとNew-Itemを使用します。
copy-item -Path $file -Destination (new-item -type directory -force ("C:\Folder\sub\sub\" + $newSub)) -force -ea 0
バージョン2では試していません。
function Copy-File ([System.String] $sourceFile, [System.String] $destinationFile, [Switch] $overWrite) {
if ($sourceFile -notlike "filesystem::*") {
$sourceFile = "filesystem::$sourceFile"
}
if ($destinationFile -notlike "filesystem::*") {
$destinationFile = "filesystem::$destinationFile"
}
$destinationFolder = $destinationFile.Replace($destinationFile.Split("\")[-1],"")
if (!(Test-Path -path $destinationFolder)) {
New-Item $destinationFolder -Type Directory
}
try {
Copy-Item -Path $sourceFile -Destination $destinationFile -Recurse -Force
Return $true
} catch [System.IO.IOException] {
# If overwrite enabled, then delete the item from the destination, and try again:
if ($overWrite) {
try {
Remove-Item -Path $destinationFile -Recurse -Force
Copy-Item -Path $sourceFile -Destination $destinationFile -Recurse -Force
Return $true
} catch {
Write-Error -Message "[Copy-File] Overwrite error occurred!`n$_" -ErrorAction SilentlyContinue
#$PSCmdlet.WriteError($Global:Error[0])
Return $false
}
} else {
Write-Error -Message "[Copy-File] File already exists!" -ErrorAction SilentlyContinue
#$PSCmdlet.WriteError($Global:Error[0])
Return $false
}
} catch {
Write-Error -Message "[Copy-File] File move failed!`n$_" -ErrorAction SilentlyContinue
#$PSCmdlet.WriteError($Global:Error[0])
Return $false
}
}
$filelist | % {
$file = $_
mkdir -force (Split-Path $dest) | Out-Null
cp $file $dest
}
私のお気に入りは、ロジックの一部を処理する.Net [IO.DirectoryInfo]クラスを使用することです。実際に、これを多くの同様のスクリプトの課題に使用しています。存在しないディレクトリを作成する.Create()メソッドがあり、存在する場合はエラーが発生しません。
これはまだ2段階の問題であるため、foreachエイリアスを使用して単純にします。単一ファイルの場合:
[IO.DirectoryInfo]$to |% {$_.create(); cp $from $_}
複数のファイル/ディレクトリが一致する限り、xcopyではなくRoboCopyを使用します。から「*」を削除し、使用するだけです:
RoboCopy.exe $from $to *
/ r(再帰)、/ e(空を含む再帰)を追加できます。他にも50の便利なスイッチがあります。
編集:これを振り返ってみると簡潔ですが、コードを頻繁に使用していない場合は読みにくいです。通常、次のように2つに分割します。
([IO.DirectoryInfo]$to).Create()
cp $from $to
また、DirectoryInfoはFileInfoのParentプロパティのタイプであるため、 $ toがファイルの場合、それらを一緒に使用できます。
([IO.FileInfo]$to).Parent.Create()
cp $from $to
ここに私のために働いた例があります。テキストファイルには、約100個の異なるフォルダーに含まれる約500個の特定のファイルのリストがあり、それらのファイルが後で必要になった場合に備えて、バックアップ場所にコピーすることになっています。テキストファイルには、完全なパスとファイル名が1行に1つずつ含まれていました。私の場合、各ファイル名からドライブ文字と最初のサブフォルダー名を削除したかった。これらすべてのファイルを、指定した別のルート保存先フォルダーの下の同様のフォルダー構造にコピーしたかったのです。これが他のユーザーにも役立つことを願っています。
# Copy list of files (full path + file name) in a txt file to a new destination, creating folder structure for each file before copy
$rootDestFolder = "F:\DestinationFolderName"
$sourceFiles = Get-Content C:\temp\filelist.txt
foreach($sourceFile in $sourceFiles){
$filesplit = $sourceFile.split("\")
$splitcount = $filesplit.count
# This example strips the drive letter & first folder ( ex: E:\Subfolder\ ) but appends the rest of the path to the rootDestFolder
$destFile = $rootDestFolder + "\" + $($($sourceFile.split("\")[2..$splitcount]) -join "\")
# Output List of source and dest
Write-Host ""
Write-Host "===$sourceFile===" -ForegroundColor Green
Write-Host "+++$destFile+++"
# Create path and file, if they do not already exist
$destPath = Split-Path $destFile
If(!(Test-Path $destPath)) { New-Item $destPath -Type Directory }
If(!(Test-Path $destFile)) { Copy-Item $sourceFile $destFile }
}
私はここで2回つまずきましたが、この最後の時間はユニークな状況でしたが、copy-item
使用したソリューションを投稿したかった。
フルパスのファイルのみのリストがあり、ほとんどの場合、ファイルには拡張子がありません。 -Recurse -Force
オプションが機能しないので、私はcopy-item
機能し、xcopyを使用して以下のようなものにフォールバックしました。最初は私はRobocopyを使用していましたが、ファイル拡張子を探しているようです。私の多くは拡張子がなかったため、ディレクトリと見なしていました。
$filelist = @("C:\Somepath\test\location\here\file","C:\Somepath\test\location\here2\file2")
$filelist | % { echo f | xcopy $_ $($_.Replace("somepath", "somepath_NEW")) }
それが誰かを助けることを願っています。