Summary: Microsoft Scripting Guy teaches you how to use .NET Framework classes to explore the Windows PowerShell process in this beginner how-to post

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! I want to first tell you that I appreciate all the hard work you do. I find your articles to be both funny and educational. I will admit, however, that I do not understand everything you write. This includes your allusions to Anzac biscuits as well as your more serious comments about the .NET Framework. In fact, I guess if I actually cared, I could click your link about Anzac biscuits and figure out what is going on there, but the problem with the .NET Framework, that it is huge. I thought we were supposed to be learning about Windows PowerShell. Therefore, my question is as follows: what is the relationship between Windows PowerShell and the .NET Framework?

-- MJ

 

Hey, Scripting Guy! AnswerHello MJ, Microsoft Scripting Guy Ed Wilson here. I love Microsoft Outlook 2010! I am on the road again, and I am using the cool offline feature because there is no wireless access around. This time, the Scripting Wife and I are attending a SQL Saturday in Orlando, Florida. We figure if we are going to drive all the way down there (I still am unable to fly - Dr. orders, not the TSA no fly list) we may as well spend some time in the sunshine state so we are going to take a few days of holiday while we are down there. We packed Dr. Scripto and are going to head for the beach. I actually grew up in Florida so this is like a homecoming for me. In the meantime, it will be a fun drive or more correctly, a fun ride. I am working, and the Scripting Wife is driving. I fixed a thermos of English Breakfast tea before leaving the house, she snagged my Zune HD and is blasting the Rolling Stones as we take to the open road. Don't get me wrong, I love the Rolling Stones, we even went to see them when we were in Munich, Germany while I was there teaching a Windows PowerShell class to Microsoft Premier customers at the office in Unterschleißheim. But dude, Forty Licks at 6:00 AM is beyond my tolerance for fun.

MJ, I will let you check Anzac biscuits on the Internet if you wish, I fell in love with them while I was in Brisbane, Australia teaching a VBScript workshop. On every trip back there, I always make it a point to stuff my suitcase with them before my return trip to the United States. I have not located a local supply in Charlotte, North Carolina. Luckily, my Aussie friends bring some with them when they come to the U.S., and somehow they always find their way to me in Charlotte.  

MJ, your second question was about the .NET Framework's relationship to Windows PowerShell. First, Windows PowerShell is a .NET Framework application. This means that it is a computer program, an application, built upon the .NET Framework. The .NET Framework consists of classes that arrange into namespaces. The classes in a particular namespace are usually arranged a particular theme such as security, XML, input and output, directory services, protocols and other things. If you think about the kinds of things that a computer must be able to do you can generally find a namespace related to that, and from there find the appropriate .NET Framework class that encapsulates the required functionality. An example will help make this clear.

MJ, suppose that you are concerned about processes on your computer. It seems to be running slow, and you want to diagnose the problem. As it turns out, there is a .NET Framework namespace named System.Diagnostics that is documented in MSDN. By examining the list of classes in the System.Diagnostics namespace, you will eventually run across the Process .NET Framework class. To work directly with .NET Framework classes, you have to know whether the class has any static properties or methods that do what you want to do. If it does not, then you may have to create a new instance of a class so that you can use the instance methods or properties. This may sound a bit confusing, so I will talk you through determining the static properties and methods (known as members) of the Process class.

The first thing that I like to do is to make sure that I have things correct. To do this, I will type the .NET Framework namespace and class name onto the command line in the Windows PowerShell console. When doing this, the user must put it inside square brackets. This command and the associated output are here.

PS C:\> [system.diagnostics.process]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Process                                  System.ComponentModel.Component


PS C:\>

In the output above, two things are confirmed. The first is that the namespace / class name combination is correct, and second that the .NET Framework assembly that contains the class is loaded into Windows PowerShell. An assembly is the .NET Framework code that tells the .NET Framework how to create the class we want to use. By default, Windows PowerShell loads the most common .NET Framework classes that are likely to be used by Windows PowerShell users. Occasionally, you may have to load an assembly to provide access to a specific .NET Framework class (an example would be the assembly that is used to provide access to an old Visual Basic 6 style message box). Nothing is required to load the Process class, because the previous command worked correctly.

To determine if there are any static members available from the Process class, pipe the class to the Get-Member Windows PowerShell cmdlet and use the -static switch. An example of how to use this command is here.

PS C:\> [system.diagnostics.process] | Get-Member -Static


   TypeName: System.Diagnostics.Process

Name               MemberType Definition
----               ---------- ----------
EnterDebugMode     Method     static System.Void EnterDebugMode()
Equals             Method     static bool Equals(System.Object objA, System.Object objB)
GetCurrentProcess  Method     static System.Diagnostics.Process GetCurrentProcess()
GetProcessById     Method     static System.Diagnostics.Process GetProcessById(int processId, st...
GetProcesses       Method     static System.Diagnostics.Process[] GetProcesses(), static System....
GetProcessesByName Method     static System.Diagnostics.Process[] GetProcessesByName(string proc...
LeaveDebugMode     Method     static System.Void LeaveDebugMode()
ReferenceEquals    Method     static bool ReferenceEquals(System.Object objA, System.Object objB)
Start              Method     static System.Diagnostics.Process Start(string fileName, string us...


PS C:\>

The first thing I notice in the output is that there are no properties, only methods. Properties describe things, and methods are used to do things. The GetCurrentProcess static method looks interesting. To use it, call it from the Process class by using double colons. This is illustrated here.

PS C:\> [system.diagnostics.process]::GetCurrentProcess()

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    449      22    53520      53132   569     1.42   2108 powershell


PS C:\>

In the output above, the GetCurrentProcess static method provides information about the currently running process-PowerShell in this example. If I store this returned process object into a variable, I can access it by using the variable. As seen here, I store the Process object in the $a variable.

PS C:\> $a = [system.diagnostics.process]::GetCurrentProcess()
PS C:\> $a

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    391      22    50468      50092   569     1.44   2108 powershell

The output from the $a variable is the same as the output that was received directly from the GetCurrentProcess static method. This is because in both cases, I am working with an instance of the System.Diagnostics.Process .NET Framework class. Previously, I showed you that there were several static methods. Static methods are always available of a class - that is what makes them static. Nevertheless, when I have an instance of the class, then additional members are revealed when I pipeline the object to the Get-Member Windows PowerShell cmdlet. This command is here.

PS C:\> $a = [system.diagnostics.process]::GetCurrentProcess()
PS C:\> $a | Get-Member

As illustrated in the following figure, the results are very extensive.

 

There are several properties that look interesting, but one property stands out to me - modules. To retrieve the modules property, I only have to call it directly by using a dotted notation. The command to do this is:

$a = [system.diagnostics.process]::GetCurrentProcess()
$a.Modules

 

The output from the command is visible in the following figure.

By piping the results from querying the modules property to a Windows PowerShell where-object cmdlet (where is an alias for where-object that I use to shorten the command a bit) I can find only the modules that are loaded from locations that have a direct relationship to the .NET Framework. The information returned is interesting, as seen here.

PS C:\> $a = [system.diagnostics.process]::GetCurrentProcess()
PS C:\> $a.Modules | where { $_.filename -match "microsoft.net" -OR $_.filename -match "assembly" }

   Size(K) ModuleName                                         FileName
   ------- ----------                                         --------
       576 mscoreei.dll                                       C:\Windows\Microsoft.NET\Framework...
      9912 mscorwks.dll                                       C:\Windows\Microsoft.NET\Framework...
     15212 mscorlib.ni.dll                                    C:\Windows\assembly\NativeImages_v...
     10360 System.ni.dll                                      C:\Windows\assembly\NativeImages_v...
       712 Microsoft.PowerShell.ConsoleHost.ni.dll            C:\Windows\assembly\NativeImages_v...
     11632 System.Management.Automation.ni.dll                C:\Windows\assembly\NativeImages_v...
      3248 System.Core.ni.dll                                 C:\Windows\assembly\NativeImages_v...
       420 Microsoft.PowerShell.Commands.Diagnostics.ni.dll   C:\Windows\assembly\NativeImages_v...
       200 System.Configuration.Install.ni.dll                C:\Windows\assembly\NativeImages_v...
       676 Microsoft.WSMan.Management.ni.dll                  C:\Windows\assembly\NativeImages_v...
       916 System.Transactions.ni.dll                         C:\Windows\assembly\NativeImages_v...
       292 System.Transactions.dll                            C:\Windows\assembly\GAC_64\System....
      2136 Microsoft.PowerShell.Commands.Utility.ni.dll       C:\Windows\assembly\NativeImages_v...
      1120 Microsoft.PowerShell.Commands.Management.ni.dll    C:\Windows\assembly\NativeImages_v...
       248 Microsoft.PowerShell.Security.ni.dll               C:\Windows\assembly\NativeImages_v...
      6804 System.Xml.ni.dll                                  C:\Windows\assembly\NativeImages_v...
      1392 System.Management.ni.dll                           C:\Windows\assembly\NativeImages_v...
      1620 System.DirectoryServices.ni.dll                    C:\Windows\assembly\NativeImages_v...
      1552 mscorjit.dll                                       C:\Windows\Microsoft.NET\Framework...
      8508 System.Data.ni.dll                                 C:\Windows\assembly\NativeImages_v...
      3080 System.Data.dll                                    C:\Windows\assembly\GAC_64\System....
       792 diasymreader.dll                                   C:\Windows\Microsoft.NET\Framework...


PS C:\>

MJ, that is enough for one day. The Scripting Wife says we are approaching St. Augustine, Florida. I remember there are some decent restaurants here and some cool shops as well. I think we will pull off for a bit. Exploring .NET Framework week will continue tomorrow when I will continue talking about the System.Diagnostics.Process .NET Framework class.

I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson, Microsoft Scripting Guy