Создание в Powershell директорий и файлов с New-Item их перенос и копирование


22 мая 2020


Создание файлов и папок с Powershell New-Item с копированием и переименованием

Для работы с файлами в Powershell есть около 10 команд. С помощью команды New-Item можно создать файл или папку в Powershell, жесткую и мягкую ссылку. Copy-Item и Move-Item выполняют копирование и перемещение объектов. В этой стать мы рассмотрим все эти операции, а так же удаление директорий и файлов включая сетевые пути, на примерах.

 

Создание файлов

В следующем примере мы создадим файл с расширением '.txt':

New-Item file.txt

Создание файлов в Powershell New-Item

По умолчанию файл создается в той директории откуда был запущен сам Powershell. Изменить путь создания файла можно указав путь в Path:

New-Item -Path 'C:\file.txt'

Создание файлов по пути с Powershell New-Item

Каждая папка так же является файлом, но для ее создания в Powershell нужно указывать тип 'Directory' в 'ItemType':

New-Item -Path 'C:\Dir\' -ItemType Directory

Создание каталогов с Powershell New-Item

Создание со вложенными директориями

Мы можем создать множество папок не указывая дополнительных параметров:

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

Создание вложенных папок с Powershell New-Item

Перезапись

Ключ 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 New-Item

Запись данных

Еще один из способа перезаписи файлов в Powershell - использование символа перенаправления вывода '>'. Если объект уже существует - он будет перезаписан, иначе будет создан новый файл:

'test' > file.txt
Get-Content .\file.txt

Запись в файл с Powershell New-Item

Почти такой же результат будет если добавить в команду параметр Value. Результат следующего примера будет аналогичен предыдущему:

New-Item -Path 'C:\file.txt' -Value 'test'
Get-Content 'C:\file.txt'

Запись в файл с Powershell New-Item

Мягкие и жесткие ссылки

Кроме файлов и директорий в 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'

Создание жестких ссылок с Powershell New-Item 

Создание множества файлов и директорий

Параметр Path может принимать несколько значений. Это значит, что одной командой мы можем создать несколько объектов:

New-Item -Path 'C:\doc.ini','C:\data.ini'

Создание нескольких файлов с Powershell New-Item

Можно использовать сочетания директорий и файлов, добавляя ключ Force тем самым избегая ошибок.

 

Копирование и перемещение папок и файлов

В следующем примере, с помощью 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

Копирование файлов с Powershell Copy-Item

Дополнительные параметры фильтрации

Если предыдущих примеров, где мы находили файлы с неизвестным название, не достаточно, то можно использовать дополнительные параметры. Они доступны в обеих командах 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\'

Копирование множества файлов с Powershell Copy-Item

Я бы не рекомендовал использовать 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 используется 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'}

Переименовывание файлов с Powershell Rename-Item

 

Удаление

В следующем примере мы удалим файл:

Remove-Item -Path 'C:\pictures\1.png'

Пустые каталоги в Powershell удаляются так же. Если в папке находятся другие файлы будет запрошено разрешение на удаление. 

Remove-Item 'C:\pictures\'

Удаление файлов с Powershell Remove-Item

Избежать таких вопросов можно использовав рекурсию в виде параметра 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

Запрос учетных данных пользователя Powershell 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'
}

Удаленное создание файлов и директорий в Powershell 

...

Теги: #powershell


Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.