Работа с файлами
Windows PowerShell предоставляет пользователям четыре способа работы с файлами.
- Применение составных команд. Существует ряд команд, созданных специально для работы с файлами. При помощи этих команд вы можете управлять файлами и путями к файлам так, как если бы работали с содержанием файлов.
- Применение команд DOS. PowerShell полностью совместим с командами DOS. Таким образом, то, что вы можете сделать при использовании DOS, вы можете сделать и при помощи PowerShell. PowerShell признает даже команду xcopy.
- Использование инструментария управления Windows Management Instrumentation (WMI). WMI предлагает иной механизм для управления файлами (например, изменение файловых свойств, поиск или переименование файла). Лучше всего запускать команды WMI в удаленном режиме.
- Применение методов Microsoft. NET Framework. Пространство имен. NET System.IO доступно через командную строку PowerShell. Эта строка включает в себя классы System.IO.File и System.IO.FileInfo.
В данной статье я расскажу о командах, которые были созданы специально для файлов. Вот те команды, которые вы можете использовать для работы с файлами:
- Get-ChildItem
- Get-Item
- Copy-Item
- Move-Item
- New-Item
- Remove-Item
- Rename-Item
Использование Get-ChildItem
Команда Get-ChildItem возвращает элементы, обнаруженные в одном или нескольких указанных местах. Местоположение может быть контейнером файловой системы, таким как каталог, или местом, показанным другим провайдером, таким как подраздел реестра или хранилище сертификатов. Вы можете задействовать параметр Recurse данной команды, чтобы добраться до элементов во всех подпапках.
Если использовать эту команду без параметров, она возвращает все дочерние элементы (такие как подпапки и файлы) в текущем местоположении. Например, если текущее местоположение – корневой каталог H, то запуская команду Get-ChildItem, вы получите результаты, похожие на те, что показаны на экране 1.
Используя параметры, вы можете получить информацию, которая вам нужна. Например, следующая команда возвращает все файлы. log в корневом каталоге C, включая подкаталоги:
Get-ChildItem C:\* -Include *.log -Recurse -Force
Как мы видим, эта команда использует параметры -Include, -Recurse и –Force. Параметр –Include служит для возвращения заданных элементов. Он поддерживает использование групповых символов и является идеальным для указания расширения имени файла. Параметр –Recurse дает PowerShell указание возвращать подпапки наряду с файлами. Параметр –Force добавляет скрытые и системные файлы к выходным данным.
После запуска этой команды вы, вероятно, получите обширный список сообщений об ошибках доступа. В зависимости от настроек и политик безопасности системы, доступ к некоторым каталогам (например, Recycle Bin, Start Menu, пользовательские папки) ограничен и их нельзя прочитать. Вы можете скрыть эти сообщения об ошибках, указав параметр -ErrorAction SilentlyContinue.
Следующая команда дает те же результаты, что и предыдущая, потому что параметр –Path понимает групповые символы:
Get-ChildItem -Path C:\*.log -Recurse -Force
Для некоторых параметров команд PowerShell имя параметра вы можете опустить, если знаете, что параметр находится в той позиции, которая нужна PowerShell. Так происходит при использовании параметра –Path команды Get-ChildItem. Таким образом, следующая команда выдаст тот же результат, что и предыдущая команда:
Get-ChildItem C:\*.log -Recurse -Force
Параметр –Path может принимать множественные аргументы, разделенные запятыми. Например, предположим, что вы хотите возвратить. log-файлы из двух мест: корневого каталога С и корневого каталога Н, последний является текущим (то есть местоположением по умолчанию). Для выполнения этого действия нужно указать значение C:\* для получения всех файлов журналов из корневого каталога С и значение * для получения всех файлов журналов из корневого каталога Н (поскольку корневая папка Н является местоположением по умолчанию, вам не нужно указывать H:\.). Необходимо разделить два аргумента запятой, например так:
Get-ChildItem C:\*, * -Include *.log -Force
В результатах примера на экране 2 обратите внимание на атрибут «h" в колонке Mode корневого каталога Н. Этот атрибут показывает, что файл ntuser.dat.LOG является скрытым. Это обнаруживается при помощи параметра –Force.
Хотя в примерах это и не показано, вы можете обратиться к Get-ChildItem при помощи дополнительных имен, псевдонимов. Вот три встроенных псевдонима: dir (как в DOS команда dir), gci и ls (как команда ls в UNIX).
Использование команды Get-Item
Команда Get-Item возвращает заданные элементы из назначенных местоположений. Как и ChildItem, Get-Item может применяться для навигации по различным типам хранилищ данных. В отличие от Get-ChildItem, Get-Item не имеет местоположения по умолчанию, поэтому вы должны всегда предоставлять, как минимум, одно местоположение с помощью параметра –Path. Хотя сам параметр и нужен, указывать имя параметра не требуется. Например, вот простая команда, которая использует «точку» для возвращения информации о текущем каталоге (в данном случае корневая папка Н):
Get-Item.
Результаты показаны на экране 3. Команда Get-Item позволяет задействовать групповой символ * для возвращения всего содержимого элемента (то есть всех дочерних элементов). Например, следующая команда возвращает весь контент текущего каталога (в данном случае корневого каталога Н). Точка и символ звездочки могут быть использованы как компоненты в пути файла, но вы должны еще указать косую черту как разделитель папок:
Get-Item. \*
Результаты вы можете увидеть на экране 4. Важно понимать, что команды PowerShell, включая Get-Item, возвращают объекты. Команда Get-Item возвращает объекты System.IO.DirectoryInfo, которые содержат несколько методов и свойств, которые вы можете использовать. Чтобы увидеть эти методы и свойства, можно передать результаты команды Get-Item в команду Get-Member. Если вы хотите увидеть эти свойства, можете запустить такую команду:
Get-Item. | Get-Member -MemberType Property
Как показано на экране 5, свойство LastAccessTime возвращает дату и время, когда к указанному каталогу был в последний раз осуществлен доступ.
Например, если вы хотите выяснить, когда к текущему каталогу был осуществлен доступ в последний раз, вы запускаете команду:
(Get-Item. ).LastAccessTime
Заметим, что в этой команде вызов Get-Item. заключен в круглые скобки и что между закрывающей круглой скобкой и LastAccessTime стоит точка. Круглые скобки вокруг вызова «Get-Item. » нужны для того, чтобы возвращенные объекты сохранялись в памяти и вы могли бы выполнять с ними дополнительные операции. В этом случае операцией является поиск возвращаемого значения свойства LastAccessTime объекта. В PowerShell вы используете символ точки для получения доступа к ряду свойств объекта и методов. Вот почему следует вставить точку между закрывающейся скобкой и LastAccessTime.
Существует коллекция специальных свойств, которая называется NoteProperty. Вы можете применять ее для того, чтобы сузить выводимые результаты для определенного типа объекта. Вы можете использовать Get-Member с параметром -MemberType NoteProperty, чтобы узнать о специальных свойствах этой коллекции:
Get-Item. | Get-Member -MemberType NoteProperty
Если вы запустите эту команду, то обнаружите, что коллекция возвращает шесть свойств: PSChildName, PSDrive, PSIsContainer, PSParentPath, PSPath и PSProvider. Свойство PSIsContainer коллекции NoteProperty показывает, является ли объект контейнером (папкой). Свойство возвращает True, когда объект является папкой, и False, когда он является файлом. Вы можете использовать это свойство для ограничения вывода Get-Item папками:
Get-Item C:\* | Where-Object { $_.PSIsContainer }
Давайте обсудим эту команду подробнее. Ее результаты показаны на экране 6. Вы передаете по конвейеру весь контент корневого каталога С команде Where-Object, которая позволяет отфильтровать объекты. В этом случае вы используете PSIsContainer из NoteProperty для фильтрации выходных данных, и, таким образом, возвращаются только каталоги. Автоматическая переменная $_ представляет каждый файловый объект, как только он передается команде по конвейеру.
Как и в случае с Get-ChildItem, вы можете обращаться к Get-Item по дополнительному имени. У Get-Item есть одно встроенное дополнительное имя: gi.
Использование Copy-Item
Команда Copy-Item является реализацией в PowerShell команды copy bp DOS и команды cp из UNIX. Но помимо этого, Copy-Item сконструирован для работы с данными, выдаваемыми любым провайдером. Первыми двумя параметрами команды являются -Path (вы используете его для указания элемента, который хотите скопировать) и –Destination (вы применяете его для указания места, в которое хотите скопировать этот элемент). Они позиционные, поэтому имена параметров можно опустить. Например, следующая команда копирует файл test.txt из папки C:\Scripts в папку C:\Backups\Scripts:
Copy-Item C:\Scripts\test.txt C:\Backups\Scripts
Параметр –Path принимает групповые символы, поэтому вы можете копировать несколько файлов сразу. Например, следующая команда копирует все файлы в папке C:\Scripts в папку C:\Backups\Scripts:
Copy-Item C:\Scripts\* C:\Backups\Scripts
Чтобы получить более детальное управление операцией копирования, вы можете задействовать параметры -Recurse, -Filter и –Force. Так, следующая команда копирует все файлы. txt, содержащиеся в C:\Scripts в C:\Temp\Text:
Copy-Item -Path C:\Scripts -Filter *.txt -Recurse `
-Destination C:\Temp\Text
Обратите внимание, что «обратная кавычка» в конце первой строки является символом продолжения строки в PowerShell.
Немного освоившись, вы можете вставить свойство FullName в параметр –Path для копирования тщательно отобранного списка файловых объектов, используя либо Get-Item, либо команду Get-ChildItem:
Get-ChildItem C:\* -include *.txt |
Where-Object { $_.PSIsContainer -eq $false -and `
$_.LastAccessTime -gt ($(Get-Date).AddMonths(-1))} |
ForEach-Object { Copy-Item $_.FullName C:\Temp}
На самом деле это предложение является комбинацией трех отдельных команд. Первая команда (то есть команда в первой строке) возвращает все файлы. txt в корневом каталоге С. Вторая команда (команда во второй и третьей строках) вычленяет список текстовых файлов таким образом, что содержит только те файловые объекты, чье свойство LastAccessTime больше, чем месяц назад. Третья команда (команда в последней строке) вставляет каждое файловое имя в свойство –Path, располагающееся в Copy-Item, используя команду ForEach-Object. Слишком сложно для вас? Тогда можете принять входные данные по конвейеру. Только убедитесь, что вы указали имя параметра –Destination так, чтобы Copy-Item знала, что делать с этими входными данными, так как данный параметр находится не в ожидаемой позиции:
Get-ChildItem C:\* -Include *.log |
Copy-Item -Destination C:\Temp
Хотя в наших примерах это и не показано, вы можете обратиться к Copy-Item через дополнительные имена. Существует три псевдонима: copy, cp, cpi.
Использование Move-Item
Move-Item очень похожа на Copy-Item. Фактически, если вы заменяете Copy-Item на Move-Item в любой из команд, представленных в предыдущем разделе, команды будут вести себя во многом так же, за исключением того, что исходные файлы будут удалены в исходную папку.
Однако есть одно важное различие. Если вы запустите одну и ту же команду Copy-Item дважды, то обнаружите, что PowerShell переписывает существующий файл в папку назначения без какого-либо предупреждения.
Move-Item более осторожна в этом смысле и вместо удаления выдает ошибку. Например, если вы запускаете команду
Get-ChildItem C:\* -Include *.txt |
Where-Object `
{ $_.LastAccessTime -gt ($(Get-Date).AddMonths(-1))} |
ForEach-Object { Move-Item $_.FullName C:\Temp}
то получите ошибку Cannot create a file («нельзя создать файл»), так как файл уже существует. Использование параметра –Force приводит к тому, что Move-Item переписывает существующий файл.
Помимо параметра –Force, вы можете задействовать параметры Recurse и –Filter в команде Move-Item, чтобы настраивать ее. Например, следующая команда перемещает текстовые файлы в папке C:\Scripts и ее подпапках в папку C:\Temp\Text. В данном случае вам нужно указать имя параметра –Destination, поскольку вы не используете этот параметр в той позиции, где его ожидает PowerShell:
Move-Item C:\Scripts -Filter *.txt -Recurse `
-Destination C:\Temp\Text
Как и Copy-Item, Move-Item имеет три псевдонима: move, mv и mi.
Использование New-Item
New-Item играет двойную роль — создателя каталога и файла (кроме того, она может создавать разделы и параметры реестра). Когда вы хотите создать файл, вам нужно указать параметры –Path и –ItemType. Как было показано выше, параметр –Path является позиционным, таким образом, не требуется имя параметра –Path, когда вы задаете путь и имя (то есть путь к файлу) сразу же после имени команды. Также следует указать параметр –ItemType при помощи флажка»file«. Вот пример:
New-Item 'C:\Documents and Settings\Nate\file.txt' `
-ItemType»file«
Параметр –Path может принимать массив строк так, что вы можете создавать несколько файлов за раз. Вам просто нужно разделить пути при помощи запятых. Вдобавок, необходимо вставить сначала параметр -ItemType»file«, который означает, что вам нужно указать имя параметра –Path, поскольку он теперь не первый параметр после имени команды:
New-Item -ItemType»file«-Path»C:\Temp\test.txt«, `
»C:\Documents and Settings\Nate\file.txt«, `
»C:\Test\Logs\test.log«
Если файл с точно таким же именем пути файла уже существует, вы получите ошибку. Однако вы можете указать параметр –Force так, что New-Item перепишет существующий файл.
Что на самом деле примечательно, так это то, что New-Item позволяет вставлять текст в файл посредством параметра –Value:
New-Item 'C:\Documents and Settings\Nate\file.txt' `
-ItemType»file«-Force `
-Value»Here is some text for my new file.«
Не забудьте указать параметр –Force, если файл уже существует. Иначе система выдаст ошибку.
Параметр –Value может принимать ввод данных по конвейеру, что является отличным способом перенаправлять вывод данных других команд в файл. Вам нужно просто конвертировать выходные объекты в строку, используя Out-String (если вы этого не сделаете, New-Item создаст новый файл для каждого объекта). Например, следующая команда возвращает информацию обо всех файлах из корневого каталога С, конвертирует информацию о файлах в строку, а затем пишет эту информацию в файл H:\C Listing.txt:
Get-ChildItem C:\* | Out-String |
New-Item -Path»H:\C Listing.txt«-ItemType»file«-Force
New-Item имеет только одно встроенное дополнительное имя: ni.
Использование Remove-Item
Remove-Item навсегда удаляет ресурс с указанного диска, то есть она не перемещает его в корзину. Таким образом, если вы используете Remove-Item для удаления файла, то нет иного способа вернуть его, кроме как через программу восстановления файлов.
Вы указываете, какой файл должна удалять Remove-Item при помощи параметра –Path. Он позиционный, поэтому вам не нужно указывать имя параметра –Path, если оно идет сразу же за именем команды. Например, вот команда для удаления файла test.txt, который был ранее скопирован в папку C:\Backups\Scripts:
Remove-Item»C:\Backups\Scripts\test.txt«
Давайте рассмотрим другой пример. Следующая команда удаляет все файлы. txt (что указано в параметре –Include) в папке C:\Scripts, кроме тех файлов, которые имеют слово test где-либо в файловом имени (что указано в параметре –Exclude):
Remove-Item C:\Scripts\* -Include *.txt -Exclude *test*
Будучи, по сути, опасным инструментом, Remove-Item предоставляется с парой элементов защиты. Прежде всего, если вы пытаетесь удалить все из папки, которая содержит непустые подпапки, вы получите запрос на подтверждение Confirm. Например, предположим, что C:\Scripts содержит непустые подпапки и вы запускаете такую команду:
Remove-Item C:\Scripts\*
Нужно подтвердить, что вы хотите удалить непустые подпапки, как показано на экране
Если вы хотите запустить сценарий, который использует Remove-Itemм для удаления всего содержимого папок, включая содержимое подпапок, вам нужен способ запускать Remove-Item без участия пользователя. Этот способ – включение флажка –Recurse.
Второй элемент защиты – это параметр –WhatIf. Если вы включаете его в команду Remove-Item, то PowerShell покажет, какие элементы будут удалены, вместо того, чтобы просто удалить их. В силу деструктивной природы операций удаления, имеет смысл выполнять пробное применение команды Remove-Item с параметром –WhatIf, как здесь:
Remove-Item c:\* -Recurse -WhatIf
Результаты примера показаны на экране 8. Заметьте, что результаты могут включать в строку сообщение об ошибке Cannot remove the item at 'C:\Users' because it is in use. Такая ситуация возникает, если текущая рабочая папка является подпапкой каталога, которую вы пытаетесь удалить (в примере – подпапка корневого каталога С).
Что касается дополнительных имен, то Remove-Item стоит особняком. У него шесть псевдонимов: del, erase, rd, ri, rm и rmdir.
Использование Rename-Item
Команда Rename-Item используется, когда вы хотите переименовать ресурс внутри пространства имен, предоставленного провайдером PowerShell. Первый параметр Rename-Item – это –Path, а второй параметр -NewName. Параметр –NewName, как и следовало ожидать, задает новое имя ресурса. Если Rename-Item обнаруживает не только имя, но и путь, он выдаст ошибку. Например, если вы хотите сменить имя файла C Listing.txt из корневого каталога Н на имя c_listing.txt, вам потребуется запустить такую команду:
Rename-Item -Path»H:\C Listing.txt«-NewName c_listing.txt
Поскольку -Path и -NewName являются позиционными параметрами, вы можете пропускать имена параметров до тех пор, пока они находятся в ожидаемых позициях:
Rename-Item»H:\C Listing.txt" c_listing.txt
У Rename-Item есть одно ограничение – параметр –NewName ожидает одной строки без групповых символов. Однако вы можете обойти это требование, перечисляя элементы в каталоге. Вам нужно просто направить по конвейеру выходные данные команде Get-ChildItem в параметр –Path и указать параметр –NewName.
Например, следующая команда перечисляет все файлы в текущем каталоге и переименовывает каждый файл, заменяя все пробелы в файловых именах на подчеркивания:
Get-ChildItem * |
Where-Object {! $_.PSIsContainer } |
Rename-Item -NewName { $_.name -replace ' ','_' }
Давайте посмотрим, как работает эта команда. Выходные данные Get-ChildItem попадают в Where-Object, которая фильтрует выходные данные так, что возвращаются только файлы. Это достигается путем использования PSIsContainer из NoteProperty с логическим оператором -not (!) (в качестве альтернативы вы могли бы взять $_.PSIsContainer -eq $false, как это было сделано в предыдущем примере). Отфильтрованные выходные данные (файловые объекты) попадают в Rename-Item. Значение параметра –NewName в Rename-Item является блоком сценария. Этот блок будет выполнен перед командой Rename-Item. В блоке сценария автоматическая переменная $_ представляет каждый файловый объект, так как он попадает в команду через контейнер. Оператор сравнения –replace заменяет пробелы в каждом имени файла (' ') на символ подчеркивания ('_'). Заметьте, что вы можете использовать выражение '\s' для указания пробела, поскольку первый параметр принимает регулярные выражения. Даже скрытые файлы могут быть переименованы благодаря параметру –Force.
Rename-Item имеет два псевдонима: ren и rni.
Великолепная семерка
В данном руководстве я познакомил вас со способами взаимодействия PowerShell с файлами. В частности, мы изучили встроенные команды PowerShell, предназначенные для работы с файлами. Это Get-ChildItem, Get-Item, Copy-Item, Move-Item, New-Item, Remove-Item и Rename-Item.
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.