Заметки о Windows и других программных продуктах Microsoft...

PowerShell, WMI и операции с файлами

PowerShell, WMI и операции с файлами

Инструментарий управления Windows (Windows Management Instrumentation, WMI) — одна из базовых технологий для мониторинга и управления компьютерами на базе операционных систем Windows. WMI является открытой унифицированной системой интерфейсов доступа ко всем параметрам операционной системы, а также к устройствам и приложениям, работающим в ней.

В числе прочего WMI предоставляет доступ к файловой системе и позволяет производить некоторые действия с файлами и папками. Создавать файлы\папки с помощью WMI нельзя, но можно копировать, удалять и переименовывать файлы. Сегодня мы немного поиздеваемся 🙂 над файлами с помощью WMI и PowerShell.

Примечание. В основе WMI лежит открытая информационная модель (Common Information Model, CIM). Поэтому в Windows существует два типа классов WMI — Win32 и CIM. Так например для работы с файлами очень удобно использовать класс CIM_DataFile, а для работы с директориями класс Win32_Directory.

Также в PowerShell есть два типа командлетов для WMI — традиционные WMI-командлеты и CIM-командлеты, появившиеся в PowerShell 3.0.  Основное их различие в способе удаленного взаимодействия: командлеты WMI используют DCOM, тогда как CIM-командлеты WS-Management. В остальном они работают одинаково, например команды Get-WmiObject и Get-CimInstance выведут практически одно и то же.

Поиск файлов

Найти нужные файлы можно с помощью командлета Get-CimInstance. Для примера выведем список текстовых файлов, находящихся в директории C:\Files, командой:

Get-CimInstance -ClassName CIM_DataFile -Filter ″Drive=′C:′ and Path=′\\Files\\′ and Extension=′txt′″

Примечание. Обратите внимание, что в указании пути используется двойной слэш вместо одинарного. Дело в том, что WMI воспринимает обратный слэш как управляющий символ, поэтому при указании пути его надо обязательно экранировать еще одним слэшем.

поиск файла при помощи фильтра

 

Как вариант, для поиска можно использовать запросы на языке WQL (WMI Query Language). Следующей командой выведем файлы, находящиеся в директории C:\Files и имеющие в своем имени obj:

Get-CimInstance -Query ″SELECT * FROM CIM_Datafile WHERE Drive=′C:′ AND Path=′\\Files\\′ AND Name LIKE ′%obj%′″  | select Name,Version

поиск файла при помощи запроса WQL

 

Для понимания того, по каким критериям можно производить поиск, возьмем произвольный файл и выведем его свойства:

$file = Get-CimInstance -ClassName CIM_Datafile -Filter ″Name=′C:\\Files\\user.txt′″
$file | Get-Member -MemberType Properties

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

вывод свойств файла

 

В качестве примера возьмем дату последнего изменения (LastModified) и найдем все файлы в директории C:\Files, у которых эта дата старше 6 месяцев:

$Date = (Get-Date).addMonth(-6)
$query = ″SELECT * FROM CIM_DataFile WHERE Drive=′C:′ AND Path=′\\Files\\′″
Get-CimInstance _Query $query | where {$_.LastModified -lt $date} | select Name, LastModified

поиск файлов старше чем

 

Примечание. Когда вы производите поиск файлов с помощью Get-ChildItem, то у вас есть возможность указать ключ Recurce для рекурсивного поиска по всем поддиректориям. В отличие от него Get-CimInstance ищет только в указанном расположении. WMI не имеет встроенной рекурсии, поэтому поиск по поддиректориям необходимо реализовывать собственными силами.

Удаление файлов

Все основные операции с файлами производятся с помощью командлета Invoke-CimMethod. Например, для удаления одного файла user.txt можно воспользоваться такой командой:

Get-CimInstance -ClassName CIM_Datafile -Filter ″Name=′C:\\Files\\user.txt′″ | Invoke-CimMethod -MethodName Delete

А удалить из папки все файлы, имеющие в имени user можно так:

$Query = ″SELECT * FROM CIM_Datafile WHERE Drive=′C:′ AND Path=′\\Files\\′ AND Name LIKE ′%user%′″
Invoke-CimMethod -Query $query -MethodName Delete

удаление выбранных файлов

Переименование файлов

Переименование производится с помощью метода Rename. Например, переименовать один файл можно таким образом:

$query = ″SELECT * FROM CIM_Datafile WHERE Name=′C:\\Files\\error.txt′″
$NewName = ′C:\Files\OldError.txt′
Invoke-CimMethod -Query $query -MethodName Rename -Arguments @{FileName=$NewName}

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

 

Один файл переименовать достаточно просто, поэтому возьмем более сложный случай. Например, требуется переименовать группу файлов, заменив в имени файла img на pic. Делаем так:

$query = ″SELECT * FROM CIM_Datafile WHERE Drive=′C:′ AND Path=′\\Files\\′ AND Name LIKE ′%img%′″
$files = Get-CimInstance -Query $query
foreach ($file in $files) {$name=$file.name -replace ′img′,′pic′; Invoke-CimMethod -InputObject $file -MethodName Rename -Arguments @{FileName=$name}}

переименование группы файлов

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

Процедура копирования очень похожа на переименование. Например, скопируем файл pic.png  из директории C:\Files в C:\Temp такой командой:

Invoke-CimMethod -MethodName Copy -Query ″SELECT * FROM CIM_DataFile WHERE Name=′C:\\Files\\pic.png′″ -Arguments @{FileName=″C:\\Temp\\pic.png″}

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

 

А для копирования из C:\Files в C:\Temp всех файлов с именем pic воспользуемся следующей конструкцией:

$query = ″SELECT * FROM CIM_Datafile WHERE Drive=′C:′ AND Path=′\\Files\\′ AND Name LIKE ′%pic%′″
$files = Get-CimInstance -Query $query
foreach ($file in $files) {$name=″C:\Temp\$($file.FileName).$(Sfile.Extension)″; Invoke-CimMethod -InputObject $file -MethodName Copy -Arguments @{FileName=$name}}

копирование группы файлов

 

Как видите, WMI предоставляет альтернативный вариант доступа к файловой системе. Конечно не самый простой и удобный, но вполне рабочий.

 
 
Комментарии

Пока нет комментариев.