Why Use .NET Framework Classes from Within PowerShell?

Doctor Scripto

Summary: Microsoft Scripting Guy, Ed Wilson, talks about the need to use .NET Framework classes from within Windows PowerShell code.

Microsoft Scripting Guy, Ed Wilson, is here. The Scripting Wife and I had a great meeting with the Windows PowerShell Users Group in Charlotte, North Carolina. It was a script club format, so there was no set agenda, nor was there a formal presentation. This provided a great chance to talk to people, find out what they were working on, and in general, have a lot of fun. Speaking of a lot of fun, make sure you check out the first ever Windows PowerShell Saturday that will be held in Columbus Ohio on March 10, 2012. This event, limited to 100 persons, is nearly sold out. So you need to hurry if you want to take advantage of a unique opportunity to network with a great bunch of Windows PowerShell people. The Scripting Wife and I will be there, as will an all-star group of other Windows PowerShell luminaries.

One of the questions I had from a group member was about using the .NET Framework from within Windows PowerShell. I have written quite a bit about using .NET Framework classes from within Windows PowerShell. Those blogs cover working with methods, discovering properties, finding documentation, and other bread-and-butter types of issues.

One of the things that I have not talked much about is why one needs to use .NET Framework classes inside of Windows PowerShell. Keep in mind, that as a best practice, I recommend using a native Windows PowerShell cmdlet when it exists—unless there are compelling reasons for not doing so. For example, I have seen a number of Windows PowerShell scripts (for example, when I was grading the Scripting Games submissions for the last three years), where participants use .NET Framework classes when there is a perfectly good Windows PowerShell option available. Here are two equivalent commands:

[datetime]::now

Get-Date

In the image that follows, I run both commands, and you can see that the output is essentially the same. (That the time indicated is three seconds later is a feature of the fact that for some reason it took me three seconds to run the second command.)

I can use the GetType method to verify that both commands return a System.Datetime object. These two commands are shown here.

PS C:\> ([datetime]::now).gettype()

 

IsPublic IsSerial Name                                     BaseType

——– ——– —-                                     ——–

True     True     DateTime                                 System.ValueType

 

PS C:\> (Get-Date).gettype()

 

IsPublic IsSerial Name                                     BaseType

——– ——– —-                                     ——–

True     True     DateTime                                 System.ValueType

 

PS C:\>

Because both commands return a DateTime .NET Framework class object, there is no advantage to the first command. Some may ask, what does the first command actually do? The command that appears here calls the static DateTime.Now property from the System.DateTime .NET Framework class.

[datetime]::now

The static Now property returns a System.DateTime object that represents the current local date and time—this is the same thing that the Get-Date cmdlet does. The difference? Well, the command Get-Date is much easier to read than [datetime]::now. So why do people use the static Now property? Well, I am convinced there are two reasons.

The first reason, I feel is legitimate: .NET developers may not know that the Get-Date cmdlet exists, and they have learned that to call a static member, they put the class name in square brackets and use the double colon before the member name. As I said, this is completely legitimate. Windows PowerShell is flexible enough, that you can write Windows PowerShell code as if it were C#, VB.NET, or even as if it were VBScript or Perl. Anything that helps you get the job done is fine with me—after all, Windows PowerShell is simply a tool for the vast majority of network administrators.

The second reason is more insidious. I think there are some people who simply want to use .NET Framework classes because they think it is cool, and that it makes the code appear to be more complex. Maybe they are attempting to impress their coworkers or their boss. Maybe they think that if people see things like Get-Date in a Windows PowerShell script, they will realize how easy Windows PowerShell is to use and to learn, and then they will no longer have the mantle as the “PowerShell guru.” I am all for job security, but I prefer to ensure job security by helping others maximize their potential. I prefer to show people how easy it is to use Windows PowerShell to become more productive than to attempt to obscure that fact by deliberately writing confusing code.

What do you think? I would love to hear from you.

Tomorrow I will discuss those occasions when I think it is OK to use .NET Framework code. There are times when it makes perfectly good sense.

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

Ed Wilson, Microsoft Scripting Guy 

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Bernold, Matthew (US - Arlington) 0

    I don’t usually respond to old posts like this, but this article still comes up near the top of search engines when searching for “PowerShell .NET”, and the information in the post leaves out something critical.  I’m relatively new to PowerShell, but have been programming for more than 30 years.  Reading this article got me to wondering if there was any performance difference between the two calls.  My gut told me that the native solution should be the better one, but my results were surprising.
    I ran a quick loop for each of the two solutions, and timed the results:
    $GDStart = Get-DateFor ($i=0;$i -le 99999;$i++) {$r = get-date}$GDEnd = Get-Date$GDElapsed = $GDEnd – $GDStart$DTStart = Get-DateFor ($i=0;$i -le 99999;$i++) {$r = [datetime]::now}$DTEnd = Get-Date$DTElapsed = $DTEnd – $DTStart” Get-Date – $GDElapsed””[datetime]::now – $DTElapsed”
    From the results, it is obvious that the .NET command is significantly more efficient than the cmdlet.
               Get-Date – 00:00:04.7205419[datetime]::now – 00:00:00.1558390
    So, perhaps one good reason for using .NET methods is execution speed?

Feedback usabilla icon