So, you’re all excited about this PowerShell thing – You went and bought a couple of books, started browsing the web, and were looking forward to having a tool kit chock full of scripting goodness.
The first thing you did was start PowerShell. I am assuming here that you were running PowerShell 2.0 (x64) because you were wanting to use it with SharePoint 2010. If you are not sure what version you have, take a look at my previous post about PowerShell versions – http://blog.sharepointcookbook.com/2010/06/what-version-of-powershell-am-i-using.html
So you went and downloaded a killer looking .PS1 script from Microsoft or some other place, and proceeded to run it on your system. You opened the PowerShell window, tried to run the script “./MyNewDownloadedScript.ps1”, and PowerShell refused to run your script saying “the execution of scripts is disabled on this system”.
Now what? Well, this restriction is a well-intentioned (and pretty effective) effort on Microsoft’s part to keep us SharePoint Admins from downloading PowerShell code that may be buggy or malicious in origin.
If you do a typical internet search on this error message, you’ll find that the default setting for the Execution Policy is set to “Restricted”. You can see this in the PowerShell environment by typing Get-ExecutionPolicy.
A little more searching, and Voila! You have one solution – simply shut off the ExecutionPolicy by typing Set-ExecutionPolicy Unrestricted. Now you can just run your scripts.
But wait a second, what did you just do? Is this really the right solution in the long term?
Looking at the screenshot above, did you notice the warning - “Changing the execution policy might expose you to security risks”? Setting the Execution Policy to Unrestricted simply bypassed all of the security measures meant to protect you from potentially damaging PowerShell scripts. What’s worse is that this setting will survive a reboot of the server. That’s right, the security stays off until you tell it to come back on!!!
It will even survive an uninstall and reinstall of PowerShell.
I’m just like you. I usually would not have a problem turning the Execution Policy off, running a known, trusted script I downloaded from the web, and then turning the Execution Policy back on. But someday I am going to get a phone call, lunch invite, or help desk ticket that is going to help me forget to turn the Execution Policy back on. When that happens, I will not have any security in place – Not good.
So, what’s a good SharePoint admin to do? As usual, we have to read the manual, or in this case, the help file. To see help about Execution Policies, type in help about_Execution_Policies in your PowerShell window.
Lots of reading in that one – pages and pages of information. In fact, you may be surprised how many different settings can be affected by one tiny PowerShell command. But what we care about (for now) is the Execution Policies – there are six total, but really only need to know about four. We already know about “Restricted” and “Unrestricted”, but there are two new ones:
- AllSigned – Will run all scripts that are signed by a trusted publisher (either home-grown or from the Internet)
- RemoteSigned – Will run all scripts that are signed by a trusted publisher AND will run any script that is written on the local computer
In my case, I did not want to set up the infrastructure necessary to sign my PowerShell script. So I chose to look at the Remote Signed option. And I wondered how could take a script that I had downloaded and use it as a “local” script?
Well, obviously, the first order of business is to look at the contents of the script to make sure that there is nothing malicious inside it. So far, so good.
Something in Windows itself knows that we downloaded this script; that something is the Alternate Data Stream (ADS). Alternate Data Stream (ADS) information is added by NTFS when a file is downloaded from the internet. To see the Zone.Identifier information for a downloaded script, open a Command Prompt, change to the directory where your script is stored and type in DIR/R.
Both the file itself and another version of the listing (with :Zone.Identifier:$DATA appended to the end of it) appear in the file system. The one with the zone.identifier suffix is the Alternate Data Stream. To review the contents of this file, we simply open it up in Notepad by typing
notepad MyNewDownloadedScript.ps1:zoneidentifier
All this file does is state the origin of the file by ZoneId, per this MSDN PowerShell article – http://blogs.msdn.com/b/powershell/archive/2007/03/07/how-does-the-remotesigned-execution-policy-work.aspx
This article states that items with a ZoneId greater than or equal to 3 are considered remote.
Decision Time – At this point, you can either:
- Remove the Zone.Identifier information from this file, or
- Change the ZoneId value to 2 to indicate that it is “Trusted”
Either of these choices would assume that you have actually reviewed the PowerShell script and deemed it to be safe.
Removing the Zone.Identifier
To remove the Zone.Identifier, you can download and use the streams utility by Mark Russinovich from http://technet.microsoft.com/en-us/sysinternals/bb897440.aspx, or you can simply remove the Zone.Identifier using the command line:
echo.>MyNewDownloadedScript.ps1:Zone.Identifier
Changing the Zone.Identifier
I much prefer this method because (1) the Zone.Identifier tells me that I most likely did download and review the file at some point, and (2) it’s fairly easy to change ZoneId value from a “3” to a “2”. To change the Zone.Identifier, type:
notepad MyNewDownloadedScript.ps1:ZoneIdentifier
Change the ZoneId value to 2, and save the file.
Don’t miss this part!
You really should not to run your file with the Execution Policy set to Unrestricted. Open up PowerShell (don’t forget to run as Administrator) and set your Execution Policy to RemoteSigned by typing:
Set-ExecutionPolicy RemoteSigned
and choosing [Y] Yes at the prompt
You now have a system that can accept either signed PowerShell scripts –or– locally generated/modified PowerShell scripts. If you ever do convert your entire environment to using fully signed scripts, all you need to do is revisit these servers and change the Execution Policy to “Signed”. In addition, all Execution Policy settings we have made are addressable by Group Policy in your environment.