Hey, Scripting Guy! Question

Hey, Scripting Guy! I would like to be able to use a named parameter when running my scripts. There are a couple of reasons for this. The first is that I think that it looks cool to use a named parameter. The second reason is probably just as important as the first: I think it makes the script easier to use if I use a named parameter rather than needing to rely upon remembering the order of the parameters. How can I do that? In VBScript I created a special object, the WshNamed object, but I tried and that does not work on Windows PowerShell. What am I missing?

- SC

SpacerHey, Scripting Guy! Answer

Hi SC,

What I am missing is my afternoon teaEarl Grey leaves, fresh drawn spring water, a cinnamon stick (Ceylon not cassia), a dribble of milk, and an ANZAC biscuit. Why, you may ask, am I missing my afternoon tea? Well I will tell you: Never make a Scripting Wife mad! Yesterday, she caught me in the pantry getting into her Tim Tams, which are chocolate-covered cookies (“biscuits”) made in Australia. They have chocolate cream in the middle, and the cookie itself is chocolate. If you are keeping count, that is three different types of chocolate! Every once in a while, I will relent and make a pot of fresh Kona coffee.

What do a Tim Tam and cup of coffee have to do with not getting afternoon tea? Well, let me finish. When I was in Brisbane, Australia, one of the students who was attending my VBScript class showed me a trick he called the "exploding Tim Tam." What you do is bite the opposite corners off the Tim Tam, stick it in your coffee, and suck the hot coffee through the Tim Tam as if it were a straw. You have to be really quick because the hot coffee will melt the soft chocolate cream that is in the middle of the cookie (biscuit). If you are not careful or are out of practice, you can end up with a terrible mess in the middle of the kitchen. If you have stolen one of the Scripting Wife's carefully rationed Tim Tams to make this mess, you probably will be missing your afternoon tea. (It is only fair. The ANZAC biscuits are mine, and the Tim Tams are hers. She is of course right, and I should have stayed out of the Tim Tamsor at least asked.)

This banded coral shrimp (Stenopus hispidus) I saw while scuba diving off the coast of Little Cayman did not get any afternoon tea either. Perhaps it too should have stayed out of the Tim Tams.

Image of a banded coral shrimp


Well, CJ, as you have no doubt seen using the $args automatic variable is a quick and easy method to receive input to your script from the command line. As we saw yesterday, this simplicity is not without cost.

The cost is flexibility. While it works great for retrieving single values, it does not work as well when multiple parameters have to be supplied. In addition there is no way to make switched parameters when using the $args automatic variable.

The param statement lets you create named arguments and switched arguments. To use the param statement to create a named argument, you use the param keyword, open a set of parentheses, and specify your parameter name. This is illustrated here.

Param($computer)


To specify a default value for the parameter you use the param keyword, specify the parameter name inside a set of parentheses, and use the equality operator to assign a value. This is shown here:

Param($computer = "localhost")


The param statement must be the first noncommented line in the script. If you try to use the param statement in another position, you will receive two errors. The first is an error from WMI that mentions that the value supplied to the computername parameter of the Get-WmiObject cmdlet is null. The second error that you will receive states that param is not recognized as a cmdlet, function, script file, or operable program. This error is seen here:

Image of error returned when param statement is in wrong position


The Get-BiosParam.ps1 script illustrates using the param keyword to create a named argument, and to assign a default value for the $computer variable. The Get-WmiObject cmdlet uses the WIN32_Bios WMI class to return BIOS information to the display from the computer that was specified in the $Computer variable. This will be either a computer name that was typed when the Get_BiosParam script was run, or the localhost computer.

There are three different ways the computer parameter may be supplied from the command line:

·         Type the entire parameter name.

·         Type a partial parameter name. You must type enough of the parameter name to uniquely identify the parameter.

·         Omit the parameter name and rely upon position.

These three different ways of using the command-line parameters are illustrated here with the Get-BiosParam.ps1 script.

PS C:\> Get-BiosParam.ps1 –computer loopback

SMBIOSBIOSVersion : 7LETB7WW (2.17 )
Manufacturer      : LENOVO
Name              : Ver 1.00PARTTBLx
SerialNumber      : L3L4518
Version           : LENOVO – 2170

PS C:\> Get-BiosParam.ps1 –c loopback

SMBIOSBIOSVersion : 7LETB7WW (2.17 )
Manufacturer      : LENOVO
Name              : Ver 1.00PARTTBLx
SerialNumber      : L3L4518
Version           : LENOVO – 2170

PS C:\> Get-BiosParam.ps1 loopback

SMBIOSBIOSVersion : 7LETB7WW (2.17 )
Manufacturer      : LENOVO
Name              : Ver 1.00PARTTBLx
SerialNumber      : L3L4518
Version           : LENOVO – 2170


The complete Get-BiosParam.ps1 script is shown here.

Get-BiosParam.ps1

Param($computer = "localhost")
Get-WmiObject -Class win32_bios -computername $computer

If you would like to make the parameter mandatory, you need to check for the existence of the variable you used to hold the command-line input. To check for the existence of the variable you can use the –not operator and an if statement:

if(-not($computer) )


If the variable does not exist, it means that a value was never supplied for the parameter. The cool thing we do in the script is use the Read-Host cmdlet to prompt for the missing value. This is a much better experience than raising an error. Here is how we prompt for the missing value:

{ $computer = Read-Host "Please supply computer name" }


After we have the requested value, we proceed to the remainder of the script. The complete PromptForMissingParameter.ps1 script is seen here.

PromptForMissingParameter.ps1


Param($computer )
if(-not($computer) ) { $computer = Read-Host "Please supply computer name" }
Get-WmiObject -Class win32_bios -computername $computer


CJ, you can see that it is easy to use the param statement to request values for parameters from the command line. By using the param statement, you gain a tremendous amount of flexibility when it comes to working with command-line arguments. Join us tomorrow as we continue with Input Week. If you want to keep up with the latest information for the Script Center, follow us on Twitter. You can also join our group on Facebook. If you get stuck with a scripting problem, you can always post a question on the Official Scripting Guys Forum.


Ed Wilson and Craig Liebendorfer, Scripting Guys