Summary: Ed Wilson, Microsoft Scripting Guy, talks about basic design considerations for Windows PowerShell functions.
Hey, Scripting Guy! I keep hearing about functions, but I really do not know what they are, how to create one, or even how to use one. Can you help me with this? I am not a programmer, but it seems likely that you guys are trying to force me to become one. Help!
—DS
Hello DS,
Microsoft Scripting Guy, Ed Wilson, is here. It is another beautiful day here in Central Florida. I am sipping a nice cup of Djareerling tea, with a bit of orange blossom local honey, and munching on a honeydew melon that came from a farm less than 20 miles from here. Way cool. Oh, yeah, I am also listening to Dire Straits on my Zune. They are playing “Money for Nothing” right now.
DS, using Windows PowerShell is a lot like getting your money for nothing and your checks for free...as the song goes. Why? Because when you learn Windows PowerShell, it is remarkably powerful, and it really is easy to create a script that will accomplish a lot of useful stuff in a very short period of time.
When I say "learn Windows PowerShell," I do not mean learn everything about it. Instead, there is a basic level of knowledge that you need to know, and then what you can do with it can build very quickly. For example, several of my guest bloggers teach a Windows PowerShell class for Microsoft Premier customers. This class is four days long, and at the end, the customers walk away able to accomplish incredible things.
If a class is not to your liking, you can go through my book, Windows PowerShell Step by Step, in less than a week. At the end, you have a really good grasp of what is possible with Windows PowerShell. So in less than forty hours, you can go from zero knowledge to being the hero scripting guy at your company. Then as Dire Straits said it, it will seem like you are getting your money for nothing and your checks for free.
Functions
Functions are a basic building block of a Windows PowerShell script or module. I use functions for several reasons:
- Reusability
I can reuse the code I have written. This really is getting a lot of bang for your buck, so to speak. I can write once, and reuse the code many times. - Readability
If I can read a script, I can understand what the script is doing. This, in turn, makes it easier to troubleshoot and modify it at a later date. Readability is the key, and it will vastly simplify (or even eliminate) many troubleshooting situations. I very seldom need to use a debugger on my scripts, and the only times I really need to do so is when a script is so long and complicated that I cannot follow the flow of the argument. Good organization promotes readability, and that simplifies troubleshooting. - Flexibility
A script with hard-coded values must be edited prior to reuse for an additional purpose. By abstracting tasks into functions, you add flexibility to the script and makes it easier to use for other purposes. - Simplicity
A well-crafted function will simplify the flow of a script, and make it easier to write. Indeed, it can even make the script shorter by encapsulating code that may be required more than once.
A basic function
To create a function, I begin with the Function keyword. Then I need to give it a name. I like to use Verb-Noun combinations like Windows PowerShell cmdlets. This will simplify things when I decide to move my function into an advanced function. In fact, I always make sure that I use an approved verb—one that is specified in Windows PowerShell as permissible to use. I can, of course, make up any verb I wish. It is my script after all.
But if I put the unapproved verb named function in a module, a warning message appears when I load the module. That can prompt calls from users who see the warning and they wonder what is going on (kind of like the SQL module contains unapproved verbs in it, and that always prompts questions from people when I do demonstrations).
Finding an approved verb is easy: I use the Get-Verb cmdlet:
PS C:\> Get-Verb
Verb Group
---- -----
Add Common
Clear Common
Close Common
Copy Common
Enter Common
Exit Common
If I want to create a function to add a local user to a local group, I may name it Add-LocalUserToLocalGroup—or not, but you get the idea. In addition, it is good that the noun is descriptive. There is no doubt at all what Add-LocalUserToLocalGroup does. I can then create an alias for the long function name—maybe alug (for Add Local User Group), which will make it easy to remember.
After the Function keyword and the function name, I create input parameters, and then I add the code. Here is an example:
function Add-TwoNumbers
{
Param ([int]$a,
[int]$b)
$a + $b
}
To use the function, I need to “load” it into memory. In the Windows PowerShell ISE, this simply means that I run the script that contains the function. I can then go to the immediate console window and call the function by name like I would do with a Windows PowerShell cmdlet. Indeed, tab expansion works, as does IntelliSense. When I have done this and press ENTER, and the function runs and returns my output:
DS, now you know the basics about using functions. To Script or Not to Script Week will continue tomorrow when I will talk about advanced functions.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy