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..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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.