Windows PowerShell Tip of the Week

Here’s a quick tip on working with Windows PowerShell. These are published every week for as long as we can come up with new tips. If you have a tip you’d like us to share or a question about how to do something, let us know.

Using the Range Operator in Wildcard Queries

It probably comes as no surprise that Windows PowerShell cmdlets such as Get-ChildItem (a cmdlet roughly equivalent to the dir command) allow you to use standard wildcard characters like the asterisk (*) and the question mark (?) when making queries. For example, suppose you want to look at all the files in the folder C:\Scripts, provided that these files have a file name that begins with the letter a. No problem; just include the asterisk as part of your command:

Get-ChildItem C:\Scripts\a*

Nothing too exciting or revolutionary there: because the asterisk in Windows PowerShell (just like the asterisk in Cmd.exe) stands for “anything,” this command returns all the files that start with the letter a and then are followed by, well, anything. (Or, technically, by nothing: a file named A – with no file extension – will also be returned by the command.)

Likewise, you can use the question mark to represent a single character in a file name. For example, suppose you have a set of files named FileA1.txt, FileA2.txt, FileA3.txt, etc. (for this example, up to and including FileA9.txt). How can you return all these files with a single command? Like this:

Get-ChildItem C:\Scripts\FileA?.txt

Or, combine your wildcard characters to return any “FileA” files regardless of their file extension:

Get-ChildItem C:\Scripts\FileA?.*

That’s great, but here’s something even better. Suppose you need a list of all the files that have file names beginning with the letters A-F. How can you do that in Cmd.exe? To tell you the truth, we don’t know. But here’s how you can perform that task in Windows PowerShell:

Get-ChildItem C:\Scripts\[a-f]*

As you can see, all we did here was include a range operator – [a-f] – that asks PowerShell to return any files that have a file name starting with any of the specified letters: a through f. By tacking on the asterisk, we further specify that we don’t care what characters (if any) follow that initial letter. What kind of data will we get back when we issue this command? Data similar to this:

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         5/23/2007   9:52 AM         93 addresses.txt
-a---        11/17/2006   2:52 PM        708 alice.txt
-a---         2/26/2007  10:44 AM        732 Alice2.txt
-a---         3/12/2007   8:08 AM         88 bullet.gif
-a---         6/15/2007   8:07 AM       1060 ccs.csv
-a---         5/14/2007   8:41 AM          8 computers.txt
-a---         5/23/2007  10:36 AM        114 current.txt
-a---         2/22/2007  12:56 AM        730 decode.txt
-a---         2/26/2007  10:33 AM        732 Decoded.txt
-a---         2/22/2007   1:06 AM        728 Decrypt.txt
-a---         5/23/2007  10:36 AM         59 Differences.txt
-a---          7/3/2007  10:38 AM       5781 drawing.TXT
-a---          7/3/2007  10:47 AM      17920 drawing.xls
-a---          4/3/2007   8:29 AM      13824 Employees.xls
-a---         2/22/2007  12:44 AM       2916 encode.txt
-a---         2/26/2007  10:44 AM        732 Encoded.txt
-a---         2/21/2007  12:24 AM        732 EncodedAlice.txt
-a---         2/22/2007   1:06 AM       2852 Encrypt.txt
-a---         2/21/2007  12:10 AM       1458 Encrypted.txt
-a---         5/24/2007  10:08 AM        408 erase.vbs
-a---         10/9/2006   8:30 PM        649 fv.ps1

Pretty slick, huh? Interested only in files that start with the letters c through f? That’s fine; just set the range operator accordingly:

Get-ChildItem C:\Scripts\[c-f]*

And yes, this works with numbers as well as with letters. Need a list of files that start with a number rather than a letter? Okey-doke:

Get-ChildItem C:\Scripts\[0-9]*

Of course, all this is great if you’re interested in a range of characters. But what if you’re interested in a specific set of letters, letters that don’t fall into a nice, neat range? (For example, files starting with the letter b, the letter d, or the letter f.) No problem; all you have to do is put each of those characters in the range operator. Just leave out the hyphen so that PowerShell knows to deal with each individual letter instead of a range of letters:

Get-ChildItem C:\Scripts\[bdf]*

Is that going to work? Of course it is:

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         3/12/2007   8:08 AM         88 bullet.gif
-a---         2/22/2007  12:56 AM        730 decode.txt
-a---         2/26/2007  10:33 AM        732 Decoded.txt
-a---         2/22/2007   1:06 AM        728 Decrypt.txt
-a---         5/23/2007  10:36 AM         59 Differences.txt
-a---          7/3/2007  10:38 AM       5781 drawing.TXT
-a---          7/3/2007  10:47 AM      17920 drawing.xls
-a---         10/9/2006   8:30 PM        649 fv.ps1

As if that wasn’t enough, you can use the range operator anywhere in your command; it doesn’t have to represent the first letter. For example, suppose you need a list of all the files where the second character is an l, an n, or an r. (No, we don’t know why you’d need such a list; just pretend that you do.) Here’s a fancy little command that uses a question mark to represent the first letter in the file name, a range operator to represent the second letter, and an asterisk to represent any additional letters:

Get-ChildItem C:\Scripts\?[lnr]*

And here’s the kind of output you can expect to get back:

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        11/17/2006   2:52 PM        708 alice.txt
-a---         2/26/2007  10:44 AM        732 Alice2.txt
-a---          7/3/2007  10:38 AM       5781 drawing.TXT
-a---          7/3/2007  10:47 AM      17920 drawing.xls
-a---         2/22/2007  12:44 AM       2916 encode.txt
-a---         2/26/2007  10:44 AM        732 Encoded.txt
-a---         2/21/2007  12:24 AM        732 EncodedAlice.txt
-a---         2/22/2007   1:06 AM       2852 Encrypt.txt
-a---         2/21/2007  12:10 AM       1458 Encrypted.txt
-a---         5/24/2007  10:08 AM        408 erase.vbs
-a---         5/24/2007  10:07 AM        850 WriteToCD.vbs

Not bad, not bad at all.