{"id":2843,"date":"2013-09-20T00:01:00","date_gmt":"2013-09-20T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/09\/20\/hey-dude-where-are-my-methods\/"},"modified":"2013-09-20T00:01:00","modified_gmt":"2013-09-20T00:01:00","slug":"hey-dude-where-are-my-methods","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-dude-where-are-my-methods\/","title":{"rendered":"Hey, Dude! Where Are My Methods?"},"content":{"rendered":"<p><strong>Summary<\/strong>: Windows PowerShell MVP, Richard Siddaway, talks about WMI&#8217;s missing methods in Windows PowerShell.\nMicrosoft Scripting Guy, Ed Wilson, is here. Today we have a guest blog post by Windows PowerShell MVP, Richard Siddaway.<\/p>\n<p style=\"padding-left: 30px\">Richard has been working with Microsoft technologies for 25 years and has spent time in most &nbsp;IT roles, including analyst-programmer, server administrator, support, DBA, and architect. He has been interested in automation techniques (including automating job creation and submission on main frames many years ago).&nbsp;He originally used VBScript and WMI since it became available on Windows&nbsp;NT 4.0. Windows PowerShell caught his interest during the early beta versions in 2005.&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Richard blogs extensively about Windows PowerShell and founded the UK Windows PowerShell User Group in 2007. A Windows PowerShell MVP for the last six years, Richard has given numerous talks on Windows PowerShell at various events in the UK, Europe, and the USA. He is frequent speaker for Windows PowerShell User Groups worldwide.<\/p>\n<p style=\"padding-left: 30px\">He has published a number of posts about Windows PowerShell, including expert commentaries on the Microsoft Scripting Games, for which he has been a judge for the last four years. He has written two Windows PowerShell books: Windows PowerShell in Practice (Manning 2010) and Windows PowerShell and WMI (Manning 2012). He then collaborated with Don Jones and Jeff Hicks to write Windows PowerShell in Depth, which was published in 2013. Richard is currently writing an introductory book for Active Directory administrators that features Windows PowerShell.<\/p>\n<p style=\"padding-left: 30px\">Contact information: <a href=\"http:\/\/msmvps.com\/blogs\/RichardSiddaway\/Default.aspx\" target=\"_blank\">Richard Siddaway&#8217;s Blog<\/a>\nTake it away Richard&hellip;\nThanks, Ed.\nWMI has been with us for a long time, and it is one of those technologies that you either love or hate. (Some of us manage both at the same time, but that is another story.) Admins love WMI because it&rsquo;s so powerful&mdash;if I can get a WMI connection to your machine, I can do just about anything to that machine. On the flip side, admins hate WMI because it can be very difficult to use, and finding information can be very difficult.\nWindows PowerShell has had great WMI support, which was enhanced in Windows PowerShell&nbsp;3.0 by the introduction of the CIM cmdlets and other WMI enhancements. The new functionality has caused some confusion because the WMI class methods, which we have come to rely on, seem to have disappeared.&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\nBefore I show you what&rsquo;s happened to your methods, I need to dive into a little WMI theory.\nThe starting point is that WMI is Microsoft&rsquo;s implementation of the Common Information Model (CIM). CIM is part of the <a href=\"http:\/\/www.dmtf.org\/standards\/wbem\" target=\"_blank\">Web-Based Enterprise Management<\/a> (WBEM) industry standards that are maintained by the Distributed Management Task Force (DMTF). WBEM is defined as &ldquo;a set of management and Internet standard technologies developed to unify the management of distributed computing environments.&rdquo;&nbsp; WBEM standards are designed to be independent of the operating system and hardware.&nbsp;\nWhen you start Windows, the WMI repository is created. The repository consists of a number of things:<\/p>\n<ul>\n<li>WMI providers (a DLL that provides access to WMI classes)<\/li>\n<li>WMI namespaces<\/li>\n<li>WMI class definitions<\/li>\n<li>WMI instances<\/li>\n<\/ul>\n<p>This is where some if the confusion arises. WMI classes can be taken to refer to the class definition (comparable to Active Directory schema definitions) and the class instances (compare to an object in Active Directory, such as a user).\nWhen we only had the WMI cmdlets in Windows PowerShell 2.0, life was fairly simple in that you do things like this:<\/p>\n<p style=\"padding-left: 30px\">Get-WmiObject -Class Win32_Volume -Filter &#8220;Name = &#8216;C:\\'&#8221; |<\/p>\n<p style=\"padding-left: 30px\">Get-Member -MemberType method&nbsp;\nAnd you would see the list of methods:<\/p>\n<ul>\n<li>AddMountPoint<\/li>\n<li>Chkdsk<\/li>\n<li>Defrag<\/li>\n<li>DefragAnalysis<\/li>\n<li>Dismount<\/li>\n<li>Format<\/li>\n<li>Mount<\/li>\n<li>Reset<\/li>\n<li>SetPowerState<\/li>\n<\/ul>\n<p>At this point, I need to remind you that the WMI is COM based, and the WMI cmdlets work over DCOM to local or remote machines.\nYou could access the methods by creating a Windows PowerShell object that represents the class, and call the method directly:<\/p>\n<p style=\"padding-left: 30px\">$disk = Get-WmiObject -Class Win32_Volume -Filter &#8220;Name = &#8216;C:\\'&#8221;<\/p>\n<p style=\"padding-left: 30px\">$disk.DefragAnalysis()\nThe methods that you have seen so far are <strong>Instance<\/strong> methods. They only make sense and can only be used in the context of an instance. For example, you can&rsquo;t perform <strong>DefragAnalysis<\/strong> against a non-existent volume!\nLet&rsquo;s skip over to Win32_Process for a minute:<\/p>\n<p style=\"padding-left: 30px\">Get-WmiObject -Class Win32_Process&nbsp; | Get-Member -MemberType method\nThis produces the following list of methods:<\/p>\n<ul>\n<li>AttachDebugger<\/li>\n<li>GetOwner<\/li>\n<li>GetOwnerSid<\/li>\n<li>SetPriority<\/li>\n<li>Terminate<\/li>\n<\/ul>\n<p>Notice that there isn&rsquo;t a <strong>Create<\/strong> method&mdash;these are all <strong>Instance<\/strong> methods. You have to have an instance of a process before you can terminate it.\nWhen you are dealing with instances, you are dealing with the System.Management.ManagementObject .NET class. This is where some of the issues lie because you are working with a .NET wrapper for DCOM-based WMI.\nWindows PowerShell is .NET based, and you can create just about any .NET object in Windows PowerShell. The Windows PowerShell team recognized that some .NET objects were of great interest to admins, and they provided shortcuts known as &ldquo;type accelerators.&rdquo; WMI has a number of type accelerators&mdash;in particular, the <strong>[wmiclass]<\/strong> type accelerator.\nIf you apply the <strong>[wmiclass]<\/strong> accelerator to the Win32_Process class, you get this:<\/p>\n<p style=\"padding-left: 30px\">$proc = [wmiclass]&#8217;\\.rootcimv2:Win32_Process&#8217;<\/p>\n<p style=\"padding-left: 30px\">$proc | Get-Member -MemberType method<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp; MemberType<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp; &#8212;&#8212;&#8212;-<\/p>\n<p style=\"padding-left: 30px\">Create Method\nWe now have access to a method that we can use to create instances of the WMI class. The other important point is that we are dealing with a new .NET class: System.Management.ManagementClass. It&rsquo;s a <strong>ManagementClass<\/strong> rather than a <strong>ManagementObject<\/strong>.\nAs a side note, the <strong>Create<\/strong> method is one of the intrinsic methods of a WMI class. It will always be there even if you can&rsquo;t access it. Creating a new instance of the Win32_OperatingSysyem class could do interesting things to your machine!\nIn .NET terms, you can think of these as <strong>Static<\/strong> methods. You don&rsquo;t need an instance of the class to utilize the methods. The WMI registry provider is a classic example of using WMI <strong>Static<\/strong> methods.\n<strong>Get-WmiObject<\/strong> is a bit of a general work horse. You can use it to work with the instances of a WMI class, and you can use it to investigate WMI classes.\nThe Windows PowerShell&nbsp;3.0 CIM cmdlets have separated these functions. <strong>Get-CimInstance<\/strong> is for working with instances of a WMI class only!<\/p>\n<p style=\"padding-left: 30px\">Get-CimInstance -Class Win32_Volume -Filter &#8220;Name = &#8216;C:\\'&#8221; |<\/p>\n<p style=\"padding-left: 30px\">Get-Member -MemberType method<\/p>\n<ul>\n<li>Clone<\/li>\n<li>Dispose<\/li>\n<li>Equals<\/li>\n<li>GetCimSessionComputerName<\/li>\n<li>GetCimSessionInstanceId<\/li>\n<li>GetHashCode<\/li>\n<li>GetObjectData<\/li>\n<li>GetType<\/li>\n<li>ToString<\/li>\n<\/ul>\n<p>Hang on! This is totally different.&nbsp; These aren&rsquo;t the methods we want.\nRemember that the WMI cmdlets work over DCOM to the local or remote machine. DCOM isn&rsquo;t a firewall-friendly or Internet-friendly protocol. It also relies on an old programming methodology that is being replace by .NET.\nThe CIM cmdlets use DCOM to access the local machine if the <strong>&ndash;ComputerName<\/strong> parameter isn&rsquo;t specified. As soon as you utilize the <strong>&ndash;ComputerName<\/strong> parameter to access the local or a remote machine, the CIM cmdlets switch to using WSMAN through the WinRM service. You can also use a CIM session with the CIM cmdlets. CIM sessions also work over WSMAN by default. (CIM sessions will be the subject of a future post.)&nbsp;\nWSMAN is the protocol that is used for Windows PowerShell remoting. Windows PowerShell remoting always returns an inert object&mdash;one that doesn&rsquo;t have any methods. This is exactly the situation with the CIM cmdlets&mdash;they are designed to work over WSMAN, so they return inert objects.\nThe methods that you saw belong to the .NET class, which has changed from the WMI cmdlets. It is now Microsoft.Management.Infrastructure.CimInstance.\nSo far, it&rsquo;s been established that you can&rsquo;t access the <strong>Instance<\/strong> methods of a WMI class directly through <strong>Get-CimInstance<\/strong>. What you can do is pipe the results from your use of the <strong>Get-CimInstance<\/strong> cmdlet to <strong>Invoke-CimInstance<\/strong> to trigger the method, for example:<\/p>\n<p style=\"padding-left: 30px\">Get-CimInstance -ClassName Win32_Process -Filter &#8220;Name = &#8216;notepad.exe'&#8221; |<\/p>\n<p style=\"padding-left: 30px\">Invoke-CimMethod -MethodName Terminate\nThe <strong>Invoke-CimMethod<\/strong> cmdlet has an <strong>&ndash;Arguments<\/strong> parameter, so you can work with methods that need arguments.\n<strong>Get-CimInstance<\/strong> enables you to access instances of a WMI class. How do you investigate WMI classes?\nThis is the function of the <strong>Get-CimClass<\/strong> cmdlet. It gives you access to the WMI class metadata (such as properties, methods, and parameters).<\/p>\n<p style=\"padding-left: 30px\">PS&gt; Get-CimClass -ClassName Win32_Process | fl *<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">CimClassName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Win32_Process<\/p>\n<p style=\"padding-left: 30px\">CimSuperClassName&nbsp;&nbsp; : CIM_Process<\/p>\n<p style=\"padding-left: 30px\">CimSuperClass&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ROOT\/cimv2:CIM_Process<\/p>\n<p style=\"padding-left: 30px\">CimClassProperties&nbsp; : {Caption, Description, InstallDate, Name&#8230;}<\/p>\n<p style=\"padding-left: 30px\">CimClassQualifiers&nbsp; : {Locale, UUID, CreateBy, DeleteBy&#8230;}<\/p>\n<p style=\"padding-left: 30px\">CimClassMethods&nbsp;&nbsp;&nbsp;&nbsp; : {Create, Terminate, GetOwner, GetOwnerSid&#8230;}<\/p>\n<p style=\"padding-left: 30px\">CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties\nNotice that the <strong>Create<\/strong> method is listed. Let&rsquo;s drill down into the method definition:<\/p>\n<p style=\"padding-left: 30px\">PS&gt; $class.CimClassMethods[&#8220;Create&#8221;].Parameters<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CimType Qualifiers<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;- &#8212;&#8212;&#8212;-<\/p>\n<p style=\"padding-left: 30px\">CommandLine&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String {ID, In, MappingStrings}<\/p>\n<p style=\"padding-left: 30px\">CurrentDirectory&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String {ID, In, MappingStrings}<\/p>\n<p style=\"padding-left: 30px\">ProcessStartupInformation Instance {EmbeddedInstance, ID, In, MappingStrings}<\/p>\n<p style=\"padding-left: 30px\">ProcessId&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UInt32 {ID, MappingStrings, Out}\nThe fact that I get the parameter name and expected data type makes life so much easier. It&rsquo;s worth upgrading to Windows PowerShell&nbsp;3.0 for this alone.\nSecondly, <strong>Get-CimClass<\/strong> gives you one way to access to the <strong>Static<\/strong> methods of a WMI class:<\/p>\n<p style=\"padding-left: 30px\">Get-CimClass -ClassName Win32_Process |<\/p>\n<p style=\"padding-left: 30px\">Invoke-CimMethod -MethodName Create -Arguments @{CommandLine=&#8217;notepad.exe&#8217;}\nThe arguments are presented as a hash table with the parameter names as the keys. This removes the issue that arises with <strong>Invoke-WmiMethod<\/strong>, where the expected order of the parameters can change from that in the documentation.\nOne last piece of the puzzle remains: How can we tell if a particular method is a <strong>Static<\/strong> (or intrinsic) method as opposed to an <strong>Instance<\/strong> method? The information is buried in the qualifiers for the methods. Windows PowerShell MVP, Shay Levy, supplied the following script during the discussions that prompted this post:<\/p>\n<p style=\"padding-left: 30px\">$class = Get-CimClass -ClassName Win32_Process<\/p>\n<p style=\"padding-left: 30px\">$class.CimClassMethods | select Name, @{N=&#8217;MethodType&#8217;;<\/p>\n<p style=\"padding-left: 30px\">E={if ($_.Qualifiers[&#8216;Static&#8217;]){&#8216;Static&#8217;}else{&#8216;Instance&#8217;} }}&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MethodType<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-<\/p>\n<p style=\"padding-left: 30px\">Create&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Static<\/p>\n<p style=\"padding-left: 30px\">Terminate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Instance<\/p>\n<p style=\"padding-left: 30px\">GetOwner&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Instance<\/p>\n<p style=\"padding-left: 30px\">GetOwnerSid&nbsp;&nbsp;&nbsp; Instance<\/p>\n<p style=\"padding-left: 30px\">SetPriority&nbsp;&nbsp;&nbsp; Instance<\/p>\n<p style=\"padding-left: 30px\">AttachDebugger Instance&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\nYou can derive the same information by using the WMI cmdlets:<\/p>\n<p style=\"padding-left: 30px\">$class = Get-WmiObject -List Win32_Process -Amended<\/p>\n<p style=\"padding-left: 30px\">$class.Methods | select Name, @{N=&#8217;MethodType&#8217;;<\/p>\n<p style=\"padding-left: 30px\">E={if ($_.Qualifiers[&#8216;Static&#8217;]){&#8216;Static&#8217;}else{&#8216;Instance&#8217;} }}\nYou need to be aware that using the <strong>&ndash;Amended<\/strong> parameter drills deep into the WMI repository, and it is an expensive operation in CPU cycles. It will take several seconds to return the data.\nTo return to the original question&hellip;\nDude, your methods are where they have always been. You just need to access them in a different way.\n~Richard\nThanks, Richard! You can learn more about using WMI and the new CIM cmdlets with Windows PowerShell in Richard&rsquo;s book, <a href=\"http:\/\/www.manning.com\/siddaway2\/\" target=\"_blank\">Windows PowerShell and WMI<\/a> from Manning Publications. Join me tomorrow when Windows PowerShell MVP, Sean Kearney, will talk about Getting Funky with Windows PowerShell.\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.\n<strong>Ed Wilson, Microsoft Scripting Guy<\/strong>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Windows PowerShell MVP, Richard Siddaway, talks about WMI&#8217;s missing methods in Windows PowerShell. Microsoft Scripting Guy, Ed Wilson, is here. Today we have a guest blog post by Windows PowerShell MVP, Richard Siddaway. Richard has been working with Microsoft technologies for 25 years and has spent time in most &nbsp;IT roles, including analyst-programmer, server [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[56,189,3,4,100,6],"class_list":["post-2843","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-richard-siddaway","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell-ise","tag-wmi"],"acf":[],"blog_post_summary":"<p>Summary: Windows PowerShell MVP, Richard Siddaway, talks about WMI&#8217;s missing methods in Windows PowerShell. Microsoft Scripting Guy, Ed Wilson, is here. Today we have a guest blog post by Windows PowerShell MVP, Richard Siddaway. Richard has been working with Microsoft technologies for 25 years and has spent time in most &nbsp;IT roles, including analyst-programmer, server [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2843","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=2843"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2843\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=2843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}