Summary: Two Microsoft PFEs discuss the basics of .NET Framework language elements as they relate to Windows PowerShell with examples from Active Directory.
Microsoft Scripting Guy, Ed Wilson, is here. Today is part 2 of a 5-part series written by guest blogger Adam Haynes with some help from his friend Shubert Somer. You can read about them and part 1 in yesterday’s Hey, Scripting Guy! Blog post.
Take it away, Adam …
Welcome back. In this post I would like to introduce a developer PFE friend of mine, Shubert Somer. Shubert helped me understand what all of the gibberish on our MSDN site meant and how to use it with Windows PowerShell. Let’s look closer at the class, object, method, constructor, property, and member topics a little closer.
Shubert: Thanks, Adam. While you don’t need to be a hard-core object-oriented programming (OOP) developer to get the most out of Windows PowerShell, as Adam has pointed out, PowerShell is object oriented, and you do want to be comfortable with the concepts.
Let’s look a little more closely at what classes are, really, and why we want to use them. In a nutshell, a class is a way to collect related functionality together and isolate it from other collections of related functionality. You may see the term encapsulation used to describe this aspect of OOP. The Windows PowerShell scripter encapsulation is probably the most important feature of OOP, so let’s give a little historical perspective to show just why it is so important and useful.
I think we’re all familiar with things like variables to hold data and functions to perform a set of actions. These are a pretty natural parallel to class properties and methods. Back in the pre-OOP days everything was pretty much global—you would have a big code file and every function would be visible from anywhere. So, if your code needed to open a window to display some data, and also needed to open a file to read some data, you would need an “OpenWindow()” function and an “OpenFile()” function. After a while, the code would get very cluttered because you would need to put some kind of description in the function name—both to tell what kind of stuff it was for and also to keep the name unique. In fact, this is something you might eventually find happening in your own Windows PowerShell scripts as they get larger and more complex.
The idea of OOP is that you can take all of the functionality related to say, window management, and collect it into a single container: a class. Then all of the functions and variables related to that class become children of the container and can be referenced more cleanly. Now that old “OpenWindow()” function becomes Window.Open() and OpenFile() becomes File.Open(). These child variables and functions are collectively known as the class members, and for formalistic reasons, we call the exposed variables properties and the exposed functions methods.
Adam: Ok, that makes sense to me. So we can get the information from our data source, like a file in your example, and then just pass that to the Window Class. I personally don’t care about how the window works; I just want one on the screen with my information in it.
Shubert: That’s it. The takeaway concept is that these containers, these classes, internally define all of the interesting stuff that the objects created from them can do. This makes them exceptionally modular and reusable. It also enables things like IntelliSense in Visual Studio and the Windows PowerShell Get-Member cmdlet to return a list of exactly that stuff for a given class.
One common point of confusion is the difference between an object and a class. As you can see from our earlier definition, a class is often referred to as the abstract definition, blueprint, or template, for an object. So while the class has all the same properties and methods as the objects created from it, the class really cannot do anything. First, you need to use it to create an object.
What does that mean? Essentially, the object needs to be set up as an actual thing in the system or be what we call instantiated. In other words, some system memory has to be reserved to hold any data, perhaps some values need to populated or connections to other services set up, etc. All of this takes place in a special method called the constructor. By convention, this method name is simply the name of the class itself.
Adam: Now that makes perfect sense. I was looking at DirectoryContext Class on the MSDN website, and I was trying to understand why I could access methods and properties of objects with the “.”, but not constructors. I guess I can’t use an actual window to make another window.
Shubert: Exactly. Because constructors are a special type of method, they have to be handled a little differently. As we mention in our definitions in the beginning of this blog, the actual “constructing” is done by the .NET Framework, so we need some way to communicate to the system that we want to use the class constructor to create a new object. In Windows PowerShell, this is done by using the New-Object cmdlet, which takes care of all of those system details for you.
Adam: Oh, so now whenever I see that a class in MSDN that has a constructor and I want to use it, I know that I need to use the New-Object cmdlet to call it. But I also noticed that there were four different versions of the constructor. What’s that all about?
Shubert: It’s important to know that there may be many versions of the constructor. This is because you can pass parameters into it and different sets of parameters define different versions of the method (this is called overloading a method). That is why you see four different versions of the constructor. Typically, the differences are just in overriding default or assumed values. Picking the correct one goes back to understanding the technology you are trying to manage, so we will leave that up to you to decide. Below is a snip from the MSDN site for the DirectoryContext Class with an overloaded constructor.
I want to point out, too, that any method can be overloaded as well as constructors. In all these cases, what you will see in MSDN is that each overload of a method gets its own page. This can be quite handy when you are looking for samples or more detailed documentation, as some of the overloads are more documented than others.
So we have covered classes, which define a set of related functionality, and we have objects, which are instantiated by calling the class constructor methods. These new objects are generally assigned to a variable in your code or script, and you can then use them to do cool stuff.
Now, remember that I said that the class itself really can’t do anything and that you have to instantiate an object first and then it is the object that can do things?
Adam: I knew there was a catch.
Shubert: Yes, this is not completely true. Classes can also define properties and methods that are called static, which can be referenced only via the class itself. Behind the scenes there is kind of a special object for any class with static members—you might think of it as the static object—and there will be exactly one per class per instance of PowerShell.exe. It is created before the class is first referenced in your script and stays in the system memory until Windows PowerShell exits. Static members are usually used to define utility code, and they are called using the class name rather than the object name. Most importantly, the static members of a class are always available—you do not need to create an object instance first because the system will have already created the “static object” for you, automagically. We will see some examples in the following posts where we break down the above script line by line and look at a few more topics and examples.
Adam: Before we go, I wanted to mention a side bar that Shubert and I had that helped me move past the MSDN monster. When trying to decide how to present this material, Shubert mentioned that we really should work from the inside-out. What that means is that I knew what I wanted, and once I found what I wanted on MSDN, I could work my way out from there on how to actually get it.
In this specific instance, I knew that I needed the DSASignature attribute and I knew that the DSASignature is part of the replication metadata. If I didn’t know that to begin with, the rest of this wouldn’t be much help. That is why we say that you need to know the object model of the technology you are interacting with.
I started at http://msdn.microsoft.com and searched for “replication metadata.” I found a lot of good information, including some samples to get me going in the right direction. More specifically, I found the DirectoryServer.GetReplicationMetadata Method and started working my way up the navigation tree on the left side of the site. I found the DomainController Class and how to find a domain controller with the DirectoryContext Object. So you often conceptualize the script inside-out, but you will still usually build from top down.
Shubert: Yes, that’s really key. Everything in MSDN will have links to other things in MSDN. Every parameter for a method will have a link to the class of that parameter, and every property will have a link to the class of the property. So start with what you know, and then just keep following the links!
Adam: We are just getting warmed up, so I encourage you to go back and re-read this post to make sure that you are comfortable with these concepts. These are the essential building blocks for the following posts. If things are not 100% clear at this point, that’s ok, too. Now that we have all of the conceptual stuff out of the way, in the next post, we can dig into what this actually means to the script.
Thank you, Adam and Shubert. I love your back and forth discussion. This is great.
Join me tomorrow when Adam and Shubert return with part 3.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy