Уроки Powershell – работа с файлами и папками
Честно говоря, когда я принялся за работу над этим уроком я не знал о чем писать.
Очень уж простым показался вопрос, потому что все примеры есть в стандартной помощи, доступной прямо из консоли.
Казалось бы, все банально, есть командлеты Item которые позволяют создавать (New-Item), удалять (Remove-Item), копировать (Copy-Item) и переименовывать (Rename-Item) и выжать из этого ничего нельзя, но я попробую.
Теория
По сути своей мало что изменилось, более правильно сказать «видоизменилось», и получило новые возможности которые несомненно пригодятся для работы. Если внимательно присмотреться то видно что старые команды поддерживаются через псевдонимы, вернее псевдонимы облегчают переход и поэтому освоение новых команд облегчено и снабжено богатым справочным материалом.
Давайте вернемся к вопросу преемственности поколений… Тьфу. Перехода на новые синтаксис
Первым на что следует посмотреть это аналог хорошо знакомой команды dir, это командлет Get-Children.
Примечание: Действие командлета Get-Children его распространяется не только на файловую систему. Но об этом позже.
В консоли PowerShell введите команду dir, нажмите Enter, затем Get-ChildItem D:\Script и снова Enter, посмотрите на результаты. Они одинаковы. Поптому что dir является алиасом к Get-Children.
Вывод – PowerShell унаследовал все старые команды и снабдил нас замечательной справочной системой.
Как дополнительный пример можно привести аналог для dir /S которая рекурсивно выводит список файлов будет команда.
На замену dir *.exe пришла возможность фильтрации элементов при помощи параметров Path, Filter, Include и Exclude.
Примечание: В своей практике я видел множество вариантов использования но чаще всего фильтрация осуществлялась лишь по имени.
Добавилась сложная фильтрация элементов при помощи командлета Where-Object (сокращенное написание Where).
Простой пример фильтрации по расширению.
Дополнение: PowerShell использует в качестве подстановочных знаков не только ? и * как это было в cmd.exe, но и группы символов в квадратных скобках.
Поэтому если вы попробуете найти файл Script[01].ps1 командой
То получите ошибку.
В этом случае необходимо использовать параметр -LitealPath
Более сложный вариант выполнит поиск архивов в папке D:\Backup, созданных после 1 мая 2011 года, размер которых находится в диапазоне 10-100 Мб.
Опции Include и Exclude работают соответственно своим названиям т.е. первая включает а вторая исключает заданный фильтр из поиска.
$include = @(‘*.txt’,‘*.ps1′)
$result1 = Get-ChildItem "C:\Script" -Recurse -Exclude $exclude
$result2 = Get-ChildItem "D:\Script" -Recurse -Include $include
Перейдем к вопросу копирования файлов.
Аналогом команды copy стал командлет Copy-Item.
В случае если целевой файл уже существует, при попытке его скопировать вы встретите ругань красного цвета
и процесс копирования закончится. Для перезаписи целевого файла используется параметр Force:
Примечание: Ключ Force работает даже когда целевой файл помечен как файл только для чтения.
Копирование дерева папок выполняется той же командой, но с указанием ключа Recurse.
При необходимости копирования определенных объектов, например только скриптов PowerShell-а вы можете задать фильтр.
Создание файлов и папок средствами PowerShell производится с помощью командлета New-Item.
Для создания папки придется указать тип элемента «Directory», а для создания файла «File»
New-Item -Path ‘D:\Script\New Folder\script-02.ps1′ -ItemType "file"
Примечание: Старая команда mkdir, позволяющая создавать папки получила новую жизнь в виде алиаса md.
Переименование элементов производится с помощью команды Rename-Item.
Удаление производится с помощью Remove-Item.
Удалить вложенные в папку элементы можно при помощи командлета Remove-Item, однако он потребует подтверждения удаления, если элемент сам что-нибудь содержит. К примеру, в случае если мы пытаемся удалить папку d:\Backup\20-09-2011, содержащую другие элементы, powershell предложит подтвердить свои действия. Для того что бы этого не происходило (подумайте о том дествительно ли вам нужно удалять
)
Практика
Практическое применение всего вышесказанного может быть разнообразно.
Например, может быть задача поиска в лог файлах определенного выражения по маске ip-адреса «192.168.100.253″ с последующим копированием найденного в папку D:\TEMP, вариантов множество, вот метод поиска:
Можно придумать сценарий когда на файловой помойке требуется из определенной папки удалять все файлы и папки старше 30 дней.
$Days = "-30"
$CurrentDate = Get-Date
$OldDate = $CurrentDate.AddDays($Days)
Get-ChildItem $Path | Where-Object { $_.LastWriteTime -lt $OldDate } | Remove-Item
Или если вам требуется удалять все что есть в папке и в подпапках т.е. удаление еще и самих папок.
$Days = "-30"
$CurrentDate = Get-Date
$OldDate = $CurrentDate.AddDays($Days)
Get-ChildItem $Path -Recuse | Where-Object { $_.LastWriteTime -lt $OldDate } | Remove-Item
PS. Альтернативный метод решения задачи удаления временных файлов скриптом по расписанию вы можете найти в блоге Вадима Стеркина. Рекомендую.
Похожие статьи
Вы можете оставить комментарий.

Сергей, добавь, плиз, якорь в абзац «Можно придумать сценарий когда на файловой помойке». Я поставлю ссылку в Удаление временных файлов скриптом по расписанию
Vadim SterkinЦитировать
Подправил.
Сергей МариничевЦитировать
Не вижу якоря
Я предлагал вставить в абзац
(надеюсь, тег code не позволит съесть ссылку в комменте)
Я бы тогда сослался прямо на абзац.
Vadim SterkinЦитировать
Кэш…
Вычистил.
имя – #script
Сергей МариничевЦитировать
Оки, добавил http://www.outsidethebox.ms/11968/#ps
Vadim SterkinЦитировать
Спасибо.
Сергей МариничевЦитировать
«Если внимательно присмотреться то видно что старые команды поддерживаются через псевдонимы, а освоение новых облегчего богатым справочным материалом.» – старые команды не поддерживаются через псевдонимы,псевдонимы лишь облегчают переход с других платформ и сред.
«Более сложный вариант выполнит поиск архивов в папке D:\Backup, созданных после 1 мая 2011 года, размер которых не превышает 100 мб.» – и больше 10 мб ( в пределах 10-100 мб).
«В случае если целевой файл уже существует, при попытке его скопировать вы встретите ругань красного цвета и процесс копирования закончится. » – если не хватает прав на запись,стоят аттрибуты S,R,вот тогда мы получим ошибку.
Для создание папок,если Вы начали в начале статьи про «старые командлы»,можно рассказать про md,который является альясом mkdir(в свою очередь является proxy function).
«Можно придумать сценарий когда на файловой помойке требуется из определенной папки удалять все файлы старше 30 дней.» – но и за одно и папки удалим.
«Или если вам требуется удалять все что есть в папке и в подпапках» – вместе с подпапками
Так же нет упоминание про параметр -LiteralPath,он очень важен,когда есть подстановочные знаки или escape сиволы.
KazunЦитировать
1. Согласен. Сказано для простоты восприятия. Человека порою пугает когда его знакомая команда copy вдруг отсутствует.
2. Спасибо. Исправил.
3. по умолчанию я считаю что права есть. Пытаться перезаписать файлы на которые нет прав не совсем правильно.
4. Подправил.
5. 6.
7. Ценное дополнение. Сейчас допишу.
Сергей МариничевЦитировать
Get-ChildItem ‘.\Script[01].ps1′ -LiteralPath – поправьте ошибку
3) По третьему пункту,я имел ввиду,то что если нет атрибутов RS ,то ошибки не получим, в случае – существования конечного файла.
KazunЦитировать
Подправил это и еще пару опечаток.
Говорил я себе – публиковать надо в начале дня и только на свежую голову т.к. мелких ошибок и опечаток можно будет и не заметить.
Сергей МариничевЦитировать
Любопытная статья, да и сам сайт я смотрю очень даже не плох. Попал сюда по поиску из Google, занес в букмарки
nanolargeЦитировать
Get-ChildItem $Path -Recuse | Where-Object { $_.LastWriteTime -lt $OldDate } | Remove-Item – поправьте -Recurse
«Или если вам требуется удалять все что есть в папке и в подпапках т.е. удаление еще и самих папок.» – точно сами подпапки удаляются ? Я попробовал с ключем -WhatIf ? показывает что будут удалены только файлы (в папке и подпапке) но не сама подпапка..
maksЦитировать
Спасибо за комментарий.
Зачем удалять папки?
Их нужно удалять только в случае если они пустые. Хотя если есть такая необходимость ваш метод предпочтительнее.
Сергей МариничевЦитировать
Всем доброго времени суток!!! Нужна помощь!
Мне нужно чтоб из папки, удалялись все файлы старше 3х дней, кроме последних двух, как это реализовать?
Щас проблема в том что если файлы не добавились в папку, а оставшиеся стали больше трех дней, то скрипт все удаляет!
СержоЦитировать
пользуюсь вот этим скриптом!
# удаляем файлы старше трех месяцев
$date = (Get-Date).AddDays(-3)
#удаляет все файлы формата *.txt старше трех дней.
Get-ChildItem -Path F:\test\*.txt | where {!$_.PSIsContainer} |
foreach {
if ($_.LastWriteTime -lt $date) {
Remove-Item $_
}
}
СержоЦитировать
вот это http://blog.wadmin.ru/2011/01/delete-old-files/ не то?
Сергей МариничевЦитировать
Я этим скриптом и пользуюсь, переработав его под мои нужды! Нужно както поставить условие удаления!
СержоЦитировать
Тогда вопрос – старше трех кроме последних двух это как?
Сергей МариничевЦитировать
Система значит такая удаляються файлы старше 3хдней, есть 5 файлов, каждый создан в разное время!
файл1 создан 1.01.2012;
файл2 создан 5.01.2012;
файл3 создан 7.01.2012;
файл4 создан 11.01.2012;
файл5 создан 13.01.2012;
на момент удаления число 20.01.2012, скрипт удаляет все эти файлы так как они устаревшие, а мне нужно чтоб файл4 и файл5 не удалился! А когда появяться новые файлы!
файл4 создан 11.01.2012;
файл5 создан 13.01.2012;
файл6 создан 7.02.2012;
файл7 создан 11.02.2012;
файл8 создан 13.02.2012;
скрипт на 20.02 2012 должен удалить все кроме файл7, файл8!
СержоЦитировать
В строке
if ($_.LastWriteTime -lt $date) {
поэкспериментируйте с параметрами LastWriteTime и сложите условия через логическое И
$_.LastWriteTime -lt $date -and $_.LastWriteTime -gt $date
Сергей МариничевЦитировать