Copy-Item, не включая файлы подпапок исходного каталога в PowerShell

У меня есть скрипт, который перемещает файлы с определенным расширением из исходного каталога в каталог назначения.

Мой исходный каталог выглядит так:

FILESFOLDER

  • File1.td

  • File2.td

    ПОДПАПКА

    • File3.td

    • File4.td

Мой сценарий короткий и выглядит так:

if(!(Test-Path $SourceDirPath) -or !(Test-Path $DestinationDirPath))
{
    Write-Host "The source- or destination path is incorrect, please check "
    break
}else
{
    Write-Host "Success"
    Copy-Item -path $SourceDirPath -Filter "*$extension" -Destination $DestinationDirPath -Recurse
}

Я должен отметить, что $SourceDirPath исходит из файла конфигурации и работает, только если я объявил его как C:\FILESFOLDER\*

Сценарий работает, но не копирует файлы из подпапки в место назначения. Назначение имеет только File1 и File2.

Что не так с моей командой Copy-Item?

4 ответа

Решение

Так что это сравнит источник каталога с местом назначения, а затем скопирует содержимое. Проигнорируйте мои напуганные переменные, я исправил их ниже на правке

 #Release folder
    $Source =  ""
    #Local folder
    $Destination = ""

    #Find all the objects in the release
    get-childitem $Source -Recurse | foreach {

    $SrcFile = $_.FullName
    $SrcHash = Get-FileHash -Path $SrcFile -Algorithm MD5 # Obtain hash

    $DestFile = $_.Fullname -replace [RegEx]::escape($Source),$Destination #Escape the hash
    Write-Host "comparing $SrcFile to $DestFile" -ForegroundColor Yellow

    if (Test-Path $DestFile) 
    {
    #Check the hash sum of the file copied
    $DestHash = Get-FileHash -Path $DestFile -Algorithm MD5

    #compare them up
    if ($SrcHash.hash -ne $DestHash.hash) {
        Write-Warning "$SrcFile and $DestFile Files don't match!"

        Write-Warning "Copying $SrcFile to $DestFile " 

        Copy-Item $SrcFile -Destination $DestFile -Force
    } 
    else {
        Write-Host "$SrcFile and $DestFile Files Match" -ForegroundColor 
Green

    }
        } 
    else {
        Write-host "$SrcFile is missing! Copying in" -ForegroundColor Red
        Copy-Item $SrcFile -Destination $DestFile -Force

         }
    }  

-RecurseПереключатель не имеет никакого эффекта в вашем случае, потому что он применяется только к элементам, которые соответствуют комбинации $SourceDirPath, который использует трейлинг \* сопоставить элементы в исходном каталоге, и -Filter, которые в вашем случае являются только *.td файлы, расположенные прямо в вашем исходном каталоге.

Опуская трейлинг\* нацеливаться на сам каталог (например, C:\FOLDER скорее, чем C:\FOLDER\*), решает эту проблему в принципе, но из-за досадной причуды работает только так, как задумано, если целевой каталог еще не существует. Если он существует, элементы помещаются в подкаталог целевого каталога, названный по имени исходного каталога.

Если в существующем целевом каталоге нет ничего для сохранения перед копированием (и нет необходимости сохранять специальные атрибуты самого каталога, вы можете обойти эту проблему, предварительно удалив существующий каталог назначения.

if(!(Test-Path $SourceDirPath) -or !(Test-Path $DestinationDirPath))
{
    Write-Host "The source or destination path is incorrect, please check "
    break
}
else
{
    Write-Host "Success"

    # Delete the preexisting destination directory,
    # which is required for the Copy-Item command to work as intended.
    # BE SURE THAT IT IS OK TO DO THIS.
    Remove-Item $DestinationDirPath -Recurse

    # Note: $SourceDirPath must NOT end in \*  
    Copy-Item -Recurse -LiteralPath $SourceDirPath -Filter "*$extension" -Destination $DestinationDirPath
}

Если вам нужно сохранить существующие $DestinationDirPath контент или атрибуты (ACL, ...), требуется больше работы.

Попробуй это:

$source =  "C:\Folder1"

$destination = "C:\Folder2"

$allfiles = Get-ChildItem -Path $source -Recurse -Filter "*$extension"
foreach ($file in $allfiles){
    if (test-path ($file.FullName.replace($source,$destination))) {
    Write-Output "Seccess"
    Copy-Item -path $file.FullName -Destination ($file.FullName.replace($source,$destination))
    }
    else {
    Write-Output "The source- or destination path is incorrect, please check "
    break
    }
}

Вы должны использовать Get-ChildItem командлет с -recurse Параметр для получения всех файлов в зависимости от состояния фильтра. Затем вы можете передать результат в Copy-Item Командлет и только нужно указать место назначения.

Другие вопросы по тегам