Windows PowerShell Script Security

Excerpted from Microsoft Official Course 10325, Automating Administration with Windows PowerShell 2.0. Get a taste of this brand-new instructor-led course, written by Don Jones and Greg Shields of Concentrated Technology, LLC.

The script security features for Windows PowerShell are specifically designed to help prevent some of the scripting-related security problems of older technologies, including Microsoft Visual Basic Scripting Edition (VBScript). Windows PowerShell defaults to a secure state and enables you to modify that state to accommodate your scripting needs and a variety of security goals.

After completing this lesson, you will be able to:

  • Explain the script security features, including filename extension association, execution policy, and current path searching.
  • Explain the role of trusted root Certification Authorities (either commercial or private) in shell script security.
  • Set the shell execution policy locally and in a domain environment.
  • Explain how to digitally sign a script.

Script Concerns

The IT industry has had ample experience with the security problems that scripting languages can create. The main security problem is that scripts can be an easy way to introduce malware into an environment, primarily because users can be convinced to execute scripts without really understanding what the script is doing or that they are even running a script.

The Windows PowerShell security features are intended to create a “secure by default” environment in which users cannot easily or unknowingly run scripts. This is not to say that the shell makes it impossible for users to run scripts because it does not. Rather, the shell makes it difficult—by default—for users to run scripts without realizing they are doing so.

The shell’s default security configuration is rarely convenient for someone who wants to run scripts frequently, and so the shell can be reconfigured to make script execution more convenient. This reconfiguration does make it somewhat easier for malicious scripts to enter the environment, and so the shell offers a range of security settings that let you strike the balance you want between convenience and security.

Script Concerns


Security Features

The shell offers three core security features related to scripts:

  • The .ps1 filename extension used to identify Windows PowerShell scripts is not registered with Microsoft Windows® as an executable file type. By default, double-clicking a .ps1 file does not run the script (although it may open it in an editor such as Windows Notepad or the Windows PowerShell ISE).
  • The shell does not search the current path for script files. Thus, if you type myscript into the shell, it does not execute the myscript.ps1 file that may be located in the current directory. Instead, you would need to specify either an absolute or a relative path—such as ./myscript—to the script. This behavior helps to prevent a form of attack called command hijacking, where a script executes instead of an internal command that has the same name.
  • The shell has a script Execution Policy that determines what scripts are permitted to run, and by default this setting is set to Restricted, which disables script execution entirely.

Security Features

Execution Policy

The shell’s execution policy can be changed in one of three ways:

  • By Group Policy. A downloadable Group Policy administrative template is available from; this template is built into Windows Server 2008 R2. Any execution policy set via Group Policy overrides any locally configured setting.
  • By Administrators. Running the Set-ExecutionPolicy cmdlet enables an administrator to change the system-wide execution policy on a given computer, provided the computer is not subject to a Group Policy setting as described previously. The systemwide execution policy is stored in the HKEY_LOCAL_MACHINE registry hive, which is normally writable only by local Administrators of the computer.
  • By Users. Users can execute Windows PowerShell using powershell.exe and a command-line parameter that changes the execution policy for the duration of that shell session. This action overrides any local setting.

It may seem odd to permit users to override an administrator-established value for the execution policy, but remember that the execution policy is intended to help stop unintended script execution. It is not intended to stop skilled users from executing scripts at all, merely to ensure that they do not do so without knowing what they are doing. Running Powershell.exe and specifying a command-line parameter is definitely not something that can easily be accomplished by accident.

There are five settings for the execution policy:

  • Restricted. This is the default setting, and Windows PowerShell does not execute scripts, except for a few Microsoft-provided, digitally-signed scripts that contain shell configuration defaults.
  • RemoteSigned. This setting allows any script to be executed. However, remote scripts—those executed from a network location, those downloaded from the Internet using Internet Explorer, or those received in e-mail in Microsoft Office Outlook—must carry an intact, trusted digital signature.
  • AllSigned. This setting allows any script to execute provided it carries an intact, trusted digital signature.
  • Unrestricted. This setting allows any script to execute.
  • Bypass. This setting bypasses the execution policy entirely, allowing any script to execute. This setting is primarily intended for developers who embed the shell inside another application, where the developer plans to provide their own security model rather than using the shell’s own.

Note: If you attend this class at a Microsoft Learning Partner, your instructor will lead the class in a demonstration of script security configuration.

Execution Policy is Not Anti-Malware

A determined user cannot be stopped from running a Windows PowerShell script simply by setting the execution policy. That is not the purpose of the execution policy.

Nor is the execution policy intended as a form of anti-malware. The execution policy is intended only to help prevent users from unknowingly running a script and to help users identify scripts that might be considered “trusted” and possibly safer to run.

Keep in mind that no user can use a shell script to perform some task for which they do not have permission. In other words, a normal non-administrator couldn’t run a script to delete every user in Active Directory because the user wouldn’t have the necessary permissions to do so. Simply being able to run a script doesn’t change what someone can do with that script.

Trusted Scripts

Two of the shell’s execution policy settings—RemoteSigned and AllSigned—utilize digital certificates and trust to identify “trusted” scripts.

So what is trust?

Trust starts with a root Certification Authority, or root CA. There are public CAs, and there are private companies that provide such certificates as a service, for a cost. Many companies also have their own private root CAs. When you say that you “trust a CA,” you are saying that you have reviewed that CA’s policies for verifying the identity of the people or companies to whom the CA issues digital certificates.

A digital certificate is a form of digital identity card. A digital certificate attests to the actual identity of a person or company, but that attestation is only as good as the trust you place in the company that issued the certificate. In other words, if a company contacts you online and claims to be Microsoft Corporation, you might look at their digital certificate. If their certificate also claims that the company is Microsoft Corporation, you would look at the issuer of that certificate to see whether you trust them to have researched the company’s identity very thoroughly before issuing that certificate.

If you trust the CA to have done a good job of verifying the company’s identity, you also trust the certificate they issued to that company. If that certificate is used to digitally sign a script, you also trust that script. That doesn’t mean the script is beneficial or even free of malware; it simply means that you can identify the script’s signer, and an intact signature ensures that the script was not modified because it was signed.

A digital signature is made using the encryption keys that are part of a digital certificate. The signature includes information about the certificate, including the identity of the certificate holder. The signature also contains encrypted information that can be used to verify the script’s contents. If the signature and the contents of the script match, you know who signed the script, and you know that the script is exactly the same as it was when they signed it. Again, that does not mean the script is harmless—but if it turned out to be malicious, you could use the certificate information from the signature to track down the signer.

* If you want to see what a digital signature looks like, run this command in Windows PowerShell: type $pshome/types.ps1xml. The gibberish at the end of the file is the digital signature. You can check the status of the file’s signature by running get-authenticodesignature $pshome/types.ps1xml.

Trusted Scripts

Signing a Script

To sign a script, you first need to obtain a trusted digital certificate.

One way to do obtain one is from a public or private CA. Public CAs generally charge a yearly fee for certificates. Private CAs are ones owned by your company and may be based on Windows Certificate Services or another certificate-management product.

The type of certificate you need is a Class 3 certificate, also known as a code signing certificate. From a public CA, these are commonly more expensive than the Class 1 certificates used to encrypt or sign e-mails, and these also require usually more stringent identity verification. Many CAs offer different variants of code signing certificates; you need a Microsoft AuthentiCode style certificate.

You can also generate a locally trusted certificate using the MakeCert.exe tool, which is available as part of the Windows Platform SDK. In Windows PowerShell, run this command to learn about MakeCert.exe and how to use it:

Help about_signing

A locally trusted certificate is trusted only by your local computer. Scripts signed using this kind of certificate are trusted for execution only on your local computer.

After you have installed a certificate, you use the Set-AuthenticodeSignature cmdlet to apply a signature to a script. The help file for this cmdlet contains details on how to use it, along with usage examples.

*  Read the help for Set-AuthenticodeSignature, and review some of its options. Can you find an example of how to use it to sign a script?

Discussion: Selecting an Execution Policy

In practical use, the RemoteSigned execution policy is useful because it assumes that local scripts are ones that you create yourself, and you trust them. It does not require those scripts to be signed. Scripts that are downloaded from the Internet or received via e-mail, on the other hand, are not trusted unless they carry an intact, trusted digital signature. You could certainly still run those scripts—by running the shell under a lesser execution policy, for example, or even by signing the script yourself—but those are additional steps you have to take, so it is unlikely that you would be able to run such a script accidentally or unknowingly.

The AllSigned execution policy is useful for environments where you do not want to accidentally run any script unless is has an intact, trusted digital signature. This policy is less convenient because it requires you to digitally sign every script you write, and re-sign each script each time you make any changes to it.

Note: Some third-party Windows PowerShell script editors can automatically sign your scripts for you, making the process more transparent and less inconvenient.

The Restricted execution policy is perfect for any computer for which you do not run scripts or for which you run scripts only rarely. (Keep in mind that you could always manually open the shell with a less-restrictive execution policy.)

The Unrestricted execution policy is not usually appropriate for production environments because it provides little protection against accidentally or unknowingly running untrusted scripts.

What execution policy might be appropriate for your environment? Why?

Note: If you attend this class at a Microsoft Learning Partner, your instructor will lead the class in a demonstration of signatures and CAs.

Want more? Attend the full course at a Microsoft Learning Solutions partner near you and learn how to:

  • Explain how Windows PowerShell works.
  • Use Windows PowerShell as an interactive, command-line shell.
  • Use Core Windows PowerShell cmdlets for everyday purpose.
  • Customize the output using Windows PowerShell Formatting Subsystem.
  • Explain what Windows Management Instrumentation (WMI) is and how it can be used from Windows PowerShell.
  • Manage Active Directory objects using Windows PowerShell cmdlets.
  • Write basic Windows PowerShell scripts that execute batches of commands.
  • Work with Windows PowerShell’s background jobs and remote administration functionality.
  • Master the scripting language of Windows PowerShell.
  • Use advanced techniques related to structured programming within Windows PowerShell.
  • Automate Windows Server 2008 R2 Administration using Windows PowerShell.
  • Identify the best practices for working with Windows PowerShell.

All Microsoft Official Courses—including this one--are delivered by Microsoft Certified Trainers (MCTs)—industry-recognized experts—and offered through a network of more than 1,500 Microsoft Certified Partners for Learning Solutions (Learning Solutions partners) in more than 120 countries and regions throughout the world.