Bookmark and Share

(Note: Today's Hey, Scripting Guy! Blog post is an edited excerpt from a forthcoming SAPIEN Press book authored by Don Jones and Jeffery Hicks. Don has published more than 30 books about IT pro topics; you can also find him in TechNet Magazine, on, and on Jeffery has authored or co-authored several books in the SAPIEN TFM series; he is a Windows PowerShell MVP, a columnist and contributing editor for, and a columnist for Find out more about Jeffery at

Today is part 1 of 2. Part 2 will be published tomorrow. Thanks, Don and Jeffery!)


With many shells—particularly some *nix shells—using the shell interactively is a very different experience than scripting with the shell. Typically, shells offer a complete scripting language that is only available when you’re running a script. Not so with Windows PowerShell: The shell behaves exactly the same, and offers exactly the same features and functionality, whether you’re writing a script or using the shell interactively. In fact, a Windows PowerShell script is a true script—simply a text file listing the things you’d type interactively. The only reason to write a script is because you’re tired of typing those things interactively and want to be able to run them again and again with minimal effort.

Script Files

Windows PowerShell recognizes the .ps1 file name extension as a Windows PowerShell script. Notice the “1” in there? That indicates a script designed to work with Windows PowerShell version 1; future versions of Windows PowerShell will presumably be able to use that as an indicator for backward-compatibility. Script files are simple text files; you can edit them with Notepad or any other text editor. In fact, by default, Windows associates the .ps1 file name extension with Notepad, not Windows PowerShell, so double-clicking a script file opens it in Notepad rather than executing it in Windows PowerShell. Of course, we’re a bit biased against Notepad as a script editor: Notepad was certainly never designed for that task, and better options exist. We’re obviously keen on SAPIEN PrimalScript ( because it offers a full visual development environment with Windows PowerShell–specific support, such as the ability to package a Windows PowerShell script in a stand-alone executable that runs under alternate credentials.

Note that Windows PowerShell 2.0 continues to use the .ps1 file name extension; think of this extension as “version 1 of the script file format,” rather than having a direct relation to version 2.0 of the shell. In fact, version 2.0 should run most version 1.0 scripts unchanged.


Windows PowerShell supports four special scripts called profiles. These scripts are physically identical to any other script; what makes them special is that Windows PowerShell looks for them when it starts and, if it finds them, executes them. Think of them as a sort of “auto-run” set of scripts, allowing you to define custom aliases, functions, and so forth. For example, by defining custom aliases in your profile, those aliases will be defined every time Windows PowerShell runs, making your aliases available to you anytime you’re using the shell.

Windows PowerShell looks for profiles using a specific path and file name. It looks for them—and executes them, if they’re present—in the following order:

·         %windir%\system32\WindowsPowerShell\v1.0\profile.ps1
This applies to all users and to all shells.

·         %windir\system32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1
This applies to all users but only to the PowerShell.exe shell.

·         %UserDocuments%\WindowsPowerShell\profile.ps1
This applies to the current user but affects all shells.

·         %UserDocuments%\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
This applies to the current user and only to the PowerShell.exe shell.

By the Way…

%UserDocuments% isn’t a valid environment variable. We’re using it to represent the user’s “Documents” folder. On Windows XP, for example, this would be under %UserProfile%\My Documents; on Windows Vista, it’s under %UserProfile%\Documents.

Notice the references to “all shells.” We’re primarily working with the PowerShell.exe shell. However, other shells exist: The Exchange Management Shell (which ships with Exchange Server 2007) is a different shell. If you have things you want defined in all the shells you use—such as custom aliases—you’d put them in one of the “all shells” profiles.

A Note on Shells

Note that you don’t have to use custom shells. For example, you don’t need to use the Exchange Management Shell to manage Exchange Server 2007. Instead, you could simply add the Exchange snap-in to PowerShell.exe, using Add-PSSnapIn. Doing so would give you access to the Exchange cmdlets from the PowerShell.exe shell. This trick allows you to create a shell environment that has all the cmdlets you need to manage all your Windows PowerShell–manageable products.

None of these profile files are created by default. You should also remember that these are just Windows PowerShell scripts, so they won’t run unless they meet your shell’s execution policy. In other words, your profiles need to be signed if your execution policy is AllSigned.


See you tomorrow for part 2!