- Создание в Powershell директорий и файлов с New-Item их перенос и копирование
- Создание файлов
- Создание со вложенными директориями
- Перезапись
- Запись данных
- Мягкие и жесткие ссылки
- Создание множества файлов и директорий
- Копирование и перемещение папок и файлов
- Использование масок для копирования и перемещения
- Дополнительные параметры фильтрации
- Переименование файлов и директорий
- Удаление
- Работа с сетевыми папками и SMB
- Выполнение команд под другим пользователем
- Copy-Item копирование файлов и папок из PowerShell
- Копирование файлов и каталогов
- Копирование с заменой и копирование с заменой read-only файлов
- Копирование с фильтрацией по шаблону
- Исключение файлов при копировании
- Копирование файлов на удаленный компьютер по сети
- Ключ PassThru
- Ключ Verbose
- Несколько полезных скриптов с Copy-Item
Создание в Powershell директорий и файлов с New-Item их перенос и копирование
Для работы с файлами в Powershell есть около 10 команд. С помощью команды New-Item можно создать файл или папку в Powershell, жесткую и мягкую ссылку. Copy-Item и Move-Item выполняют копирование и перемещение объектов. В этой стать мы рассмотрим все эти операции, а так же удаление директорий и файлов включая сетевые пути, на примерах.
Навигация по посту
Создание файлов
В следующем примере мы создадим файл с расширением ‘.txt’:
По умолчанию файл создается в той директории откуда был запущен сам Powershell. Изменить путь создания файла можно указав путь в Path:
Каждая папка так же является файлом, но для ее создания в Powershell нужно указывать тип ‘Directory’ в ‘ItemType’:
Создание со вложенными директориями
Мы можем создать множество папок не указывая дополнительных параметров:
Если мы захотим создать директорию и файл, то получим ошибку:
- New-Item : Could not find a part of the path
Исправить эту ошибку можно указав параметр Force, который создаст весь путь целиком:
Перезапись
Ключ Force не только создает родительские объекты в виде папок, но и перезаписывает файлы. Если не указан параметр Force, а файл или папка уже существует — вы получите ошибки:
- New-Item : The file ‘C:\Dir1\Dir2\Dir3\file.txt’ already exists.
- New-Item : An item with the specified name C:\Dir1\Dir2\Dir3\ already exists.
Указывая Force — файлы перезаписываются удаляя все содержимое. В случае с папками ничего удалено не будет.
Запись данных
Еще один из способа перезаписи файлов в Powershell — использование символа перенаправления вывода ‘>’. Если объект уже существует — он будет перезаписан, иначе будет создан новый файл:
Почти такой же результат будет если добавить в команду параметр Value. Результат следующего примера будет аналогичен предыдущему:
Мягкие и жесткие ссылки
Кроме файлов и директорий в ItemType можно указать следующие типы ссылок:
- SymbolicLink (мягкая ссылка) — обычный ярлык на папку или директорию;
- Junction — старый тип ссылок (до Windows Vista);
- HardLink (жесткая ссылка) — ссылка на объект в файловой системе. Не работает с директориями.
Каждый файл можно представить как ссылку на объект файловой системы. Ярлык устанавливает связь с именем файла (ссылка на ссылку). При переименовании оригинального файла или его удалении ярлык перестает работать.
Жесткая ссылка работает иначе. Она ссылается на объект файловой системы, а не на имя. Поэтому при удалении или переименовании оригинального файла эта связь не потеряется. Такие ссылки можно представить как копии оригинальных фалов, но которые не занимают дополнительное место на диске. Жесткие ссылки работают в рамках одного раздела и их нельзя использовать на каталогах. Сам объект файловой системы (файл) будет существовать до последней такой ссылки.
В следующем примере я создаю жесткую ссылку, где ‘old_file.txt’ — имя существующего файла, а ‘new_link.txt’ — имя нового:
Создание множества файлов и директорий
Параметр Path может принимать несколько значений. Это значит, что одной командой мы можем создать несколько объектов:
Можно использовать сочетания директорий и файлов, добавляя ключ Force тем самым избегая ошибок.
Открываем файл и читаем его содержимое с Get-Content в Powershell
Копирование и перемещение папок и файлов
В следующем примере, с помощью Powershell, будет скопирован файл ‘C:\data.txt’ в директорию ‘C:\Catalog\’:
Перемещение объектов выполняется так же, но с использованием Move-Item:
Если в перемещаемой папке уже существует файл с этим именем, то мы получим ошибку:
- Move-Item : Cannot create a file when that file already exists
Для исправления этой ситуации можно использовать параметр Force или перемещать файл под другим именем. Новое имя можно указать в Destination:
Каталоги переносятся и копируются так же. Знак ‘\’ в конце Destination говорит, что мы хотим перенести папку внутрь указанной. Отсутствие знака ‘\’ говорит, что это новое имя директории:
Path — принимает список, а это значит, что мы можем указывать несколько значений через запятую.
Использование масок для копирования и перемещения
Во многих командах Powershell доступны следующие специальные символы:
- * — говорит, что в этом месте есть неизвестное количество неизвестных символов;
- ? — в этом месте есть один неизвестный символ;
- [A,B,C] — в этом месте есть одна из следующих букв A,B,C.
Например так мы скопируем все объекты с расширением ‘txt’ из одной папки в другую:
Перемещение сработает так же.
Предыдущий вариант сработает, если мы ищем файлы в текущей директории. Для копирования в Powershell внутри всех вложенных каталогов нужно использовать рекурсивный поиск, который доступен только в Copy-Item. Рекурсивный поиск устанавливается ключом Recurse. В следующем примере будет найден и скопирован файл hosts. В качестве * я указал один из элементов неизвестного пути:
Дополнительные параметры фильтрации
Если предыдущих примеров, где мы находили файлы с неизвестным название, не достаточно, то можно использовать дополнительные параметры. Они доступны в обеих командах Copy-Item и Move-Item:
- Include — включает объекты с этим упоминанием;
- Exclude — работает аналогично предыдущему, но исключает объекты;
- Filter — включает объекты указанные в этом параметре.
Я не вижу смысла использовать все параметры описанные выше в одной команде, но в них есть отличия. Filter будет работать быстрее, так как он работает и фильтрует данные в момент их получения. Include и Exclude сработают после получения всех файлов, но каждое значение для них можно указывать через запятую. Для Include и Exclude так же важно указывать Path с ‘*’ в конце, например ‘C:\dir\*’.
Например мы хотим скопировать все объекты с расширением ‘txt’ и ‘jpg’. Это можно сделать так:
Я бы не рекомендовал использовать Filter в обеих командах. Более удобный способ — это искать файлы с Get-ChildItem, а затем их копировать и перемещать в нужное место. В следующем примере будут перенесены все объекты формата ‘.txt’ и ‘.jpg’ в каталог Directory:
Создание и изменение в Powershell NTFS разрешений ACL
Переименование файлов и директорий
Для переименовывания в Powershell используется Rename-Item. В следующем примере мы укажем новое имя в параметре NewName:
В NewName можно указать путь, но он должен соответствовать источнику. При следующем написании будет ошибка:
- Rename-Item : Cannot rename the specified target, because it represents a path or device name.
Для массового переименовывания объектов можно использовать конвейер с ‘Get-ChildItem’. Например нам нужно поменять расширения файлов с ».jpg» на «.png» — это можно сделать так:
Удаление
В следующем примере мы удалим файл:
Пустые каталоги в Powershell удаляются так же. Если в папке находятся другие файлы будет запрошено разрешение на удаление.
Избежать таких вопросов можно использовав рекурсию в виде параметра Recurse:
Если нужно удалить все файлы внутри каталога, то нужно добавить знак ‘*’. Если внутри каталога будут находится другие папки с файлами, то запросится подтверждение:
У команды есть параметры, описанные ранее, в виде:
Работа с сетевыми папками и SMB
Для копирования и переноса данных по сети нужно использовать следующий формат:
Он сработает со всеми командами, как для источника так и для назначения:
Выполнение команд под другим пользователем
Любая команда выполняется от имени пользователя, который открыл консоль Powershell. Хоть в командах и присутствует параметр ‘Credential’, но при его использовании вы будете получать ошибку:
- The FileSystem provider supports credentials only on the New-PSDrive cmdlet. Perform the operation again without specifying credentials.
Есть несколько способов обойти эти ограничения использовав методы WMI и CIM. В Powershell так же доступен сервис PSRemoting, который создан для выполнения задач удаленно. Мы можем использовать две команды:
- New-PSItem — подключение к компьютеру и дальнейшая работы с ним;
- Invoke-Command — одноразовое выполнение команды.
Этот сервис может не работать по умолчанию и нуждаться в дополнительных настройках. Этот процесс был описан в другой статье.
В следующем примере будет объявлена переменная в которой будет храниться логин и пароль нужной учетной записи:
После заполнения этой переменной нужно будет передать ее в параметр Credential. Примеры по работе с файлами удаленно от другого пользователя:
Copy-Item копирование файлов и папок из PowerShell
PowerShell командлет Copy-Item используется для копирования файлов между локальными, сетевыми каталогами или между компьютерами по сети через WinRM. Командлет Copy-Item предоставляет большое количество опций, которые можно использовать в разных сценариях копирования файлов и каталогов (по своим возможностям этот командлет почти не уступает утилите robocopy). Например:
- перезапись файлов (override)
- фильтрация по имени/шаблону
- исключение по имени/шаблону
- Verbose режим
- Копирование файлов с/на удаленные компьютеры
Начнем с простых примеров использования Copy-Item и будем переходить к более сложным.
Копирование файлов и каталогов
Чтобы скопировать один файл 1.txt из каталога C:\SourceFolder\ в F:\DestFolder\, выполните:
Copy-Item -Path «C:\SourceFolder\1.txt» -Destination «F:\DestFolder\1.txt»
Можно использовать сокращенный синтаксис командлета, пропустив указание параметров Path и Destination:
cpi «C:\SourceFolder\1.txt» «F:\DestFolder\1.txt»
Теперь скопируем каталог C:\SourceFolder\folder в F:\DestFolder\folder. В папке folder находится файл 1.txt. Обратите внимание что без ключа –Recurse, папка folder копируется без содержимого:
Copy-Item -Path «C:\SourceFolder\folder» -Destination «F:\DestFolder\folder» -Recurse
С помощью Copy-Item также можно просто объединить файлы из несколько директорий в одну (слияние директории), для этого нужно перечислить директории в ключе –Path:
Copy-Item -Path «C:\SourceFolder\*», «C:\SourceFolder2\*», «C:\SourceFolder3\*» -Destination «F:\DestFolder\»
Копирование с заменой и копирование с заменой read-only файлов
Copy-Item по умолчанию при копировании заменяет файлы в целевом каталоге. Никаких дополнительных параметров указывать не нужно. При копировании каталога, если нужно заменить каталог в целевой папке, нужно использовать ключ –Force, иначе будет ошибка “Элемент folder с указанным именем уже существует — DirectoryExists”.
Для перезаписи файла с атрибутом read-only, нужно использовать ключ -Force. Если его не использовать, вы получите ошибку “отказано в доступе по пути… CopyFileInfoItemUnauthorizedAccessError”.
Чтобы скопировать файл с перезаписью файла с read-only атрибутом используйте параметр Force.
Copy-Item -Path «C:\SourceFolder\1.txt» -Destination «F:\DestFolder\1.txt» -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
Для примера возьмём такую структуру файлов:
Выполним копирование командой:
Copy-Item -Path «C:\SourceFolder\fol*» -Destination «F:\DestFolder\»
Результат в F:\DestFolder\
Теперь чистим папку назначения и выполняем:
Copy-Item -Path «C:\SourceFolder\folder2» -Destination «F:\DestFolder\»
Папка без цифры в окончании не скопировалась, потому что folder3 подразумевает что после 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\.
Test-WSMan -ComputerName testnode1
Если WSMan не настроен, вы можете выполнить его быструю конфигурацию. Для этого откройте командную строку с правами администратора и выполните winrm quickconfig
Также можно копировать и через обычные сетевые SMB шары, для этого просто используйте UNC формат сетевого пути.
Copy-Item -Path «C:\SourceFolder\*» -Destination «\\testnode1\C$\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 «\\testnode1\C$\copy_tutorial\» -PassThru
Переменная $items будет содержать список скопированных файлов, с которым вы можете работать дальше.Это значит что вы можете напрямую работать с этими файлами. Например выполнив команду Remove-Item $items[0] , вы удалите директорию folder.
Ключ Verbose
При использовании ключа -Verbose вы получите подробный лог операций копирования. Например, вывод команды
Copy-Item -Path «C:\SourceFolder\*.txt» -Destination «F:\DestFolder\» -Recurse -Force -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 также является мощным инструментом для написания скриптов.