Automating the world one-liner at a time…
<Edited 7/2/2006 to add tags and categories>We have recently completed work on improved support for WMI including:
Everyone that uses WMI owes a debt of gratitude to Greg Ramsey. Greg did an MMS session and lab focused on Scripting SMS using VBscript and Windows PowerShell. Jim Truher and I joined Greg to host a Birds of a Feather (BOF) session on Scripting. Greg was quite enthusiastic about the power of Windows PowerShell but during the BOF someone asked him directly, "So which is it - should we be using VBscript or Windows PowerShell to script SMS". I forgot exactly what Greg said but it was along the line so of, "if you want to do reporting, use Windows PowerShell because it is very powerful but if you want to get things done, use VBScript because you can't invoke WMI methods (at least not easily)".
This was a real wake up call for us. Greg is exactly the sort of person that we want to be a ardent, unabashed, no reservations, hard core Windows PowerShell user and the message was loud and clear - almost but not quite.
We knew that our WMI support was not what we wanted it to be but as I've mentioned many times, to ship is to choose. We thought that we had reasonable support and that WMI users wouldn't be phased by some of the deficiencies - yes calling methods was complex but we figured that if you were using WMI, you were self-qualified as being able to cope with complexity :-) .
Just to be precise, you could always call WMI methods but you had to do so using the Invoke_Method() call pass it the name of the Method and then all the parameters encoded as an array. It was probably total folly to think that this was an acceptable user-experience but it took Greg's comment to get things moving on the right track.
In RC2 this is what a WMI object looks like:
PS> $g=Get-WmiObject Win32_process -filter 'Name = "calc.exe"'PS> $g |gm -membertype "Method,Property" TypeName: System.Management.ManagementObject#root\cimv2\Win32_Process
Name MemberType Definition---- ---------- ----------AttachDebugger Method System.Management.ManagementBaseOb...GetOwner Method System.Management.ManagementBaseOb...GetOwnerSid Method System.Management.ManagementBaseOb...SetPriority Method System.Management.ManagementBaseOb...Terminate Method System.Management.ManagementBaseOb...__CLASS Property System.String __CLASS {get;}__DERIVATION Property System.String[] __DERIVATION {get;}__DYNASTY Property System.String __DYNASTY {get;}__GENUS Property System.Int32 __GENUS {get;}__NAMESPACE Property System.String __NAMESPACE {get;}__PATH Property System.String __PATH {get;}__PROPERTY_COUNT Property System.Int32 __PROPERTY_COUNT {get;}__RELPATH Property System.String __RELPATH {get;}..........
Notice that the Methods are now the WMI methods for that particular WMIObject (and not the Methods for WMI). If you want those, you can still get them using PSBASE (Remember - PSBASE is the way to bybass our type Adapter and get an the native capabilities of an object).
PS> $g.psbase |gm -membertype Method TypeName: System.Management.Automation.PSMemberSet
Name MemberType Definition---- ---------- ----------add_Disposed Method System.Void add_Disposed(EventHandl...Clone Method System.Object Clone()CompareTo Method System.Boolean CompareTo(Management...CopyTo Method System.Management.ManagementPath Co...CreateObjRef Method System.Runtime.Remoting.ObjRef Crea...Delete Method System.Void Delete(), System.Void D...Dispose Method System.Void Dispose()Equals Method System.Boolean Equals(Object obj)Get Method System.Void Get(), System.Void Get(...get_ClassPath Method System.Management.ManagementPath ge...get_Container Method System.ComponentModel.IContainer ge...get_Item Method System.Object get_Item(String prope...get_Options Method System.Management.ObjectGetOptions ...get_Path Method System.Management.ManagementPath ge...get_Properties Method System.Management.PropertyDataColle...get_Qualifiers Method System.Management.QualifierDataColl...get_Scope Method System.Management.ManagementScope g...get_Site Method System.ComponentModel.ISite get_Site()get_SystemProperties Method System.Management.PropertyDataColle...GetHashCode Method System.Int32 GetHashCode()GetLifetimeService Method System.Object GetLifetimeService()GetMethodParameters Method System.Management.ManagementBaseObj...GetPropertyQualifierValue Method System.Object GetPropertyQualifierV...GetPropertyValue Method System.Object GetPropertyValue(Stri...GetQualifierValue Method System.Object GetQualifierValue(Str...GetRelated Method System.Management.ManagementObjectC...GetRelationships Method System.Management.ManagementObjectC...GetText Method System.String GetText(TextFormat fo...GetType Method System.Type GetType()InitializeLifetimeService Method System.Object InitializeLifetimeSer...InvokeMethod Method System.Object InvokeMethod(String m...Put Method System.Management.ManagementPath Pu...remove_Disposed Method System.Void remove_Disposed(EventHa...set_Item Method System.Void set_Item(String propert...set_Options Method System.Void set_Options(ObjectGetOp...set_Path Method System.Void set_Path(ManagementPath...set_Scope Method System.Void set_Scope(ManagementSco...set_Site Method System.Void set_Site(ISite value)SetPropertyQualifierValue Method System.Void SetPropertyQualifierVal...SetPropertyValue Method System.Void SetPropertyValue(String...SetQualifierValue Method System.Void SetQualifierValue(Strin...ToString Method System.String ToString()
But now that the Instance properties are exposed, WMI objects act more like "normal" objects:PS> $g.GetOwner()__GENUS : 2__CLASS : __PARAMETERS__SUPERCLASS :__DYNASTY : __PARAMETERS__RELPATH :__PROPERTY_COUNT : 3__DERIVATION : {}__SERVER :__NAMESPACE :__PATH :Domain : NTDEVReturnValue : 0User : jsnover
PS> $g.Terminate()__GENUS : 2__CLASS : __PARAMETERS__SUPERCLASS :__DYNASTY : __PARAMETERS__RELPATH :__PROPERTY_COUNT : 1__DERIVATION : {}__SERVER :__NAMESPACE :__PATH :ReturnValue : 0
We have also changed the Adapted view of WMI Classes. These used to share the same adapter as WMI Instances which meant that you saw instance properties, which makes no sense. Here is what a WMI Class now looks like:PS> $c = Get-WmiObject -list |where {$_.Name -eq "Win32_Process"}PS> $c |Format-List *Name : Win32_Process__GENUS : 1__CLASS : Win32_Process__SUPERCLASS : CIM_Process__DYNASTY : CIM_ManagedSystemElement__RELPATH : Win32_Process__PROPERTY_COUNT : 45__DERIVATION : {CIM_Process, CIM_LogicalElement, CIM_ManagedSystemEleme nt}__SERVER : JPSLAP04__NAMESPACE : ROOT\cimv2__PATH : \\JPSLAP04\ROOT\cimv2:Win32_Process
PS> $c | Get-Member -MemberType Method TypeName: System.Management.ManagementClass#ROOT\cimv2\Win32_Process
Name MemberType Definition---- ---------- ----------Create Method System.Management.ManagementBaseObject Create(System.S...
And you can use it just as you would expectPS> $c.Create("Calc.exe")__GENUS : 2__CLASS : __PARAMETERS__SUPERCLASS :__DYNASTY : __PARAMETERS__RELPATH :__PROPERTY_COUNT : 2__DERIVATION : {}__SERVER :__NAMESPACE :__PATH :ProcessId : 2948ReturnValue : 0
In addition to these, we decided to add direct language support for WMI into Windows PowerShell.
[WMISEARCHER] is a type accelerator for a ManagementObjectSearcher. It can take a string constructor to create a searcher that you can then do a GET() on:
PS> $s = [WmiSearcher]'Select * from Win32_Process where Handlecount > 1000'
PS> $s.Get() |sort handlecount |ft handlecount,__path,name -auto
handlecount __PATH name----------- ------ ---- 1105 \\JPSLAP04\root\cimv2:Win32_Process.Handle="3724" powershell... 1132 \\JPSLAP04\root\cimv2:Win32_Process.Handle="1388" winlogon.exe 1495 \\JPSLAP04\root\cimv2:Win32_Process.Handle="2852" iexplore.exe 1699 \\JPSLAP04\root\cimv2:Win32_Process.Handle="1204" OUTLOOK.EXE 1719 \\JPSLAP04\root\cimv2:Win32_Process.Handle="1912" iexplore.exe 2579 \\JPSLAP04\root\cimv2:Win32_Process.Handle="1768" svchost.exe
[WMI] is a type accelerator for ManagementObject. This has a string constructor taking a local or absolute WMI Path to a WMI instace and returning a object bound to that instance:
PS> $p = [WMI]'\\JPSLAP04\root\cimv2:Win32_Process.Handle="1204"'PS> $p.NameOUTLOOK.EXE
[WMICLASS] is a type accelerator for ManagementClass. This has a string constructor taking a local or absolute WMI Path to a WMI class and returning a object bound to that class:
PS> $c = [WMICLASS]"root\cimv2:WIn32_Process"PS> $c |fl *Name : Win32_Process__GENUS : 1__CLASS : Win32_Process__SUPERCLASS : CIM_Process__DYNASTY : CIM_ManagedSystemElement__RELPATH : Win32_Process__PROPERTY_COUNT : 45__DERIVATION : {CIM_Process, CIM_LogicalElement, CIM_ManagedSystemEleme nt}__SERVER : JPSLAP04__NAMESPACE : ROOT\cimv2__PATH : \\JPSLAP04\ROOT\cimv2:Win32_Process
We think that these changes make Windows PowerShell THE best environment to use and script WMI. When RC2 comes out towards the end of the summer, you'll be able to kick the tires on these new features and let us know if you agree.
I want to highlight the role of user feedback in these changes. If it wasn't for Greg speaking up and giving us honest feedback about where we were not doing a good enough job, these changes would not have been made. So hat's off to Greg but also - if there is something about Windows PowerShell that you don't like - let us know - we really are listening.
Enjoy!
Jeffrey SnoverWindows PowerShell Architect
PSMDTAG:FAQ: How do i invoke a method on a WMI class?PSMDTAG:FAQ: How do i invoke a method on a WMI object?PSMDTAG:FAQ: How can I use WQL?PSMDTAG:FAQ: How do I use WMI?PSMDTAG:FAQ: How do I bind to a WMI Instance from a WMI PATH?PSMDTAG:TYPE:WMI [WMI] [WMICLASS] [WMISEARCHER]PSMDTAG:TYPE:WMI Invoking methods
I wonder why
get-wmiobject -class win32_scheduledjob
doesn't return an object, although scheduled tasks exist on the machine and the class "win32_scheduledjob" is listed by
get-wmiobject -list
I repeat the same question asked by Charlie on Nov 01 2006.
get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername .
My above script to access Scheduled Jobs. Howvere I don't any objects returned.
Is there a way third party can implement this dynamic cmdlet like WMI object?
Current cmdlet samples are all static interface.
if scheduled jobs were created not using wmi, you won't see them in wmi. look up win32_scheduledjob in msdn for the details.
Hi I am getting the following error on my script when i try it on remote servers.
The Object exporter specified was not found.
Is there anyway to resolve this issue.
Thanks
Bhavesh
Why is there never VC++ examples described.
WMI is great integrated in our application, the DCOM API works fine, but is not as documented as you would hope.
Maybe it will come.
In the meantime, I have found a good and detailed example at:
http://www.vedivi.com/blog
It seems C++ developers are a dying breed.
PSMDTAG:FAQ: What is a TYPE SHORTCUT? PSMDTAG:FAQ: What are the TYPE SHORTCUTS? Type shortcuts are a
A sneak peak at new stuff in WMI in Windows 7. (Continuation of WMI - The story so far ) WMI, Powershell