PowerShell Pipeline
Using .NET Members in PowerShell
Even with limited technical know-how, you too can work with .NET classes.
Several of my articles here have made use of paths that are just not available in PowerShell as a cmdlet. While PowerShell is indeed powerful in itself, there are just some things that you cannot do natively in PowerShell just using the cmdlets that are available. Bear in mind that I am not talking about the community driven functions and modules which are available (some of these are building on top of .NET classes, which is what I am discussing here).
In today's article, I will show you how to approach using .NET classes to build out an object as well as using methods in the objects to perform an action that would normally not be available. I promise that nothing advanced will be happening here as I want to show you how easy it can be! Anyone here can make use of .NET and not be a developer in PowerShell. In fact, you are probably using it right now and not even aware of it!
An easy example of using a static method within a .NET class is with System.Math class and using the method Sqrt to determine the square root of a number.
[System.Math]::Sqrt(36)
In this case, I am simply calling a static method of a class to do something that I normally couldn't do in PowerShell natively. Of course, I could write a function that uses this approach and then we would have something that is reusable and doesn't show anything .NET related to a user that is making use of the function.
So what is a class you ask? I mean, we already mentioned and use it, but that doesn't really explain what one is. A class is basically an object which can contain various members such as properties, methods and events. We see them every day in PowerShell whether in the objects that we return or when we use methods from an object. Run Get-Member against an object and you can see this for yourself.
Get-Date | Get-Member
A property is a piece of data, whether it is a string, integer or another object while a method can be described as a set of instructions that are run with or without parameter (just like how we use a function in PowerShell). The difference is that these can be overloaded, meaning that we only need one method and it can support a different set of parameters and knows how to handle them. For instance, look at [System.IO.File] with the ReadAllText method. Here we see that it is overloaded with two possible approaches to using the method.
[System.IO.File]::ReadAllText
We can either just supply the full path to the file or also include the encoding of the string text with the full path. As long as we follow this approach, we will not receive any errors. If we stray outside of the number of parameters or do not use the proper object type that is required, we will run into issues.
A constructor is used along with New-Object to actually build a class with some values already defined. A class might have multiple constructors in it to allow for various approaches to building out the class object.
So how can we determine what kind of constructors are available? Well, we can look up the class on the MSDN site and see the possible constructors, such as this link for looking at the Net.Sockets.TCPClient class.
Here we can see that there are four possible constructors for this class. The first constructor is that it doesn't take any parameters at all and is called the default constructor.
Another possible approach with the constructor is that you can give it a string hostname as well as an integer for the port.
Order and parameter type is very important (just like with the methods) otherwise the constructor will throw an error if not properly used.
A couple of other approaches to finding out what the constructors are for a class are using more .NET to determine this. This can be a little overwhelming to someone just coming into using .NET, so I have a function available here which can help you out called Get-Constructor.
You can then easily use this function to help find the available constructors.
Get-Constructor -Type Net.Sockets.TCPClient
The empty spot denotes that you can build an object without any parameters.
If you are running PowerShell V5, then you are in luck! There is a built-in method applied to all of the classes called New() which is used to build an object vs. using New-Object. What you may not know is that if you do not supply the parenthesis, it will actually display all of the available constructors.
As mentioned, we can use New() to create the object just like we did using New-Object.
We can bring this all together by creating an object using a constructor and then making use of one of the methods to perform an action. For this example, I will make use of the System.DateTime class to create a class and then make use of the method available in the class.
#Create the object using a constructor with a Year, Month and Day parameter
$DateTime = New-Object System.DateTime -ArgumentList 2015, 10, 10
#Display the object
$DateTime
#View all of the properties
$DateTime | Select-Object -Property *
#Use a method to convert the DateTime to a FileTime type
$DateTime.ToFileTime()
#Add seven days to the currently defined Date
$DateTime.AddDays(7
We have now taken our first step into working with .NET classes as well as covering the creation of a .NET object using a constructor as well as using the methods which are available to us, whether a static method or a method that exists on an instantiated object. We can now use this to create new functions that wrap around this that are now reusable and will help to add to your library of commands!
About the Author
Boe Prox is a Microsoft MVP in Windows PowerShell and a Senior Windows System Administrator. He has worked in the IT field since 2003, and he supports a variety of different platforms. He is a contributing author in PowerShell Deep Dives with chapters about WSUS and TCP communication. He is a moderator on the Hey, Scripting Guy! forum, and he has been a judge for the Scripting Games. He has presented talks on the topics of WSUS and PowerShell as well as runspaces to PowerShell user groups. He is an Honorary Scripting Guy, and he has submitted a number of posts as a to Microsoft's Hey, Scripting Guy! He also has a number of open source projects available on Codeplex and GitHub. His personal blog is at http://learn-powershell.net.