June 7th, 2011

Work with Legacy Exit Codes in PowerShell

Summary: Microsoft Windows PowerShell MVP, Sean Kearney, talks about working with legacy exit codes in Windows PowerShell. Microsoft Scripting Guy, Ed Wilson, here. This week we will have one guest blogger for the entire week. Sean Kearney has written a series of blog posts about Windows PowerShell and the Legacy. I am not going to be redundant by reposting his biography each and every day.

Integrating Windows PowerShell with Legacy Environments–Part 2

Note: This is part two of a five part series about interacting with legacy environments. Part one talked about retrieving exit codes. We return to the classroom. When last time we met out heroes, the Scripting Guy was dealing with a student who was a slightly over eager to learn what Windows PowerShell could do with VBScript scripts and console applications. Our fidgety little fellow was bouncing up and down like a gerbil that ate an entire bag of sugar. “Exit codes! Exit codes! They can pass exit codes back-and-forth and forth-and-back to each other! Woo woo woo woo woo!” The little fellow was bouncing out of control. He leapt into the air almost knocking other students down. The Scripting Guy passed a hand in the air waving a Universal Remote Control, and casually pressed the Pause button, which stopped our little friend (or fiend) in mid-leap. Casually, the Scripting Guy moved him to the chair, attached a seatbelt, and then stepped away from him. “Now if I may continue…” the Scripting Guy said calmly. “The fact Windows PowerShell, VBScript scripts, and console applications can return exit codes to each other is just the beginning of our journey. Would it interest you, O curious one, that we can also pass parameters to Windows PowerShell from these older systems?” At this point, our fine little human ball of energy looked up with eyes as large as cue balls. “What? WHAT? Tell me!” he shouted, quickly bursting out of his seat belt and bowing profusely to the Scripting Guy. “Be seated and watch this content. You can save the bowing for the end of the lesson, there’s more…” The Scripting Guy continued by presenting his next line:

GET-CONTENT C:PowershellLegacy2.txt | more

Being told that applications can receive exit codes back-and-forth is one thing. Sending data to them is entirely another matter. Or is it? We already know that if we drop parameters at the end of a console application, it can parse them within. Is it so inconceivable that if we duplicate the process when we call Powershell.exe, it would not work? The fact is, it will. Simply running a line from the console application (or as a scheduled task) to call the Windows PowerShell script, POSHSCRIPT.PS1, will execute the script with the parameters 6/9/2011 and SnoopyDance. This code example is shown here.

Powershell.exe –file POSHSCRIPT.PS1 –executionpolicy RemoteSigned 6/9/2011 SnoopyDance 42.4242

But there’s something we should be aware of—they are going to be received as strings. Why strings? Well, the console world only really sends and receives text. It has no clue what an object is or isn’t, nor does it really care. This does not mean that we cannot work with it, just that we should be aware of how Windows PowerShell will receive it. So our Windows PowerShell script, POSHSCRIPT.PS1, would have simply received two strings in our default variable of $Args. (This is the default array that parameters go into if you don’t define actual names and a variable to receive them.) So if POSHSCRIPT.PS1 looked as follows on this inside, it would show $Args[0] to be a string with length.

$ARGS[0] | GET-MEMBER

$ARGS[0]

$ARGS[1] | GET-MEMBER

$ARGS[1]

$ARGS[2] | GET-MEMBER

$ARGS[2]

It would also echo the output to the screen, and the other two parameters would also be strings. But if we want to ensure that the first parameter was to always be treated as a date file in that script, we could force it that way. A simple example of this would be to store the first parameter as a value called $MyFirstDateField as shown here.

$MYFIRSTDATEFIELD=$args[0]

To make this assume that the content should always appear as DateTime, we force the value of $MyFirstDateField as a [DateTime] type as shown here.

[DATETIME]$MYFIRSTDATEFIELD=$args[0]

We could do the same thing to the third variable, and ensure that it is always treated as a decimal by making it assume [Double]. An example of this script would look like this:

[DATETIME]$MYFIRSTDATEFIELD=$args[0]

$MYFIRSTDATEFIELD | GET-MEMBER

$MYFIRSTDATEFIELD

$MYSECONDSTRINGTHING=$args[1]

$MYSECONDSTRINGTHING | GET-MEMBER

$MYSECONDSTRINGTHING

[DOUBLE]$MYULTIMATEANSWER=$args[2]

$MYULTIMATEANSWER | GET-MEMBER

$MYULTIMATEANSWER

We see now that although certain parameters started as strings, they can be brought into Windows PowerShell how we need them.  Now we have a parameter that will always assume that it should be a date. You should probably look into some error checking in case somebody did not read your instructions and passes a parameter of Oogar the Planet Squisher instead. There is a good chance that it might not be accepted as DateTime (unless you happen to be coding Windows PowerShell in Oogar the Planet Squisher’s home world). Also remember that in the console world, the blank space is your parser when passing parameters. So, I’ll be honest. When I created SnoopyDance, I cheated because I didn’t want to cause confusion. Remember that before it goes to Windows PowerShell, we are working in the console world. So all the rules from the console application (and all the features) apply when passing parameters. So if we need to pass a blank space as part of a string, we need to enclose it in quotation marks (just like when we send it to a Batch file). And all of this in VBScript works exactly the same way. The exact methods and techniques that you used in VBScript to launch console applications work with Windows PowerShell. In many cases, you’ll be launching POWERSHELL.EXE –FILE SCRIPTNAME.PS1 –executionpolicy RemoteSigned and the parameters instead of a console application and its parameters. Now doesn’t this make you wonder? Could Windows PowerShell pass parameters to console applications and VBScript scripts then? Maybe it can…but as they say on the riverbank, that is another story. At this point, our little troublemaker friend began to spin about like a bad Saturday morning cartoon character. “Oh! Eeee! OOOO! I can…I can run Windows PowerShell from VBScript scripts…and from console applications! Ooooooooo!” Smoke began to appear as his feet began pounding the ground. “More! Need more input! MORE! MOOOOOOORRREE,” Mr. Trouble screamed. “Gladly,” said the Scripting Guy, tossing a convenient barrel of water onto the smoking feet. “We will talk tomorrow. You may bow at the end of the lesson afterwards. You will want to.” Guest blogger week will continue tomorrow when Sean will continue to talk about Windows PowerShell and the Legacy. A special thank you to Sean for writing this week’s blog posts. Hope you enjoy them. 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

Author

0 comments

Discussion are closed.