Copy-Item копирование файлов и папок из PowerShell

Copy-Item копирование файлов и папок из PowerShell

PowerShell командлет Copy-Item используется для копирования файлов между локальными, сетевыми каталогами или между компьютерами по сети через WinRM. Командлет Copy-Item предоставляет большое количество опций, которые можно использовать в разных сценариях копирования файлов и каталогов (по своим возможностям этот командлет почти не уступает утилите robocopy). Например:

  • перезапись файлов (override)
  • фильтрация по имени/шаблону
  • исключение по имени/шаблону
  • Verbose режим
  • Копирование файлов с/на удаленные компьютеры

Начнем с простых примеров использования Copy-Item и будем переходить к более сложным.

Копирование файлов и каталогов

Чтобы скопировать один файл 1.txt из каталога C:SourceFolder в F:DestFolder, выполните:

Copy-Item -Path "C:SourceFolder1.txt" -Destination "F:DestFolder1.txt"

Можно использовать сокращенный синтаксис командлета, пропустив указание параметров Path и Destination:

cpi "C:SourceFolder1.txt" "F:DestFolder1.txt"

Теперь скопируем каталог C:SourceFolderfolder в F:DestFolderfolder. В папке folder находится файл 1.txt. Обратите внимание что без ключа –Recurse, папка folder копируется без содержимого:

Copy-Item -Path "C:SourceFolderfolder" -Destination "F:DestFolderfolder" -Recurse

С помощью Copy-Item также можно просто объединить файлы из несколько директорий в одну (слияние директории), для этого нужно перечислить директории в ключе –Path:

Copy-Item -Path "C:SourceFolder*", "C:SourceFolder2*", "C:SourceFolder3*" -Destination "F:DestFolder"

Копирование с заменой и копирование с заменой read-only файлов

Copy-Item по умолчанию при копировании заменяет файлы в целевом каталоге. Никаких дополнительных параметров указывать не нужно. При копировании каталога, если нужно заменить каталог в целевой папке, нужно использовать ключ –Force, иначе будет ошибка “Элемент folder с указанным именем уже существует — DirectoryExists”.

copy-item DirectoryExists

Для перезаписи файла с атрибутом read-only, нужно использовать ключ -Force. Если его не использовать, вы получите ошибку “отказано в доступе по пути… CopyFileInfoItemUnauthorizedAccessError”.

copy-item CopyFileInfoItemUnauthorizedAccessError

Чтобы скопировать файл с перезаписью файла с read-only атрибутом используйте параметр Force.

Copy-Item -Path "C:SourceFolder1.txt" -Destination "F:DestFolder1.txt" -Force

Совет. Чтобы не путаться, ключ –Force можно рассматривать как ключ для копирования с заменой.

Чтобы Copy-Item скопировал файлы из одной папки в другую без замены существующих файлов, можно использовать этот простой скрипт

Copy-Item (Join-Path "C:SourceFolder" "*") "F:DestFolder" -Exclude (Get-ChildItem "F:DestFolder") -Recurse

Этот скрипт скопирует все файлы и папки из C:SourceFolder в F:DestFolder без замены файлов уже существующих в F:DestFolder

Копирование с фильтрацией по шаблону

С помощью Copy-Item можно скопировать файлы/директории выбранные с помощью wildcard символа * или с помощью символа ?. Также поддерживаются некоторые регулярные выражения

  • * — обозначает любое количество любых символов
  • ? – обозначает 1 любой символ
  • [a-z], [0-9] – символы между a-z и цифры между 0 и 9

Для примера возьмём такую структуру файлов:

source

Выполним копирование командой:

Copy-Item -Path "C:SourceFolderfol*" -Destination "F:DestFolder"

Результат в F:DestFolder

copy-item replace

Теперь чистим папку назначения и выполняем:

Copy-Item -Path "C:SourceFolderfolder[0-3]" -Destination "F:DestFolder"

Результат:

result

Папка без цифры в окончании не скопировалась, потому что folder[0-3] подразумевает что после folder будет как минимум еще 1 символ между 0 и 3

Исключение файлов при копировании

С помощью ключа –Exclude можно исключить файлы при копировании. Например, следующай команда скопирует все файлы кроме файлов с расширением txt.

Copy-Item -Path "C:SourceFolder*" -Destination "F:DestFolder" -Recurse -Force -Exclude "*.txt"

Аналогичным же образом можно применить ключ –Include, например

Copy-Item -Path "C:SourceFolder*" -Destination "F:DestFolder" -Recurse -Force -Include "*.txt"

Скопирует только txt файлы. Хотя для простоты гораздо удобнее использовать при копировании вид
-Path "C:SourceFolder*.txt"
.

Копирование файлов на удаленный компьютер по сети

Copy-File может копировать не только по SMB протоколу, но и через WinRM (WSMan).

Создайте новую сессию с компьютером testnode1 и выполните копирование в её контексте:

$session = New-PSSession -ComputerName testnode1
Copy-Item -Path "C:SourceFolder*" -ToSession $session -Destination "C:SourceFolder" -Recurse -Force

Эта команда скопирует файлы с локального компьютера из директории C:SourceFolder на компьютер testnode1 в C:SourceFolder.

Примечание. Доступность WSMan на удаленном компьютере можно проверить с помощью командлета Test-WSMan.

Test-WSMan -ComputerName testnode1

Test-WSMan

Если WSMan не настроен, вы можете выполнить его быструю конфигурацию. Для этого откройте командную строку с правами администратора и выполните
winrm quickconfig

winrm quickconfig

Также можно копировать и через обычные сетевые SMB шары, для этого просто используйте UNC формат сетевого пути.

Copy-Item -Path "C:SourceFolder*" -Destination "testnode1C$copy_tutorial"

Можно скопировать файл с удаленного компьютера. Принцип такой же, как и при копировании файлов на удаленный компьютер, за исключением параметра –ToSession, вместо него нужно использовать –FromSession:

$session = New-PSSession -ComputerName testnode1
Copy-Item -FromSession $session -Path "C:SourceFolder*" -Destination "F:DestFolder" -Recurse -Force

Эта команда скопирует содержимое папки C:SourceFolder с компьютера testnode1 на локальный компьютер в директорию F:DestFolder

Ключ PassThru

Командлет Copy-Item (как и многие другие командлеты PowerShell) не возвращает результатов в консоль. Параметр PassThru применяется скриптах, или для лог-файлов, когда нужно получить список скопированных файлов и работать с ним дальше. Рассмотрим пример

$items = Copy-Item -Path "C:SourceFolder*" –Destination "testnode1C$copy_tutorial" -PassThru

Переменная
$items
будет содержать список скопированных файлов, с которым вы можете работать дальше.Это значит что вы можете напрямую работать с этими файлами. Например выполнив команду
Remove-Item $items[0]
, вы удалите директорию folder.

copy-item passthru

Ключ Verbose

При использовании ключа -Verbose вы получите подробный лог операций копирования. Например, вывод команды

Copy-Item -Path "C:SourceFolder*.txt" -Destination "F:DestFolder" -Recurse -Force -Verbose

copy-item verbose лог

Несколько полезных скриптов с Copy-Item

Скопировать только файлы:

Get-ChildItem "C:SourceFolder" -File -Recurse | Copy-Item -Destination "F:DestFolder"

Скопировать структуру папок, без файлов:

$path = Get-ChildItem "C:SourceFolder" -Recurse | ?{$_.PsIsContainer -eq $true}
$dest = "F:DestFolder"
$parent = $path[0].Parent.Name
$path | foreach {
$_.FullName -match "$parent.+"
New-Item -ItemType directory ($dest + $Matches[0])
}

Copy-Item очень простой и удобный в использовании командлет PowerShell для выполнения операций копирования и перемещения файлов. В сочетании с другими инструментами PowerShell, Copy-Item также является мощным инструментом для написания скриптов.

Qiziqarli malumotlar
Copy-Item копирование файлов и папок из PowerShell