web-dev-qa-db-ja.com

存在しない場合にフォルダを作成するPowershell 2のコピーアイテム

$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つのコマンドで作成できますか?

58
MicMit

はい、-Forceパラメーターを追加します。

copy-item $from $to -Recurse -Force
72
Shay Levy

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を使用しても実際の宛先フォルダーは作成されません。

97
FrinkTheBrave

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では試していません。

12
mjudd
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
    } 
}
3
Bart
  $filelist | % {
    $file = $_
    mkdir -force (Split-Path $dest) | Out-Null
    cp $file $dest
  } 
3
majkinetor

私のお気に入りは、ロジックの一部を処理する.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

また、DirectoryInfoFileInfoのParentプロパティのタイプであるため、 $ toがファイルの場合、それらを一緒に使用できます。

([IO.FileInfo]$to).Parent.Create()
cp $from $to
2

ここに私のために働いた例があります。テキストファイルには、約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
Toby Bierly

私はここで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")) }

それが誰かを助けることを願っています。

1
ssaviers