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



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

$ 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 надає альтернативний варіант доступу до файлової системи. Звичайно не самий простий і зручний, але цілком робочий.

.

Поделитесь информацией

Share on FacebookTweet on TwitterPlus on Google+


EmoticonEmoticon