Steven Murawski

SysAdmin, DevOps, PowerShell, and Other Stuff

Filtering by Category: Introduction

Exploring the .NET Framework with PowerShell – Namespaces (Part 5)

One concept that is central to the understanding of the layout of classes in the Base Class Libraries is the Namespace.  Namespaces are a method of providing context for classes (and other constructs like Enums and Structs), allowing developers to group related classes and not worry about name collisions with development in other areas. In the Base Class Libraries, the root namespace is the System namespace.  The System namespace defines a large amount of the base types, like Object (which all classes derive from), String, DateTime, Boolean, and numerous others.  When you specify types, PowerShell can infer the “System” part.

Example:

PS C:\scripts\PowerShell> $random = New-Object –TypeName Random

is the same as

PS C:\scripts\PowerShell> $random = New-Object –TypeName System.Random

Namespaces are hierarchical, except in naming convention. The representation of a file in PowerShell is a great example.  A file object is represented in PowerShell as a System.IO.FileInfo object.  The FileInfo class lives in the System.IO namespace, which is a separate namespace than the System namespace.  There is a hierarchical impression implied, but that is solely through naming convention.

The CLR (Common Language Runtime) does not care about namespaces, only the fully qualified name of the class, so why use namespaces at all?

Namespaces are a convenience for developers, as languages like C# and VB.NET have language constructs that allow the developer to not have to use the fully qualified type name every time that is needed to be referenced.  C# provides the “using” syntax and VB.NET has the “imports” syntax.

How does this apply to PowerShell?

PowerShell does not currently have a “using” or “imports” syntax or language feature, but there are a couple of workarounds.  You can use variables holding the namespace and string concatenation to save some typing

PS C:\scripts\PowerShell> $netinfo = 'System.Net.NetworkInformation' PS C:\scripts\PowerShell> $ping = New-Object "$netinfo.ping" PS C:\scripts\PowerShell> $ping.gettype() IsPublic IsSerial Name           BaseType -------- -------- ----                -------- True     False    Ping            System.ComponentModel.Component

This doesn’t work with type accelerators though (at least in V1)..  V2 CTP3 has some other options and Oisin Grehan has a great discussion on how to find the type accelerators and add your own.

Another option would be to create a function to wrap the creation of objects for particular namespaces.

Use-Namespace is a function I came up with to create a function to wrap New-Object for specific namespaces.

The useage of Use-Namespace is PS C:\scripts\PowerShell>Use-Namespace System.IO, System.Net PS C:\scripts\PowerShell>$memorystream = New-System.IOObject MemoryStream PS C:\scripts\PowerShell>$memorystream.GetType() PS C:\scripts\PowerShell> $memorystream.gettype() IsPublic IsSerial  Name                    BaseType -------- --------   ----                         -------- True     True     MemoryStream      System.IO.Stream

And the function is here..

function Use-Namespace()
{
  param ([string[]]$Namespace)
  BEGIN
  {
    if ($Namespace.length -gt 0)
    {
      $Namespace | Use-Namespace
    }
  }
  PROCESS
  {
    if ($_ -ne $null)
    {
      $NS = $_
      $NSObject = "$NS" + "Object"
      $function = @"
param (`$Class, [string[]]`$ArgumentList)
if (`$ArgumentList.length -gt 0)
{
return New-Object -TypeName "$NS.`$Class" -ArgumentList `$ArgumentList
}
else
{
return New-Object -TypeName "$NS.`$Class"
}
"@
    Set-Item -Path "function:global:New-$NSObject" -Value $function -force
    Write-Debug "Created function:global:New-$NSObject "
    }
  }
}

PSMDTAG:FAQ CLR PSMDTAG:FAQ Namespace PSMDTAG:FAQ .NET Framework

Exploring the .NET Framework with PowerShell – Static Members (Part 4)

In our Exploring the .NET Framework series, we’ve covered some terminology, creating instances of objects and calling methods.  In today’s installment, we are going to look at using static members - methods and properties.  Static methods are methods that a class (or type) make available without needing to create an instance of the class.  Similarly, static properties are properties that you can access without needing an instance of the class. Many classes provide static members supply functionality where it doesn’t make sense to need an object. 

The System.Math class contains a couple of static properties, PI and E. 

PS C:\scripts\PowerShell> [math]::E 2.71828182845905 PS C:\scripts\PowerShell> [math]::PI 3.14159265358979

Constant values are not the only type of property that you’ll find.  The System.AppDomain class has a static property, CurrentDomain, which is an AppDomain instance referring to the current application domain.

PS C:\scripts\PowerShell> [AppDomain]::CurrentDomain.gettype()

IsPublic  IsSerial Name         BaseType --------    --------    ----            -------- True     False    AppDomain System.MarshalByRefObject

System.Math also contains a number of static methods that provide a great deal of basic mathematical function.

PS C:\scripts\PowerShell>[Math] | get-member –static –membertype method | select name

Name ---- Abs Acos Asin Atan Atan2 BigMul Ceiling Cos Cosh DivRem Equals Exp Floor IEEERemainder Log Log10 Max Min Pow ReferenceEquals Round Sign Sin Sinh Sqrt Tan Tanh Truncate

I wrote a little helper function to get the static method definitions (Get-StaticMethodDefinition), which you can grab from PoshCode.org.

(V2 CTP3 - We can use the trick of using the method name without parenthesis following to get additional information on each of the methods that we are interested in.)

One type of static method that I would like to highlight is the factory method.  A factory method is a common way of controlling object creation.  At its most basic level, a factory pattern is a method that creates objects of a specified type. 

An example of this is the System.Net.WebRequest’s Create method.

PS C:\scripts\PowerShell> $web = [net.webrequest]::create('http://www.google.com') PS C:\scripts\PowerShell> $web.gettype()

IsPublic IsSerial Name                                     BaseType -------- -------- ----                                     -------- True     True     HttpWebRequest                           System.Net.WebReq...

The factory method Create used the argument (‘http://www.google.com’) to determine the type of WebRequest object to create.  In this case, it created an HttpWebRequest object, which is a more specialized version of the WebRequest for HTTP requests. 

Let’s see how it would respond if we passed the Create method a URI with FTP.

PS C:\scripts\PowerShell> $web = [net.webrequest]::create('ftp://ftp.google.com') PS C:\scripts\PowerShell> $web.gettype()

IsPublic IsSerial Name                                     BaseType -------- -------- ----                                     -------- True     False    FtpWebRequest                            System.Net.WebReq...

As we can see, the WebRequest class created an FtpWebRequest object.

Factory methods provide developers a way to more flexibly support different operations by allowing the static method to determine which object to return.

UPDATE:  Joel "Jaykul" Bennet added a V2 advanced function to convert static methods to functions to PoShCode.org  and pointed out Oisin Grehan's blog post about creating functions from static methods (V1 compatible).

I’ve been really happy to receive some of the feedback (positive and constructive criticism) on this series.  There is a lot of the .NET Framework to cover, and I’m open to suggestions as to what you would like to know.  Please post a comment on the blog or email me at Steve at UsePowerShell.Com.

Exploring the .NET Framework with PowerShell – Constructors (Part 3)

In part 2(a & b) of this series, we talked about methods and looked at ways to view their overloads, or ways to call them.  We also looked at the objects returned from a method call.  In this post, we are going to explore a special kind of method called the constructor.

A constructor is a method whose job is to create the object that you want to work with.  When I created the Ping object

PS C:\scripts\PowerShell> $ping = New-Object System.Net.NetworkInformation.Ping

the New-Object cmdlet calls the constructor for Ping.

Like other methods, constructors can require parameters and can have multiple overloads. 

Let’s look at System.Net.Mail.MailMessage, which is a object that represents an email message.

The MailMessage constructor contains several overloads.  The first method listed is MailMessage(), which is the default constructor.  This method does not require any arguments and returns an empty MailMessage object.  In PowerShell, we would call this method via New-Object, just like with Ping class.

MailMessage()

PS C:\scripts\PowerShell> $message = New-Object System.Net.Mail.MailMessage

The first overload requires two MailAddress objects, the first of which is the “from” address and the second is the “to” address. 

MailMessage(
        MailAddress from,
        MailAddress to,
)

Creating an object in PowerShell from a constructor that requires parameters can be done in two ways.  The first is to use the method call notation.

PS C:\scripts\PowerShell> $message = New-Object System.Net.Mail.MailMessage($MailFrom, $MailTo)

The second is to use the ArgumentList parameter.

PS C:\scripts\PowerShell> $message = New-Object System.Net.Mail.MailMessage –ArgumentList $MailFrom, $MailTo

If you happen to have MailAddress objects floating around, this might work for you.  A more common scenario would be to use the next overload, which takes two strings.

MailMessage(
        String from,
        String to,
)

This overload requires two strings, one for the “to” and one for the “from” address. 

The final overload for MailMessage is

MailMessage(
        String from,
        String to,
        String subject,
        String body,
)

This overload allows you to pass in four strings and get back basic MailMessage object that is ready to be sent.

Wouldn’t it be great to have a function, where we could provide a type name and get a listing of all the constructors, right from the command line (not needing to go to the MSDN documentation every time).  Jeffrey Snover has beaten me to the punch and provided a function to find the constructors, appropriately called Get-Constructor.  Add that function to the your toolbox, and exploring the .NET Framework becomes a lot easier.

Next up, we’ll look at static methods.  Static methods are methods that can be called without having to create a instance of an object.

One particular type of static method that we’ll dig in to is the factory method, which is another way to create instances of objects.

Exploring the .NET Framework with PowerShell – Calling a Method (Part 2b)

Continuing from where I left off last week, we were created an instance of the System.Net.NetworkInformation.Ping class and looked at the different ways (overloads) that we can call the Send method.  Now that we’ve seen how we can create Ping objects, let’s take advantage of options for creating some custom ping packets and examine the return object.

PS C:\> $encoder = new-object System.Text.ASCIIEncoding

PS C:\> $bytes = $encoder.Getbytes('Hello From Steve')

PS C:\> $response = $ping.Send('google.com', 100, $bytes)

Let’s take a look at the response we get back.

PS C:\> $response | Get-Member

   TypeName: System.Net.NetworkInformation.PingReply

Name                  MemberType     Definition
----                       ----------     ----------
Equals                  Method         System.Boolean Equals(Object obj)
GetHashCode        Method         System.Int32 GetHashCode()
GetType               Method         System.Type GetType()
get_Address          Method         System.Net.IPAddress get_Address()
get_Buffer            Method         System.Byte[] get_Buffer()
get_Options          Method         System.Net.NetworkInformation.PingOptions...
get_RoundtripTime Method         System.Int64 get_RoundtripTime()
get_Status            Method         System.Net.NetworkInformation.IPStatus ge...
ToString               Method         System.String ToString()
Address                Property       System.Net.IPAddress Address {get;}
Buffer                  Property       System.Byte[] Buffer {get;}
Options                Property       System.Net.NetworkInformation.PingOptions...
RoundtripTime       Property       System.Int64 RoundtripTime {get;}
Status                  Property       System.Net.NetworkInformation.IPStatus St...
BufferSize             ScriptProperty System.Object BufferSize {get=$this.Buffe...
OptionsString        ScriptProperty System.Object OptionsString {get='TTL={0}...

Get-Member shows us that this is a PingReply object in the System.Net.NetworkInformation namespace.

Looking at the PingReply object that was returned, we have several methods that look strangely similar to the properties, but with a “get_” prefixed to it.  When you see a method that matches a Property, but has “get_” or “set_”, that is a method exposed by the .NET Framework that provides the functionality for the properties.  When you access the Buffer property, you are actually calling the get_Buffer method.  Properties are, for the most part, easier to work with and you can effectively ignore those methods.  Properties also contain a clue in their description, if you look at the end of the Buffer property’s description, you see “{get;}” which indicates that there is a way to retrieve that property.  Properties can also show “{set;}” which indicates that you can update that property.

In PowerShell V2 CTP3 those “getters” and “setters” (as those methods are commonly called) are hidden by default.  If you are running CTP3 and want to see the “getters” and “setters”, you can call Get-Member with the Force parameter.

PS C:\> $response | Get-Member –Force

Back to the properties of our return object.  The properties names are pretty self-explanatory, but to confirm we got back the “special” packet we crafted, let’s take a look at the Buffer property and convert that back to text.

PS C:\> $encoder.GetString($response.buffer)
Hello From Steve

Now for the meat of the response, the RoundtripTime and Status.  I commonly use the Roundtrip time to watch for latency on my network, and since it is exposed so nicely, it is easy to log.

PS C:\> $response.RoundtripTime
74

And of course, we are interested in the Status.

PS C:\> $response.Status
Success

Now, we can see from the Get-Member return above, that Status is not just a string that says, “Success”, it is a IPStatus enumeration (more on enumerations coming up, but long story short, there are a number of predefined values that an IPStatus object can hold)(also found in the System.Net.NetworkInformation namespace). 

I’m normally checking the IPStatus for a Success value like

PS C:\> $success = [System.Net.NetworkInformation.IPStatus]::Success

PS C:\> $response.status -eq $success
True

I could compare the string results, but then I’m stepping back to parsing text results.  By using the IPStatus enumeration values, I can get be reasonably sure that my value are correct and I don’t have any text matching issues.

In the next post in this series, we’ll take a look at a special type of method, the constructor.

Exploring the .NET Framework with PowerShell – Calling a Method (Part 2a)

Last week, I defined a number of terms that we’ll be exposed to as we delve into how and why PowerShell is an object oriented shell and how to use it to explore .NET Framework which it is built upon. Now, let’s take a look at how some of these terms surface themselves in PowerShell.

One of the most common tasks you might encounter is needing to ping a computer.  There is ping.exe, which works and has been a common guest in my console sessions for years.  You can also get ping information via WMI which provides you with some interesting information.

PS C:\scripts\PowerShell> Get-WmiObject Win32_PingStatus -filter "Address='google.com'"

My preference is to use a class from the .NET Framework called PingPing lives in the System.Net.NetworkInformation namespace.

To access this in PowerShell, I’ll create an instance of the class and refer to it with a variable, $ping.

PS C:\scripts\PowerShell> $ping = New-Object System.Net.NetworkInformation.Ping

By typing the method name without the parenthesis immediately after it, PowerShell will give us information about the method.

PS C:\scripts\PowerShell> $ping.send

MemberType          : Method OverloadDefinitions : {System.Net.NetworkInformation.PingReply Send(String ho                       stNameOrAddress), System.Net.NetworkInformation.PingRep                       ly Send(String hostNameOrAddress, Int32 timeout), Syste                       m.Net.NetworkInformation.PingReply Send(IPAddress addre                       ss), System.Net.NetworkInformation.PingReply Send(IPAdd                       ress address, Int32 timeout)...} TypeNameOfValue     : System.Management.Automation.PSMethod Value               : System.Net.NetworkInformation.PingReply Send(String hos                       tNameOrAddress), System.Net.NetworkInformation.PingRepl                       y Send(String hostNameOrAddress, Int32 timeout), System                       .Net.NetworkInformation.PingReply Send(IPAddress addres                       s), System.Net.NetworkInformation.PingReply Send(IPAddr                       ess address, Int32 timeout), System.Net.NetworkInformat                       ion.PingReply Send(String hostNameOrAddress, Int32 time                       out, Byte[] buffer), System.Net.NetworkInformation.Ping                       Reply Send(IPAddress address, Int32 timeout, Byte[] buf                       fer), System.Net.NetworkInformation.PingReply Send(Stri                       ng hostNameOrAddress, Int32 timeout, Byte[] buffer, Pin                       gOptions options), System.Net.NetworkInformation.PingRe                       ply Send(IPAddress address, Int32 timeout, Byte[] buffe                       r, PingOptions options) Name                : Send IsInstance          : True

What I am most interested in is the Overload Definitions, which is the explanation of how I can use this method.

PS C:\scripts\PowerShell> $ping.send.overloaddefinitions

System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress) System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress, Int32 timeout) System.Net.NetworkInformation.PingReply Send(IPAddress address) System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout) System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress, Int32 timeout, Byte[] buffer) System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout, Byte[] buffer) System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress, Int32 timeout, Byte[] buffer, PingOptions options) System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout, Byte[] buffer, PingOptions options)

As we can see from the above output $ping.Send has several different ways that we can call it and it also shows the object that we will get in return, an object of the type System.Net.NetworkInformation.PingReply.

The first overload for $ping.Send is to supply it an object of the type String (remember, in PowerShell, even text is an object) which represents the hostname or IP address of the host we wish to ping.

PS C:\scripts\PowerShell> $ping.send(‘google.com’)

Status        : Success Address       : 74.125.45.100 RoundtripTime : 29 ms BufferSize    : 32 Options       : TTL=243, DontFragment=False

Here, we called $ping.Send with a argument of the String ‘google.com’ and received back an object of the type PingReply.  We can see the textual representation of it’s properties.  In my next post, we’ll dig into the return object a bit more and see how we can use its properties to our advantage.

We still have a number of other ways that we can call $ping.Send.  Our second option is to provide a String describing the hostname or IP address (as before), but also allows us to specify a timeout by providing an Int32.  (Just a quick note, if you specify a really low timeout value, the reply still may be received.  It is more of an option to provide a longer than normal, five seconds, timeout period.)

We also see overloads that take an object of the IPAddress type to describe the target of the Ping.

Now, things get a bit more interesting.  The next argument we see is of the type Byte[], which means an Array of Byte objects.  The quick explanation of an Array is a collection of objects (not 100 percent accurate, but sufficient for right now).  This allows us to specify exactly what data will be sent with the ICMP echo message.

The final argument is to supply an object of the PingOptions type.  This allows us to specify an Int32 as the TTL (Time To Live) and a Boolean as Don’t Fragment option.

I’m starting to run a bit long here, so I’m going to continue walking through this example in my next post.  We’ll create an object of type Ping with some custom options and then dig in to the object that is returned.