As you probably know, PowerShell is Microsoft's latest Windows operating system (OS) shell and scripting tool. A shell is a program that provides a user interface for the OS. When we're talking about PowerShell, the "shell" part usually refers to its command-line interface (CLI). A CLI is a basic user interface that lets you enter a command (or a series of commands) at a prompt. When you press Enter, the shell performs an action, then the CLI displays the prompt again and waits for another command. (See also, "Getting Started with PowerShell").
At first, a CLI might not seem as efficient as a graphical user interface (GUI) because you have to type in commands, making sure of spelling, spacing, quotes, etc. However, command shells have always supported some form of batch execution, which is also called scripting. A script is simply a list of commands stored in a text file you can execute on demand. PowerShell is no exception—although PowerShell is an excellent CLI, it becomes even more flexible with the use of scripts. A PowerShell script is simply a text file with a .ps1 extension that contains a list of commands PowerShell should execute.
However, PowerShell's secure by default philosophy prevents all scripts from running, so double-clicking a PowerShell script from Windows Explorer won't execute it. Also, PowerShell doesn't execute scripts from the current directory. The good news is that you don't have to be a PowerShell guru if all you want to do is understand how to run PowerShell scripts. Simply follow these steps:
- Install Windows PowerShell.
- Set PowerShell's execution policy.
- Run your PowerShell scripts, keeping a few important details in mind.
1. Install Windows PowerShell
If you have Windows 7 or later, you don't need to install PowerShell because it comes preinstalled with the OS. If you're using Windows Vista or earlier, you need to download and install PowerShell. Windows XP and Windows Server 2003 also require the Microsoft .NET Framework 2.0. (The .NET Framework 2.0 SP1 is required for PowerShell 2.0.) You can find the links to the downloads on the "Scripting with Windows PowerShell" web page.
2. Set PowerShell's Execution Policy
As I mentioned previously, PowerShell is secure by default. The first implication of this philosophy is that PowerShell won't execute scripts until you explicitly give it permission to do so. PowerShell has four execution policies that govern how it should execute scripts:
- Restricted. PowerShell won't run any scripts. This is PowerShell's default execution policy.
- AllSigned. PowerShell will only run scripts that are signed with a digital signature. If you run a script signed by a publisher PowerShell hasn't seen before, PowerShell will ask whether you trust the script's publisher.
- RemoteSigned. PowerShell won't run scripts downloaded from the Internet unless they have a digital signature, but scripts not downloaded from the Internet will run without prompting. If a script has a digital signature, PowerShell will prompt you before it runs a script from a publisher it hasn't seen before.
- Unrestricted. PowerShell ignores digital signatures but will still prompt you before running a script downloaded from the Internet.
To display the current execution policy, you need to enter the command
at a PowerShell prompt (which will look like PS C:\> assuming the current location is C:\). To set the execution policy, enter the command
where policy is one of the policy names (e.g., RemoteSigned).
Setting the execution policy requires administrator permissions. In Vista and later, you must run PowerShell with elevated permissions if you're already an administrator and User Account Control (UAC) is enabled. To run PowerShell under elevated permissions in Vista and later, right-click its shortcut and choose Run as administrator, as Figure 1 shows.
If you're logged on to XP or Windows 2003 as a standard user, you can right-click the PowerShell shortcut, choose Run as, and enter administrator account credentials.
One thing that's important to understand about execution policies is the meaning of the phrase "downloaded from the Internet." In Windows, this phrase means that the file has an alternative data stream that indicates the file was downloaded from the Internet zone. To unblock a script, right-click the .ps1 file, choose Properties, then click the Unblock button, as shown in Figure 2. My web-exclusive article "Dealing with XP SP2's Security Warning Dialog Boxes" provides more complete details about the alternative data stream and how Windows uses it.
I recommend setting the execution policy to RemoteSigned because this execution policy lets you write and run scripts on your own computer without having to sign them with a code-signing certificate. You'll still be prevented from running a script downloaded from the Internet unless you explicitly unblock it first. To set the RemoteSigned execution policy, enter the following command at a PowerShell prompt:
Microsoft also provides an administrative template (.adm file) for managing PowerShell's execution policy through a Group Policy Object (GPO), which you can download from the "Administrative Templates for Windows PowerShell" web page.
3. Run Your PowerShell Scripts
After configuring the execution policy, you can run PowerShell scripts. To run a script, open a PowerShell window, type the script's name (with or without the .ps1 extension) followed by the script's parameters (if any), and press Enter. In keeping with PowerShell's secure by default philosophy, double-clicking a .ps1 file from Windows Explorer opens the script in Notepad rather than executing the script with PowerShell.
When you're running PowerShell scripts, you need to keep in mind several details, the first of which concerns a new option in PowerShell 2.0. When you right-click a .ps1 file, PowerShell 2.0 provides a Run with PowerShell option, but I don't recommend using it for two reasons:
- When you use this option, the PowerShell window closes immediately after the script finishes. Because most PowerShell scripts aren't written to pause when they're finished, you'll miss any output the script provides and any errors the script might encounter.
- Many PowerShell scripts use command-line parameters that control their behavior. There's no way to enter parameters when using this option.
For these reasons, I recommend running PowerShell scripts from a PowerShell command window instead.
Another important detail to keep in mind when running scripts is that PowerShell doesn't run them from the current directory. Instead, it uses the Path. (The Path is a comma-delimited list of directories, stored in the Path environment variable, that Windows searches for executable files.) If you type a script's name (but not its location) and the script isn't found in the Path, PowerShell won't run it, even if the script is in the current directory. This is another aspect of PowerShell's secure by default philosophy. PowerShell doesn't run scripts in the current directory, to prevent the scenario in which an attacker puts a bogus script in the current directory with the same name as a commonly used command. If PowerShell ran scripts from the current directory first, a user might unwittingly run the rogue program by accident. By ignoring scripts in the current directory, PowerShell avoids this potential problem.
To explicitly run a script from the current directory, you must prefix the script's name with .\ or ./ so that PowerShell understands you intend to run it from the current location. For example, suppose the directory C:\Scripts isn't in the Path and the following script, named HelloWorld.ps1, exists in C:\Scripts:
Write-Host "Hello, world" Read-Host "Press Enter to continue"
If you enter these commands at the PowerShell prompt
PS C:\> Set-Location C:\Scripts PS C:\Scripts> HelloWorld
PowerShell won't run HelloWorld.ps1, even though the current location is C:\Scripts. (Note that I included the prompts you'd see, for demonstration purposes. You wouldn't type these prompts when entering the commands.) Instead of the second command, you need to type one of the following commands:
PS C:\Scripts> .\HelloWorld PS C:\Scripts> ./HelloWorld
Because PowerShell doesn't execute scripts from the current directory, I recommend that you create a directory, add this directory to your Path, and store your PowerShell scripts in this directory. That way, you can avoid any problems.
The final detail you need to remember when running PowerShell scripts is that you need to handle spaces differently than you did in Cmd.exe. When a script's pathname contains spaces, you have to surround it with double quotes (") to run it in Cmd.exe. For example, in Cmd.exe, you'd type:
to run a script named C:\Program Files\Scripts\HelloWorld.cmd. Quoting a script's path to run it won't work in PowerShell, because the presence of double quotes causes PowerShell to evaluate the pathname as an expression rather than a command. If you simply type the script's name in quotes like you did in Cmd.exe, PowerShell assumes the pathname is a string and outputs the pathname instead of running the script. To work around this, you can use PowerShell's invocation operator, &, to execute the quoted string as a command, as in
PS C:\> & "C:\Program Files\Scripts\HelloWorld"
Because you must use the & operator and quotes to execute a script that has spaces in its pathname, I recommend that you don't use spaces in your scripts' names when creating your own scripts. In addition, if you create a directory in which to store scripts, make sure you leave out spaces in its name as well.
Running PowerShell Scripts Made Easy
You don't need to be a PowerShell or scripting expert to easily run PowerShell scripts. Simply follow these three steps and you'll be running PowerShell scripts in no time.
Learn more from "Administrative Reporting with PowerShell," June 2012.