Summary: Ed Wilson, Microsoft Scripting Guy, talks about Windows PowerShell scripting terminology.
Hey, Scripting Guy! So I am confused, and I am not afraid to admit that I am confused. In the old fashioned VBScript days, I wrote scripts. I could also write subroutines or functions. And that was about it. Pretty simple, and it made sense to me.
But with Windows PowerShell, it seems that there is so much more, and I do not even know where to begin. Not to mention that I have not seen a single reference about how to create a subroutine in Windows PowerShell. What gives? Can you throw me a bone?
Microsoft Scripting Guy, Ed Wilson, is here. I am looking out of the window from my office, and I see a big, green, grassy park. It is where people bring their dogs to walk, frolick, and catch Frisbees and other flying things. I imagine there are also a few who are throwing bones (or maybe rawhide bones) to their animals.
JT, I really don’t believe in throwing things, even bones, at people, but I can understand your confusion, and I will talk about the different scripting elements today.
So, there is the script. There is also the command line. There are the function and the advanced function, and there is the module. Knowing when to use each, in addition to the best way to use each, is a fundamental aspect of learning Windows PowerShell.
The script is a basic unit in Windows PowerShell. I like to think of scripts in several ways. The first way is as an inline script. This is basically a series of Windows PowerShell commands that are interpreted sequentially. The script starts at the top and works its way down, line-by-line, until it reaches the end of the script. Usually, these are short (less than twenty lines, with 10 – 12 lines being typical).
I write these sorts of scripts as a kind of advanced Windows PowerShell command, and usually they are one-off creations. They do nothing I could not have typed from the Windows PowerShell console, but because it is a bit longer than a one-liner, it is easier to keep track of what is going on by putting the commands into a script. What I call the inline script, does not take advantage of any advanced scripting features of Windows PowerShell (no functions, advanced functions, or modules).
When the script grows beyond the level of the inline script, I begin to group related commands into a function. A well-designed function has one way in and one way out, and it performs a single activity. At least, that is the way I like to write and design my functions.
Oh yeah, a well-designed function also returns an object. By having one way in and one way out, and by performing a single activity, it makes it easy to troubleshoot the function. It also makes it easy to reuse the function in another script, or to place it into a module.
A script can contain a function or more than one function. In fact, when my script begins to grow in length and complexity, I move related commands into a function. Sometimes, it means that I need to add a level of abstraction to my script, and often this requires a bit of thought.
So whereas my straight-line, quick script may have hard-coded paths, and string literals in it, I need to abstract all of these literal values into variables when I move them into the function. I need to begin to think about where those variables will be used: either only in the function, or in the script, or even outside the script.
The advanced function
The advanced function is a function that behaves like a Windows PowerShell cmdlet. In fact, the name for advanced functions, during the beta program was Script Cmdlet, and I actually liked that name because it was more descriptive.
The advanced function replicates the capability of a Windows PowerShell cmdlet, but instead of having to write in a higher language (like C#), we can write it in a Windows PowerShell script. An advanced function can duplicate the behavior of a cmdlet in that it can use the –WhatIf, –Verbose, –Confirm, and other common parameters that Windows PowerShell cmdlets support.
An advanced function can tie in with the Windows PowerShell Help system, so I can get help about the advanced function in the same way that I get help about other Windows PowerShell cmdlets.
The module is the logical place to store a collection of related advanced Windows PowerShell functions. I can import a module into my script, and then I automatically have access to all of the functions stored in the module.
As an example, I created a module that contained a series of advanced functions that were designed to work with local user accounts. I had functions to create a new local user, add the local user to a local group, change the local user's password, and so on.
Because these tasks were all related to things I would do to local user accounts, I stored them all in a single module. But I did not write all of these advanced functions at one time, so I added to the module over time as the needs came up. Each time I added something, I created a new version of the module.
I also store my Windows PowerShell profile in a module. The profile is simply a Windows PowerShell script that is stored in a specific location, and it has a specific name. The first thing my Windows PowerShell profile does is import my profile module. Then on subsequent lines in my profile, it calls various functions from my profile module to configure things in my Windows PowerShell environment (such as my Windows PowerShell prompt—the prompt itself is simply a function).
JT, that is all there is to understanding Windows PowerShell scripting terminology. To Script or Not to Script Week will continue tomorrow when I will talk about best practices for using different scripting techniques.
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