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:
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.
The shell offers three core security features related to scripts:
The shell’s execution policy can be changed in one of three ways:
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:
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.
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.
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:
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:
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.