Резюме: Microsoft Scripting Guy, Ed Wilson рассказывает об использовании Windows PowerShell 3.0 и CIM-командлетов для исследования классов WMI.
Одна из проблем при путешествии поездом – это стоимость беспроводного интернета, я и не готов платить столько. Это означает что я ограничен ресурсами моего ноутбука. В былые времена я обычно устанавливал WMI SDK на ноутбук, чтобы иметь информацию о классах. Сейчас WMI SDK включается в Windows Platform SDK (или он называется как-то по другому?), и он занимает кучу места, которого у меня нет. К счастью мне не обязательно выделять на диске столько пространства для определения записываемых (writable) свойств и реализованных (implemented) методов классов WMI. Для этого я могу воспользоваться командлетом Get-CIMClass.
Исследуем классы WMI
Множество классов WMI обладают записываемыми свойствами. Для определения этих свойств мне нужно найти свойства, обладающие определителем (qualifier) «write». На самом деле мне не нужно делать это самому, я могу воспользоваться утилитой WbemTest. Итак, я набираю WbemTest в консоли Windows PowerShell. Когда она откроется, мне нужно будет нажать на кнопку connect, для того чтобы подключиться к пространству имен (namespace) root/cimv2. После подключения я могу нажать на кнопку Open Class и ввести, например, Win32_ComputerSystem. Откроется окно Object Editor for Win32_ComputerSystem. Мне нужно взглянуть на каждое свойство по отдельности для просмотра его определителей. Если свойство не обладает определителем write – это свойство только для чтения, как показано на рисунке ниже.
Использовав старый командлет Get-WmiObject и передав результаты командлету Get-Member мы получим неверную информацию, так как он для всех свойств указывает Get;Set (но благодаря WbemTest я знаю, что свойство name – только для чтения).
PS C:\> Get-WmiObject win32_computersystem | get-member -Name name
TypeName: System.Management.ManagementObject#root\cimv2\Win32_ComputerSystem
Name MemberType Definition
—- ———- ———-
Name Property string Name {get;set;}
Используем классы CIM для нахождения записываемых свойств WMI
Достаточно простой способ получения информации о классе WMI – это использование командлета Get-CimClass. Например, чтобы получить все записываемые свойства для класса WMI, такого как Win32_CoputerSystem, я могу использовать следующий код:
Get-CimClass win32_computersystem | select -ExpandProperty cimclassproperties |
where qualifiers -match ‘write’ | Format-table name, qualifiers
Вывод команды вы можете видеть на рисунке.
Используем Get-CimClass для нахождения методов WMI
Таким же образом, как я получил записываемые свойства WMI, я могу получить реализованные (implemented) методы WMI. Класс WMI может обладать 5 методами и только 3 из них (например) могут обладать определителем implemented. Это потому, что все классы WMI наследуются от других классов WMI, которые наследуются от других классов WMI и т.д. и т.д. Таким образом, абстракция (abstract) может обладать методом SetPowerState, но динамический класс WMI, который я собираюсь использовать может не реализовывать этот метод (на самом деле я знаю, что ни один класс WMI не реализует метод SetPowerState).
Итак, таким же образом, как я искал определитель write в cimclassproperties, я буду искать определитель implemented в свойстве cimclassmethods.
Get-CimClass win32_computersystem | select -ExpandProperty cimclassmethods |
where qualifiers -match ‘implemented’ | Format-Table name, qualifiers
Результаты запроса приведены на рисунке.
Автор:
Ed Wilson, Microsoft Scripting Guy
Оригинал:
Страницы в социальных сетях:
Twitter: https://twitter.com/vsseth
Facebook: https://fb.com/inpowershell
VKontakte: https://vk.com/inpowershell
Здравствуйте Cthutq.
Помогите понять такое:
При выполнении инвентаризации памяти удаленного компа я получаю пустой результат. Но при обращению к описания процессора результат есть.
Я заметил закономерность, что строковый результат проблем не создает, но когда создается массив, то я его не имею на возврате.
Хотя прямое обращение через командлет к удаленному компу работает.
PS C:\Windows\system32> Srezult = Invoke-Command -ComputerName IN4411546 {(get-wmiobject win32_Processor).Description}
PS C:\windows\system32> Srezult
Intel64 Family 6 Model 15 Stepping 11
PS C:\Windows\system32> Srezult = Invoke-Command -ComputerName IN4411546 {(gwmi -class Win32_PhysicalMemory).Capacity}
PS C:\Windows\system32> Srezult
PS C:\Windows\system32> Srezult = (gwmi -class Win32_PhysicalMemory -Computer IN4411546).Capacity
PS C:\Windows\system32> Srezult
1073741824
1073741824
1073741824
PS C:\Windows\system32>
Привет.
Я так понял, что обращаешься ты к компьютеру с операционкой Windows XP или в Windows 7 в которой версия PowerShell ниже третьей.
Дело в том, что возможность обратиться к массиву подобным образом и получить значение определенного свойства для входящих в него элементов появилась в Windows PowerShell 3. В более ранних версиях такой фокус не проходил.
То есть команда $array.SomeProperty в третьей версии вернет значения свойства SomeProperty для всех входящих в массив элементов. Во второй версии эта команда не вернет ничего.
Это можно проверить явным образом зайдя в сессию на удаленном компьютере — Enter-PSSession — и попробовать запустить команду из приведенного тобой примера.
спасибо за ответ. действительно я работаю на PS 3.0, а все исследуемые компы на PS 2.0
Уж очень хотелось изящно провести инвентаризацию моих компов как в книге Windows PowerShell in Action, Second Edition BRUCE PAYETTE на стр. APPLYING POWERSHELL REMOTING 459
Надо что-то придумать свое.
Можно, например, изменить скрипт следующим образом:
спасибо, я продвинулся в понимании PS. «Вы теперь как ангел, не сходите ж с алтаря»