Для работы с файлами в Powershell есть около 10 команд. С помощью команды New-Item можно создать файл или папку в Powershell, жесткую и мягкую ссылку. Copy-Item и Move-Item выполняют копирование и перемещение объектов. В этой стать мы рассмотрим все эти операции, а так же удаление директорий и файлов включая сетевые пути, на примерах.
Создание файлов
В следующем примере мы создадим файл с расширением '.txt':
New-Item file.txt
По умолчанию файл создается в той директории откуда был запущен сам Powershell. Изменить путь создания файла можно указав путь в Path:
New-Item -Path 'C:\file.txt'
Каждая папка так же является файлом, но для ее создания в Powershell нужно указывать тип 'Directory' в 'ItemType':
New-Item -Path 'C:\Dir\' -ItemType Directory
Создание со вложенными директориями
Мы можем создать множество папок не указывая дополнительных параметров:
New-Item -Path 'C:\Dir1\Dir2\Dir3\' -ItemType Directory
Если мы захотим создать директорию и файл, то получим ошибку:
New-Item -Path 'C:\Dir1\Dir2\Dir3\file.txt'
- New-Item : Could not find a part of the path
Исправить эту ошибку можно указав параметр Force, который создаст весь путь целиком:
New-Item -Path 'C:\Dir1\Dir2\Dir3\file.txt' -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 - файлы перезаписываются удаляя все содержимое. В случае с папками ничего удалено не будет.
New-Item -Path 'C:\Dir1\Dir2\Dir3\file.txt' -Force
Запись данных
Еще один из способа перезаписи файлов в Powershell - использование символа перенаправления вывода '>'. Если объект уже существует - он будет перезаписан, иначе будет создан новый файл:
'test' > file.txt
Get-Content .\file.txt
Почти такой же результат будет если добавить в команду параметр Value. Результат следующего примера будет аналогичен предыдущему:
New-Item -Path 'C:\file.txt' -Value 'test'
Get-Content 'C:\file.txt'
Мягкие и жесткие ссылки
Кроме файлов и директорий в ItemType можно указать следующие типы ссылок:
- SymbolicLink (мягкая ссылка) - обычный ярлык на папку или директорию;
- Junction - старый тип ссылок (до Windows Vista);
- HardLink (жесткая ссылка) - ссылка на объект в файловой системе. Не работает с директориями.
Каждый файл можно представить как ссылку на объект файловой системы. Ярлык устанавливает связь с именем файла (ссылка на ссылку). При переименовании оригинального файла или его удалении ярлык перестает работать.
Жесткая ссылка работает иначе. Она ссылается на объект файловой системы, а не на имя. Поэтому при удалении или переименовании оригинального файла эта связь не потеряется. Такие ссылки можно представить как копии оригинальных фалов, но которые не занимают дополнительное место на диске. Жесткие ссылки работают в рамках одного раздела и их нельзя использовать на каталогах. Сам объект файловой системы (файл) будет существовать до последней такой ссылки.
В следующем примере я создаю жесткую ссылку, где 'old_file.txt' - имя существующего файла, а 'new_link.txt' - имя нового:
New-Item -Path 'C:\new_link.txt' -ItemType HardLink -Value 'C:\old_file.txt'
Создание множества файлов и директорий
Параметр Path может принимать несколько значений. Это значит, что одной командой мы можем создать несколько объектов:
New-Item -Path 'C:\doc.ini','C:\data.ini'
Можно использовать сочетания директорий и файлов, добавляя ключ Force тем самым избегая ошибок.
Открываем файл и читаем его содержимое с Get-Content в Powershell
Копирование и перемещение папок и файлов
В следующем примере, с помощью Powershell, будет скопирован файл 'C:\data.txt' в директорию 'C:\Catalog\':
Copy-Item -Path 'C:\data.ini' -Destination 'C:\Catalog\'
Перемещение объектов выполняется так же, но с использованием Move-Item:
Move-Item -Path 'C:\data.ini' -Destination 'C:\Catalog\'
Если в перемещаемой папке уже существует файл с этим именем, то мы получим ошибку:
- Move-Item : Cannot create a file when that file already exists
Для исправления этой ситуации можно использовать параметр Force или перемещать файл под другим именем. Новое имя можно указать в Destination:
Move-Item -Path 'C:\oldname.ini' -Destination 'C:\Catalog\newname.ini'
Каталоги переносятся и копируются так же. Знак '\' в конце Destination говорит, что мы хотим перенести папку внутрь указанной. Отсутствие знака '\' говорит, что это новое имя директории:
Copy-Item -Path 'C:\folder\' -Destination 'C:\folder2'
Path - принимает список, а это значит, что мы можем указывать несколько значений через запятую.
Использование масок для копирования и перемещения
Во многих командах Powershell доступны следующие специальные символы:
- * - говорит, что в этом месте есть неизвестное количество неизвестных символов;
- ? - в этом месте есть один неизвестный символ;
- [A,B,C] - в этом месте есть одна из следующих букв A,B,C.
Например так мы скопируем все объекты с расширением 'txt' из одной папки в другую:
Copy-Item -Path 'D:\*.txt' -Destination 'D:\Catalog\'
Перемещение сработает так же.
Предыдущий вариант сработает, если мы ищем файлы в текущей директории. Для копирования в Powershell внутри всех вложенных каталогов нужно использовать рекурсивный поиск, который доступен только в Copy-Item. Рекурсивный поиск устанавливается ключом Recurse. В следующем примере будет найден и скопирован файл hosts. В качестве * я указал один из элементов неизвестного пути:
Copy-Item -Path 'D:\Windows\System32\drivers\*\host[a,s]' -Destination 'D:\Catalog\' -Recurse
Дополнительные параметры фильтрации
Если предыдущих примеров, где мы находили файлы с неизвестным название, не достаточно, то можно использовать дополнительные параметры. Они доступны в обеих командах Copy-Item и Move-Item:
- Include - включает объекты с этим упоминанием;
- Exclude - работает аналогично предыдущему, но исключает объекты;
- Filter - включает объекты указанные в этом параметре.
Я не вижу смысла использовать все параметры описанные выше в одной команде, но в них есть отличия. Filter будет работать быстрее, так как он работает и фильтрует данные в момент их получения. Include и Exclude сработают после получения всех файлов, но каждое значение для них можно указывать через запятую. Для Include и Exclude так же важно указывать Path с '*' в конце, например 'C:\dir\*'.
Например мы хотим скопировать все объекты с расширением 'txt' и 'jpg'. Это можно сделать так:
Copy-Item -Path 'D:\*' -Include '*.txt','*.jpg' -Destination 'D:\Catalog\'
Я бы не рекомендовал использовать Filter в обеих командах. Более удобный способ - это искать файлы с Get-ChildItem, а затем их копировать и перемещать в нужное место. В следующем примере будут перенесены все объекты формата '.txt' и '.jpg' в каталог Directory:
# Копирование
Get-ChildItem 'D:\Home\*' -Include '*.txt','*.jpg' -Recurse | Copy-Item -Destination 'D:\Catalog\'
# Перенос
Get-ChildItem 'D:\Home\*' -Include '*.txt','*.jpg' -Recurse | Move-Item -Destination 'D:\Catalog\'
Создание и изменение в Powershell NTFS разрешений ACL
Переименование файлов и директорий
Для переименовывания в Powershell используется Rename-Item. В следующем примере мы укажем новое имя в параметре NewName:
Rename-Item -Path 'D:\SomeData.ini' -NewName 'NewData.ini'
В NewName можно указать путь, но он должен соответствовать источнику. При следующем написании будет ошибка:
Rename-Item 'D:\SomeData.ini' -NewName 'D:\SomePath\NewData.ini'
- Rename-Item : Cannot rename the specified target, because it represents a path or device name.
Для массового переименовывания объектов можно использовать конвейер с 'Get-ChildItem'. Например нам нужно поменять расширения файлов с ''.jpg" на ".png" - это можно сделать так:
Get-ChildItem -Path 'D:\pictures\*' -Include '*.jpg' |
Rename-Item -NewName {$PSItem.Name -replace '.jpg','.png'}
Удаление
В следующем примере мы удалим файл:
Remove-Item -Path 'C:\pictures\1.png'
Пустые каталоги в Powershell удаляются так же. Если в папке находятся другие файлы будет запрошено разрешение на удаление.
Remove-Item 'C:\pictures\'
Избежать таких вопросов можно использовав рекурсию в виде параметра Recurse:
Remove-Item -Path 'C:\pictures\' -Recurse
Если нужно удалить все файлы внутри каталога, то нужно добавить знак '*'. Если внутри каталога будут находится другие папки с файлами, то запросится подтверждение:
Remove-Item 'C:\pictures\*'
У команды есть параметры, описанные ранее, в виде:
- Include
- Exclude
- Filter
Работа с сетевыми папками и SMB
Для копирования и переноса данных по сети нужно использовать следующий формат:
'\\server\folder\file'
Он сработает со всеми командами, как для источника так и для назначения:
# Копирования
Copy-Item -Path '\\localhost\C$\*.txt' -Destination '\\localhost\C$\NewCatalog\'
# Перенос
Move-Item -Path '\\localhost\C$\*.txt' -Destination '\\localhost\C$\NewCatalog\'
Выполнение команд под другим пользователем
Любая команда выполняется от имени пользователя, который открыл консоль 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 = Get-Credential
После заполнения этой переменной нужно будет передать ее в параметр Credential. Примеры по работе с файлами удаленно от другого пользователя:
# Переменная, которая хранит нужного пользователя
$credential = Get-Credential
# Удаленное копирование от другого пользователя
Invoke-Command -ComputerName 'localhost' -Credential $credential -ScriptBlock {
Copy-Item -Path 'C:\*.txt' -Destination 'C:\new_directory\' -Force
}
# Удаленное создание объекта
Invoke-Command -ComputerName 'localhost' -Credential $credential -ScriptBlock {
New-Item -Path 'C:\SomeData.txt'
}
...
Подписывайтесь на наш Telegram канал
Теги: #powershell