Learn about Windows PowerShell
Summary: Microsoft Scripting Guy Ed Wilson answers several questions that will improve your productivity with Windows PowerShell.
In this post:
Hey, Scripting Guy! I was reading about arrays this morning and I wondered if there is a way to count the number of items in an array if you don't have that information already.
Also, I'm using somebody else's script right this minute. It prompts a user to remove a flash drive or USB drive when they log off. I don't have a clue how the message box stuff works. (I just use their code.) If you have a link or a search phrase or can point me in the right direction, it would sure be helpful.
One more thing: I spent hours today trying to figure out how to break a long line in half so that the code was more readable. I can't find a single place where formatting of Windows PowerShell is discussed in detail. Like where it would talk about case, line continuation, do tabs, blank lines, or spaces mean anything, etc.
Hello TJ, this is Microsoft Scripting Guy Ed Wilson. To count the items in an array, use the count property. The code shown here shows this technique. It first creates an array with three elements, and stores the array in the $array variable. Next, it uses the count property from the array object.
PS C:\> $array = "a","b","c"
PS C:\> $array.Count
To break up lines, use the acute accent character (') followed by a space for line continuation. The code seen here shows this methodology by querying the WMI class Win32_Bios through the Get-WmiObject Windows PowerShell cmdlet. The computername property appears at the end of the physical line, but not the logical command. Therefore, the acute accent character is used to continue the command to the next line. After the value is supplied on the next line, the enter key is pressed two times to submit the command.
PS C:\> Get-WmiObject -Class win32_bios -computername '
SMBIOSBIOSVersion : 7LETB7WW (2.17 )
Manufacturer : LENOVO
Name : Ver 1.00PARTTBLx
SerialNumber : L3L4518
Version : LENOVO - 2170
To continue a string, make sure that you do not close and open the quotation marks. This is seen here.
PS C:\> $a = "this is a '
>> long string"
PS C:\> $a
this is a
Here is an example that does not work:
PS C:\> $a = "this is a" '
>> " long string"
Unexpected token ' long string' in expression or statement.
At line:2 char:15
+ " long string" <<<<
+ CategoryInfo : ParserError: ( long string:String) , ParentContainsErrorRecordExce
+ FullyQualifiedErrorId : UnexpectedToken
PS C:\> $a = "this is a '
Unexpected token 'long' in expression or statement.
+ CategoryInfo : ParserError: (long:String) , ParentContainsErrorRecordException
If you want your string on a single line and therefore want to avoid using the line continuation operator, use concatenation. This is seen here.
PS C:\> $a = "This is a"
PS C:\> $a += " long string"
This is a long string
To do a popup box, I find it easiest to use the same popup method I used in VBScript. It comes from the wshShell object that is created by using wscript.shell. You can do this, as seen here.
PS C:\> $shell = New-Object -ComObject wscript.shell
PS C:\> $shell.Popup("this is a popup")
The popup box seen here appears.
The cool thing, is that it can be done in a single line as seen here.
PS C:\> (New-Object -ComObject wscript.shell).popup("this is a one line popup")
If we want to continue the previous one line command, be aware that this example causes an error.
PS C:\> (New-Object -ComObject wscript.shell).popup'
>> ("broke line")
Unexpected token '(' in expression or statement.
At line:2 char:2
+ ( <<<< "broke line")
+ CategoryInfo : ParserError: ((:String) , ParentContainsErrorRecordException
However, this line will work.
PS C:\> (New-Object -ComObject wscript.shell).popup(
>> "broke line")
This is because, when Windows PowerShell sees the opening parenthesis, it knows that you have not completed the command. It therefore looks for more information. Using the acute accent character, you can continue the command as seen here.
PS C:\> (New-Object -ComObject wscript.shell).'
>> popup("this is a popup")
I do not like breaking lines at the period. This command is easier to read.
PS C:\> (New-Object -ComObject '
>> wscript.shell).popup("this is a popup")
I will frequently use variables to keep the lines short and I try to avoid line continuation like the plague. It makes it really difficult to see what is going on and is another layer of potential error. In addition, it really confuses people who are trying to learn the language. But the style in books and on the web means that line continuation is unavoidable in some cases. This is especially true when you are using .NET Framework classes whose names are really long at times.
I have a complete series of Hey Scripting Guy! posts that are all tagged Getting Started. I cover fundamental Windows PowerShell concepts such as strings, numbers, dates and times, line continuation and concatenation, arrays, and more. There are many fundamental concepts and therefore many posts. I continue to add to the collection regularly.
There is also a series of posts that are all tagged Scripting Wife. The Scripting Wife posts were written as a result of my wife's decision to enter the 2010 Scripting Games. These posts assume no scripting knowledge, and only basic computer understanding. She did accounting work, and is therefore familiar with computers from a user perspective. They are an excellent place to start before even wading into the Getting Started posts. You may also want to review the 2010 Scripting Games especially the beginner division. The tasks are things a typical network administrator would be tasked with performing. The beginner division games really are for beginning users, and they assume that you have the basics covered. There was a study guide that would prepare you for the events in the 2010 Scripting Games. They are great learning tools. Here would be a step-by-step approach to learning about Windows PowerShell.
Hey, Scripting Guy! I have a script that I want to run every 30 minutes. Should I use Windows scheduling to run it every 30 minutes or should I code a sleep routine and have it wake up every 30 minutes and just schedule it once per day. Maybe it is one of those '6 or half dozen' things but just curious if, from a Windows perspective (memory?), it's better to do it one way or the other.
Hello RD, I would highly recommend that you create a scheduled task. The advantages are that it does not require the script to run constantly. If you have the script running, there is always a chance that it might be unintentionally stopped. In addition, a running script will consume some memory. Depending on what the script is actually doing, it might be using a large amount of memory. If you need a long term monitoring operation, you might consider writing an actual service in either C# or Visual Basic .NET. At any rate, I would definitely use the Windows Task Scheduler instead of sleeping the script.
Well, this concludes another edition of Quick Hits Friday. Join us tomorrow for the Weekend Scripter as we delve into the mysteries of Win 32 reliability WMI class.
I would love you to follow me on Twitter or Facebook. If you have any questions, send email to me at firstname.lastname@example.org or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy