Powershell 2 copy-элемент, который создает папку, если она не существует


$from = "\something XLS10_04_22\*"
$to =  "c:\out XLS10_04_22\"
copy-item $from $to -Recurse 

это работает, если c:\out\1 XLS\2010_04_22\ существует . Возможно ли с помощью одной команды создать "c:\out\1 XLS\2010_04_22\" если он не существует.

7   51   2010-04-23 04:50:08

7 ответов:

Да, добавить

в 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

Если вы используете -Recurse в Copy-Item, он создаст все подпапки исходной структуры в месте назначения, но он не создаст фактическую папку назначения, даже с-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.

мой любимый, чтобы использовать .Net [IO.DirectoryInfo] класс,который заботится о некоторой логике. Я на самом деле использую это для многих подобных задач сценариев. У него есть .Create () метод, который создает каталоги, которые не существуют, без ошибок, если они есть.

поскольку это все еще двухэтапная проблема, я использую псевдоним foreach, чтобы сохранить его простым. Для отдельных файлов:

[IO.DirectoryInfo]$to |% {$_.create(); cp $from $_}

что касается вашего соответствия нескольких файлов/каталогов, я бы использовал RoboCopy над xcopy. Удалять "*"от вашего ОТ и просто использовать:

RoboCopy.exe $from $to *

вы все еще можете добавить /r (Recurse), /e (Recurse включая пустой), и есть 50 других полезных переключателей.

Edit: оглядываясь назад, это кратко, но не очень читаемо, если вы не используете код часто. Обычно я его разделяю на два, вот так:

([IO.DirectoryInfo]$to).Create()
cp $from $to

и DirectoryInfo - это тип родительского свойства FileInfo, так что если ваш $to файл, вы можете использовать их вместе:

([IO.FileInfo]$to).Parent.Create()
cp $from $to
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
  } 

Я споткнулся здесь дважды, и в этот последний раз была уникальная ситуация, и хотя я канаву с помощью 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")) }

надеюсь, что это поможет кому-то.