Even in the most standardized networks, it's easy to specify the incorrect paths to special folders such as My Documents or temporary folders that have
special roles in Windows. Fortunately, you can ask Windows where particular folders are located. After I explain the root of the problem, I'll show you
how to make Microsoft PowerShell scripts consistently find the right path, even in nonstandard setups.
Understanding the Problem
Although working with files and folders is a standard task for network administrators, the specific paths to those folders aren't standard. Windows
installations, upgrades, hardware installations, user policies, and machine policies can all lead to wildly varying paths for special folders. Even in
standardized networks, variations are possible due to machine roles or user requirements.
Some of these paths are relatively easy to find with PowerShell variables. For example, the $home variable always contains the literal path to a user's
home folder. However, finding other paths might require some guesswork. For example, if your users are mainly running Windows 7 or Windows Vista, you
could try accessing the folder that contains temporary Internet files by using the path \$home\AppData\Local\Microsoft\Windows\Temporary Internet
Files. However, this path will fail for users running an earlier Windows OS or if their temporary Internet files are redirected to a different
location. Standardizing isn't always possible, and coding in all sorts of checks for special cases will end up being cumbersome and confusing.
Fortunately, there's an easier way. Instead of guessing, you can use the Microsoft .NET Framework's System.Environment class to obtain paths. By using
the OS APIs, you have access to more information than you can get from environment variables alone. The information is also more reliable because
Windows uses the same technique to determine paths.
Using System.Environment in PowerShell
In PowerShell, you specify a .NET class by using its name in square brackets, like this: [System.Environment]. To simplify using the System namespace,
PowerShell lets you omit the
System. portion, so you can use [Environment] for brevity.
To find the paths of special folders, the first step is to determine what special folders are exposed. The Environment class has a special enumerated
list of the canonical names for these folders. A quick way to show these names is to use the command
[Environment+SpecialFolder]::GetNames([Environment+SpecialFolder])
In Windows 7, this command returns a list of names like that shown in Figure 1. You can find the meanings of these names in the
"Environment.SpecialFolder Enumeration" web page. Note that some of the
special folders listed in this web page aren't available within PowerShell.

Figure 1: Special folders’ canonical names
At the bottom of the "Environment.SpecialFolder Enumeration" web page, you'll find a PowerShell script by Thomas Lee demonstrating how to list the
special folders' names and their paths. There are two details you should know about accessing these folders. First, if a folder doesn't exist, you'll
get an empty path back. Second, some folders might not be accessible from an unprivileged account.
Thomas Lee's script works well if you just want to see the names and paths. However, what can you do if you want to easily use those paths in scripts?
There are many possible approaches. I'll show you three of them. Each is useful in different situations, but all of them require that you understand
what the names like ProgramFiles or Startup mean, as defined in the "Environment.SpecialFolder Enumeration" web page.
Suppose you want to access a specific folder, such as the one named Desktop. In PowerShell syntax, the ID of this specific folder is
[Environment+SpecialFolder]::Desktop. You provide this ID as an argument to the Environment class's static GetFolderPath method, like this
[Environment]::GetFolderPath("Desktop")This command returns the exact path to the current user's Desktop folder.