Копирование файлов из нескольких (указанных) путей к папкам в другой каталог при сохранении файловой структуры
Я пытаюсь скопировать несколько файлов из одного каталога в другой с помощью PowerShell. Я бы хотел:
- Поддерживать структуру папок / файлов.
- Скопируйте все файлы в определенных папках.
Гипотетическая структура:
Исходная папка \ Пользователь 1 \ Папка 1 \ Файлы \ Папка 2 \ Файлы \ Папка 3 \ Файлы \ Пользователь 2 \ Папка 3 \ Файлы \ Пользователь 3 \ Папка 2 \ Файлы \ Пользователь 4 \ Папка 3 \ Файлы \ Папка 4 \ Файлы
Возможный сценарий:
- Я хочу скопировать файлы, где у пользователей есть папка 1 и папка 2.
Ожидаемый результат:
Папка назначения \ Пользователь 1 \ Папка 1 \Files \ Папка 2 \Files \ Пользователь 3 \ Папка 2 \ Files
Это код, который я до сих пор:
$FolderName = '\\Folder 1\\'
$source = 'C:\CDPTest\Live'
$target = 'C:\CDPTest\DevTest'
$source_regex = [regex]::Escape($source)
(gci $source -Recurse | where {-not ($_.PSIsContainer)} | select -Expand FullName) -match $FolderName |
foreach {
$file_dest = ($_ | Split-Path -Parent) -replace $source_regex, $target
if (-not (Test-Path $file_dest)) {mkdir $file_dest}
}
Как вы можете видеть, совпадение вернет только один путь к файлу на основе текущего кода, и я пытаюсь расширить его, чтобы он соответствовал нескольким именам папок.
Что я пробовал:
- Запуск этого кода с другим именем папки в отдельном файле PowerShell безуспешно.
- Использование массива имен папок для сопоставления.
- С использованием
-and
/-or
операторы для расширения функции соответствия.
2 ответа
Благодаря всем ответам на этот вопрос, вы все помогли указать мне правильное направление. Это решение, которое я выбрал:
#Used for time-stamped logs (requires C:\Root\RobocopyLogs\ to exist)
#$log can be added after '$dest$'
#$dateTime = Get-Date -Format g
#$currentDateTime = get-date -format "MM.dd.yyyy-HH.mm.ss.fff"
#$log = "/log:C:\Root\RobocopyLogs\$currentDateTime.txt"
# Set up variables
$sourceRootDirectory = "C:\Root\Source"
$userDirectories = $sourceRootDirectory+"\*\"
$dest = "C:\Root\Destination"
$excludeExceptions = @("Folder 1",
"Folder 2",
"Folder 3",
"Folder 4",
"Folder 5")
# Get the exclusion list from the source
$excludedFolderArray = (gci $userDirectories -Exclude $excludeExceptions)
$excludedFileArray = $excludedFolderArray |
Where-Object {$_.PSIsContainer -eq $False}
Robocopy $sourceRootDirectory $dest /FFT /MIR /XA:H /R:1 /W:5 /XD $excludedFolderArray /XF $excludedFileArray
У меня возникла проблема при синхронизации с robocopy, где, если файл был помещен в корневую папку, он был бы скопирован. Пришлось создать отдельный список файлов, которые нужно исключить из корня.
Хотя Robocopy все еще может быть лучшим подходом,
этот сценарий определяет папки для копирования в первую очередь (с помощью или |
RegEx), а затем создает папку назначения и создает ее при необходимости. (Непроверенные)
$FolderName = [regex]('\\Folder 1$|\\Folder 2$')
$source = 'C:\CDPTest\Live'
$target = 'C:\CDPTest\DevTest'
Get-ChildItem $source -Recurse |
Where-Object {$_.PSIsContainer -and $_.FullName -match $FolderName} |
Foreach-Object {
$targetFolder = Join-Path $target ($_.FullName -replace [RegEx]::escape($source),'')
if (!(Test-Path $targetFolder)) {mkdir $targetFolder|Out-Null}
Copy-Item -Path $_ -Filter * -Destination $targetFolder
}