Hey, Scripting Guy! How can I use Windows PowerShell to retrieve the value of environment variables and the path to a special folder?
Hey, SB. Well, it’s Thursday, which means that the Scripting Guy who writes this column is currently in Walla Walla, WA, which, as Daffy Duck fans all know, is the home of the Wishy Washy Washing Machine Company; various divisions of the Acme Corporation; and who-knows-what-else.
Oh, we know what else: Walla Walla was also immortalized in the song lyrics “Oo ee oo-ah-ah, ting tang walla walla bing bang.” Walla Walla is even featured in the Wikipedia entry on inherently funny words. Pretty good for a town of 30,000 people, wouldn’t you say?
Of course, the Scripting Guy who writes this column isn’t spending his time in Walla Walla sitting around doing nothing. (That’s what he does when he’s at work.) Instead, he’s busy doing all sorts of things, including
Writing this column.
Getting ready for Game 1 of the Walla Walla Invitational Baseball Tournament.
Watching the thermometer creep past the 750 degree mark.
OK, so maybe it’s not quite 750 degrees here, at least not 750 degrees Fahrenheit. However, the temperature is expected to climb above 100 degrees, and some of this Script Guy’s fellow baseball parents are already slathering themselves with sunscreen, drinking tons of water, and complaining about the heat.
And that’s a bad sign; after all, most of them haven’t even gotten out of their air-conditioned cars yet.
Having grown up in the nearby Tri-Cities, however, the Scripting Guy who writes this column isn’t going to be deterred by a little heat; after all, he once played a baseball game in 114 degree heat. (And, oddly enough, had to walk 12 miles uphill, through the snow, in order to get to the game.) He’s not complaining about the heat, taking water intravenously, or even wearing sunscreen; on top of that, he’s about to answer a question about retrieving environment variable values and special folder paths using Windows PowerShell.
Yes, he is quite a man, isn’t he?
For starters, let’s see how we can retrieve the values of an environment variable. As SB noted, in VBScript you can retrieve the value of the %logonserver% environment variable by using code similar to this:
Set oShell = CreateObject("Wscript.Shell")
Set WshSysEnv = oShell.Environment("PROCESS")
sLogonServer = WshSysEnv("LOGONSERVER")
Pretty straightforward: we create an instance of the Wscript.Shell object, grab the collection of process environment variables, then store the value of the logonserver in a variable named sLogonServer. So how do we get this same information using Windows PowerShell? Why, like this, of course:
$a = $env:logonserver
Yes, that is easy, isn’t it? As it turns out, Windows PowerShell has an environment provider that makes it a snap to access information about all the environment variables on a computer. As you can see, all we have to do is specify the $env variable followed by a colon and the name of the environment variable we’re interested in. Want to store the value of the %username% environment variable in a variable named $a? Then use this syntax:
$a = $env:username
Or maybe you’d like to know the computer name:
$a = $env:computername
If it wasn’t for the baseball game, we could sit here and retrieve environmental variables all day long.
You know, that’s a good question: what if you don’t know which environment variables are available on a computer? Fortunately that’s no big deal: to view all the environment variables and their values use this command (note that, in this case, we leave the $ off and reference the env: drive instead):
Try this command in Windows PowerShell and see what you get back.
OK, now what about the path to special folders? As SB pointed out, this is a pretty easy task to perform in VBScript; for example, the following VBScript code retrieves the path to the user’s desktop folder:
Set oShell = CreateObject("Wscript.Shell")
Set oSFolders = oShell.SpecialFolders
sDesktop = oSFolders("Desktop")
As you can probably see for yourself, the preceding script creates an instance of the Wscript.Shell object, creates an object reference to the SpecialFolders collection, then retrieves the path to the desktop folder. We could employ this exact same approach using Windows PowerShell; alternatively, we could use the .NET Framework’s System.Environment class (and the GetFolderPath method) to retrieve the path to the desktop folder. All things considered, however, we decided that it’s easier (and more powerful) to use the the Shell.Application object to retrieve special folder paths:
$a = New-Object –com Shell.Application
$b = ($a.namespace(0x10)).Self.Path
OK, granted, this might not look all that easy. With that in mind, let’s see if we can explain how it works. In line 1 we simply use the New-Object cmdlet to create an instance of a new COM object (hence the –com parameter). And what new COM object are we creating? You got it: Shell.Application.
Actually, that was pretty easy; line 2 is a different story. But don’t panic: line 2’s bark is far worse than its bite. In fact, line 2 only looks complicated because we’re actually performing a couple different tasks with a single line of code. To begin with, we’re taking the object reference to the Shell.Application object ($a) and using the Namespace method to bind to a particular folder. That’s what this portion of the script is for:
What’s the 0x10 for? That’s a hexadecimal value that represents the Desktop folder. And how did we know that 0x10 represents the Desktop folder? To tell you the truth, we didn’t; that’s why we popped over to the Script Repository and took a peek at the special folder scripts. As it turns out, the script titled List Items in the Desktop Folder looks like this:
Const DESKTOP = &H10&
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(DESKTOP)
Set objFolderItem = objFolder.Self
Set colItems = objFolder.Items
For Each objItem in colItems
Note. Do you want to use Windows PowerShell to list all the items in the desktop folder? Then just add a third line to your script: Get-ChildItem $b.
Notice the first line of code, where we assign the hexadecimal value &H10& to a constant named Desktop. The &H10& (which uses VBScript syntax for hexadecimal values) is the value that represents the Desktop folder; all we have to do is convert that to 0x10, the Windows PowerShell syntax for hexadecimal values. Suppose we were interested in the Internet Cookies folder instead. Well, the VBScript script for working with that folder includes this line of code:
Const COOKIES = &H21&
Now, guess what the PowerShell equivalent to &H21& is? That’s right: 0x21.
You might also have noticed that we placed parentheses around the call to the Namespace method:
$b = ($a.namespace(0x10)).Self.Path
Why did we do that? That’s easy: Windows PowerShell always takes care of anything in parentheses before it performs any other tasks. That means that Windows PowerShell is going to first use the Namespace method to bind to the Desktop folder; it’s only after that task is complete that PowerShell retrieves the value of the Self.Path property, which just happens to be the path to the Desktop folder. The parentheses simply make sure that Windows PowerShell first gets the folder and only then tries to retrieve the folder path.
Granted, this can be a tad bit confusing. But remember, all you have to do is replace the 0x10 with the appropriate value and you can easily bind to any special folder on the computer.
We hope that helps, SB; the truth is, it’s going to have to, because it’s almost time for the game to start. You know, watching high school baseball in Walla Walla is like a trip down memory lane for the Scripting Guy who writes this column; back when he was in high school he actually played a few games in Walla Walla. For example, when he played here as a sophomore the umpires were prisoners on work release from the Walla Walla State Penitentiary. Were these inmates good umpires? Let’s put it this way: nobody argued with them, that’s for sure.