PowerShell scripts are a powerful and flexible way of automating administrative and repetitive tasks. They can be written with only a text editor and a basic knowledge of the cmdlets that are available. However, running scripts written by others or downloaded from the Internet can be a risky activity – the level of access that a PowerShell script has to your system is extensive, and this is why their execution is blocked by default in Windows.
The information below describes how to safely enable the execution of scripts, and the specifics of how to run them when that initial configuration is complete. It is beyond the scope of this article to provide a complete tutorial on PowerShell or writing PowerShell scripts – courses containing much more information about setting up your systems to run PowerShell scripts, and even a complete getting started tutorial for beginners to PowerShell are available at Udemy.com.
Setting the Execution Policy
The PowerShell Script Execution Policy is a system-wide configuration setting that allows (or disallows) the execution of PowerShell scripts, depending on where they came from and who they are published by.
There are four different levels for this setting:
No PowerShell scripts can be run. This is the default setting on most installations of Windows.
Only scripts that have been signed by a trusted publisher may be executed.
Scripts downloaded from the Internet or a remote network must be signed by a trusted publisher. Scripts that are created on your machine (such as ones that you write yourself) can run unsigned.
All PowerShell scripts can be run. For security reasons this is not usually recommended.
The execution policy can be changed from the PowerShell console, using the cmdlet Set-ExecutionPolicy followed by one of the four levels above. You may need to run the console as an administrator in order to change the configuration setting.
For home users, and for people in the process of writing scripts, the RemoteSigned policy protects the system from downloaded scripts, but does allow users to run their own work. To enable the RemoteSigned policy, type the following statement in a PowerShell console and press Enter:
Although less convenient, AllSigned offers significant extra security. It can be particularly useful for system administrators as it not only protects the computer from downloaded scripts, but also prevents users from writing and running their own. To run scripts under the AllSigned execution policy, they must be signed by a trusted publisher with a code-signing certificate from a trusted certification authority.
Digital signatures are more useful than their real-world counterparts. In addition to verifying authenticity (that the script comes from the person or publisher that it claims to), they also verify integrity (that the script has not been modified since it was signed).
For a signature to be accepted by PowerShell, it must come from a trusted source and you can buy code-signing certificates from organizations such as Verisign and Thawte. However, if you have sufficient control over the systems that need to run your scripts, you can generate your own signing certificate for free. When deploying a self-signed script across a network, you must first create your own authority and then you will need to add that authority as a trusted certification authority on every machine that will execute your scripts.
The processes involved in creating a certification authority, issuing code-signing certificates, and managing these certificates are too lengthy to detail here. However, the steps can be summarized as:
- Download and install the Windows SDK from http://msdn.microsoft.com/en-US/windows/desktop/aa904949.aspx
- Use makecert.exe from the SDK to generate .cer and .pvk files for the authority.
- Install the .cer file as a trusted certification authority on all machines that will run the signed script.
- Use makecert.exe from the SDK to issue a code-signing certificate from that authority, generating two new .cer and .pvk files.
- Install the new .cer file as a trusted publisher on all machines that will run the signed script.
- Use pvk2pfx.exe from the SDK to convert the code-signing certificate to a .pfx file that can be used from PowerShell.
- In a PowerShell console, load the .pfx file using the cmdlet Get-PfxCertificate.
- Sign the PowerShell script using the cmdlet Set-AuthenticodeSignature.
Running a PowerShell Script from the Console
With the execution policy set, and the script signed if necessary, the script can be run from the PowerShell console by typing the file path and file name and then pressing Enter. You must include the file path otherwise the script will usually be opened in your system’s default text editor instead. For convenience, relative paths (such as .\ to refer to the current directory) can be used:
After the script has completed, any variables or functions that are declared in it will be cleared from memory. In some cases this is not the desired outcome, and it can be avoided by “dot sourcing” – starting the call with a dot, and then placing the file path and file name in quotes:
Running a PowerShell Script from another PowerShell Script
A PowerShell script can run another script using the same syntax as used in the console. However, when scripting it is often useful to hold file names in variables, particularly if they are referenced often in the script. This is done by using a variation of the “dot sourcing” technique described above. For example:
$script = ".\test2.ps1" .$script
Finally, the Invoke-Expression cmdlet can also be used to call scripts. However, given the relative simplicity of the examples so far, there is little need to use a cmdlet for such a basic process. Invoke-Expression is capable of much more than running other scripts – for example, running commands and blocks of code from strings – and you can see examples of its use in the PowerShell help system:
get-help invoke-expression -examples
Running a PowerShell Script from Windows
Double-clicking a script in Windows File Explorer or the Desktop view, usually causes the script to open in the system’s default text editor. However, a script can be started without first opening the PowerShell console by right-clicking it and then clicking Run with PowerShell.
To change how all PowerShell scripts are treated when double-clicked:
- Right-click a script with the extension .ps1, then click Properties.
- Next to “Opens With…” click Change.
- Find the PowerShell executable on your Windows system (usually in C:\Windows\System32\WindowsPowershell\v1.0\).
In certain circumstances, you may need the PowerShell console to stay open after the script has ended. To do this, use a shortcut to the script instead:
- Right-click a PowerShell script, and then click Create shortcut.
- Right-click on the shortcut you have just created, and then click Properties.
- In the textbox labelled “Target”, add the following before the filename:
Scheduling PowerShell Scripts
Scripts can be useful for a wide variety of tasks and it can often be helpful to schedule execution of scripts so that they run on a regular basis without the intervention of the system administrator or users. This can be done using the Windows Task Scheduler.
To schedule a PowerShell script to run at a predefined interval:
- Press the Windows logo key + R, type taskschd.msc and press Enter.
- On the Actions panel, click Create Basic Task…
- Follow the steps in the wizard to set the basic information and trigger.
- When prompted, select “Start a program” as the task’s action, and click Next.
- In the textbox labelled “Program/script”, enter powershell.exe
- In the textbox labelled “Add Arguments”, enter the full path to the script in between quotation marks.
- Click Next.
- Click Finish.
Getting More Power
Although the techniques described cover various methods of running scripts, both from the PowerShell console and from Windows itself, the issues surrounding their safe execution and deployment across a network have only been explored very briefly. More information on both of these topics is provided in PowerShell: A Getting Started Guide for IT Admins at Udemy.com.