Prof. Powershell

PowerShell in Lockdown Mode

PowerShell's added security measures are in place to prevent someone from hijacking systems through scripting.

Given that there have been some security fiascos around VBScript, Microsoft was determined not to get burned again. So, by default PowerShell is one of the most secure Microsoft scripting products. PowerShell won't stop you from sitting at a console and interactively typing a malicious command -- if that person has console access, you've got bigger problems anyway. PowerShell by default protects you from malicious scripts.

You may know that a PowerShell script has a .ps1 file extension. By default, this extension is associated with Notepad. This means that when your users get an e-mail with a dangerous ps1 attachment and they open it (because you know they will), the script will open in Notepad. It won't execute. Sure, you could change the association, but if something bad happens, shame on you. There's no reason to change the association.

Second, when you want to run a script, you have to include the path as well. Thus, you can't run this at a PowerShell prompt:

PS C:\Scripts> UpdateFiles.ps1

as you'll get an error message that it's an unrecognized cmdlet. You have to do this, instead:

PS C:\Scripts> ./UpdateFiles.ps1

It may seem complicated, but the intent is to prevent command highjacking. Suppose a malicious script called dir.ps1 was placed in your directory. You type the dir alias expecting to execute Get-ChildItem. Without this check, the malicious script would run instead. But with this check, PowerShell will protect you.

PowerShell scripts can also be digitally signed with a code-signing certificate. I strongly encourage you to follow this best practice for all production scripts. This will ensure that the script has not been modified in any way and comes from a trusted source. You don't necessarily have to buy a third-party certificate; an internal PKI will work fine.

But wait. Even after you've gone through all these steps to run a script, if you have a new installation of PowerShell, it still won't run. That's because PowerShell has a script execution policy which, by default, is set to Restricted. Yep, by default PowerShell won't execute any scripts from the shell. You can use the shell interactively all you want, but just no scripts.

You can change that with the Set-ExecutionPolicy cmdlet. If you look at the cmdlet help, you will learn that the four possible settings are:

  • Restricted: Does not load configuration files or run scripts. "Restricted" is the default.
  • AllSigned: Requires that all scripts and configuration files be signed by a trusted publisher, including scripts that you write on the local computer.
  • RemoteSigned: Requires that all scripts and configuration files downloaded from the Internet be signed by a trusted publisher.
  • Unrestricted: Loads all configuration files and runs all scripts.

For production systems, the recommendation is to use AllSigned. But at a minimum, set your execution policy to RemoteSigned. Any scripts you create locally don't have to be signed and this includes scripts copied internally across your network. Even better: Microsoft has a Group Policy template that you can download for setting execution policy.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular