Click to Rate and Give Feedback
Tips
Want to implement file sharing for Windows Vista clients in a workgroup environment? Be sure to keep these best practices in mind. ...

Read more!

We show you how to use the Get-MailboxStatistics cmdlet to view who last logged in to a mailbox, last logon date and time, and message count. ...

Read more!

If you want external users or mail systems to be able to send mail to an address within your organization and then have Exchange forward this mail to an external mailbox, we list the six easy steps to get it done. ...

Read more!

SQL Server includes a number of built-in functions you can use to retrieve system information. Here's an overview of these functions. ...

Read more!

Check out the commands you can use to manage Volume Shadow Copy service from a command-line tool. ...

Read more!

Related Articles

In this first part of a two part series, security expert Jesper Johansson delves into the concept of identity - What defines an identity? Who gets to control the information, and how do we ensure it is properly secured?

Jesper M. Johansson

TechNet Magazine June 2009

...

Read more!

Continuing last month’s discussion about SharePoint integration with AD RMS, this column show you how to establish an AD RMS pre-production development environment, compile the IRM protectors, and integrate the compiled components into WSS 3.0.

Pav Cherny

TechNet Magazine May 2009

...

Read more!

Automating data entry is more important than ever, and today’s automation language is Windows PowerShell. This article uses Windows PowerShell to collect some data about the local computer and write it to an Office Access database.

The Microsoft Scripting Guys

TechNet Magazine May 2009

...

Read more!

The first in an ongoing series, Jesper Johansson discusses the broad and varied challenges faced in the field of Information Security Management and the keys to planning a sound InfoSec strategy.

Jesper M. Johansson

TechNet Magazine April 2009

...

Read more!

Don Jones continues his look at how you can use Windows PowerShell to automate user provisioning. In this installment, Don details the function that will create a mail-enabled user in Active Directory.

Don Jones

TechNet Magazine April 2009

...

Read more!

Also by this Author

Don Jones concludes his four-part series on automating user provision with Windows PowerShell. In this final edition, Don discusses adding users to domain groups and modifying directory attributes.

Don Jones

TechNet Magazine June 2009

...

Read more!

Ever wish Windows PowerShell would launch with a work environment tailored to your needs? Don Jones demonstrates how you can use profiles to customize the Windows PowerShell shell.

Don Jones

TechNet Magazine October 2008

...

Read more!

In the past few installments of the Windows PowerShell column, Don Jones has been demonstrating how to develop a Windows PowerShell-based inventory tool. In this installment, Don brings it all together into a very powerful, full-featured tool, and offers some guidance on customizing the tool for your own needs.

Don Jones

TechNet Magazine February 2009

...

Read more!

Don Jones discusses filtering functions, the pipeline, custom objects, and how ping-pong balls hold the secret to understanding Windows PowerShell.

Don Jones

TechNet Magazine July 2008

...

Read more!

Don Jones continues his four-part series that explains how you can create an automated provisioning function in Windows PowerShell

Don Jones

TechNet Magazine May 2009

...

Read more!

Popular Articles

Raymond Chen looks at the skewed relationship bugs have to errors, and explains why it's important that programmers suffer as well as give results.

Raymond Chen

TechNet Magazine October 2008

...

Read more!

Windows Vista SP1 and Windows Server 2008 introduce important changes to BitLocker, including support for data volumes and improved protection against cryptographic attacks. Byron Hynes explores the new features, demonstrates how to use BitLocker on a server, and discusses some of the recent media coverage affecting BitLocker.

Byron Hynes

TechNet Magazine June 2008

...

Read more!

Without too much effort, you can deploy a terminal server to host the applications you need in your environment. But there are some important decisions you’ll need to make to ensure your implementation meets user expectations. Greg Shields discusses the various options you have and explains how they will affect you.

Greg Shields

TechNet Magazine January 2009

...

Read more!

Drivers fail, files get corrupted, disks crash--there are numerous uncontrollable reasons why Windows might fail. But all is not lost. Wes Miller explores the kinds of things that can go wrong in a Windows system, and explains how you can troubleshoot them to get your system working again.

Wes Miller

TechNet Magazine January 2009

...

Read more!

Why do attachment sizes increase when sending and receiving e-mail messages? How can you ensure databases on a passive node in a CCR cluster are defragmented during online maintenance? Can you use an external trust between forests? We answer these questions and more.

Henrik Walther

TechNet Magazine January 2009

...

Read more!

Our Blog

NAP monitors the health of specified computers when they attempt to connect to a network and includes a number of mechanisms to enforce health requirements. In this article, Geek of All Trades Greg Shields gives readers an overview of these enforcement mechanisms and, as an example, takes a closer look at setting ...

Read more!

Use Windows PowerShell to Manage Virtual Machines Here are a few examples of how you can use Windows PowerShell scripts to manage virtual machines running on a Server Core installation. Note that these scripts are presented as samples and may need to be customized to work in your environment.

Create a New ...

Read more!

Disabling an Unused Part of Group Policy Objects One way to disable a policy is to disable an unused part of the GPO. By disabling part of a policy that isn’t used, the application of GPOs and security will be faster.

Administer Windows Server 2008 Server Core from the Command Prompt ...

Read more!

In the August 2008 issue of TechNet Magazine, Paul Randal wrote an article Top Tips for Effective Database Maintenance.  It was geared toward "involuntary  DBAs" (IT pros who inadvertently wind up responsible for a SQL Server instance).  The article had a great response from our readers so Paul has written another ...

Read more!

Microsoft Forefront is designed to deliver an integrated security solution that makes it much easier to deploy and manage security across an organization’s IT infrastructure. In this, our annual security issue, we feature two articles that describe how Forefront Security protects instant messaging and e-mail.

Protect ...

Read more!

Windows PowerShell Securing the Shell
Don Jones


When the Windows PowerShell team sat down to create a new shell and the word "scripting" floated across the table, the groans of dismay were probably audible throughout Redmond. After all, previous Microsoft efforts with administrative scripting—I'm speaking of VBScript here—were not exactly problem-free. An
overly permissive execution model, combined with the penchant of most users to log on as full administrators, opened the door for disaster.
"Surely," folks in that first Windows PowerShell™ meeting must have prayed, "we're not going to go through that again." And they haven't. Microsoft has vastly improved its security reputation, in large part because it began thinking about security first rather than later in a product's development cycle. This philosophy is very much evident in Windows PowerShell.

Why Won't My Scripts Run?
Install Windows PowerShell on a fresh computer and double-click a .ps1 file: up pops Notepad, not Windows PowerShell. This is because the .ps1 file name extension—the extension used for Windows PowerShell scripts—has no association with the shell itself. In other words, you can't run a script by simply double-clicking it. The only way to run a script is to open Windows PowerShell, type the script name, and then press Enter.
Actually, just typing the script name isn't sufficient, either. You can see in Figure 1 that the file Demo1.ps1 exists in the current folder, yet typing demo1 and pressing Enter results in an error: "The term 'demo1' is not recognized as a cmdlet, function, operable program, or script file." Why is this? After all, the file is sitting right there.
Figure 1 To avoid command hijacking, Windows PowerShell requires a path to your script (Click the image for a larger view)
This is another aspect of the Windows PowerShell security model. One trick malicious users commonly attempt in other shells is creating a script with the same file name as a built-in command. So, for example, if you wanted a user to run your script, you might name it Dir.ps1 and drop it into a folder. If you convinced the user to type Dir and press Enter, your script could run, not the Dir command the user was expecting. This technique is called command hijacking. In Windows PowerShell, you must always provide a path to such a script, making Windows PowerShell pretty well protected against command hijacking.
Running demo1 doesn't work, since there's no path, but running ./demo1 does work. This is because I've now specified a path—the current folder. That command line is less likely to be confused with a built-in command since you'd never type any kind of path if you were referring to a built-in command. Thus, requiring a path helps Windows PowerShell avoid command hijacking and confusion over what might happen when you press Enter.

A Policy for Script Execution
So you've got a freshly installed copy of Windows PowerShell, you're using the proper syntax, and you attempt to run a script. To your surprise, you're greeted with yet another error message, informing you that Windows PowerShell isn't allowed to run scripts. What??? Welcome to the shell's Execution Policy.
You can see what the current Execution Policy is by running Get-ExecutionPolicy in the shell. By default, it's set to Restricted, which quite simply means that scripts won't run. Ever. For anybody. By default, Windows PowerShell can only be used interactively, rather than to run scripts. You can use the Set-ExecutionPolicy cmdlet to choose one of four possible Execution Policy settings:
  • Restricted, the default setting, doesn't allow any scripts to run.
  • AllSigned only runs trusted scripts (more on this in a moment).
  • RemoteSigned runs local scripts without requiring them to be trusted; scripts downloaded from the Internet, however, must be trusted before they can run.
  • Unrestricted allows all scripts to run, even untrusted ones.
Frankly, AllSigned is the lowest setting any production computer should be set to. I find RemoteSigned helpful in development and test environments, but it isn't necessary for the typical user. And I see no need for Unrestricted whatsoever, and wouldn't mind if some future version of Windows PowerShell omitted this overly permissive setting.

It's a Question of Trust
Your computer is preconfigured to trust certain root Certification Authorities (CAs)—that is, servers that issue digital certificates. Figure 2 shows the Internet Options control panel application, which lists trusted root CAs. In Windows Vista®, this list is pretty short and includes only a few major commercial root CAs. By contrast, the default list in Windows® XP is large and includes many root CAs I've never heard of. When a root CA is on this list, you're essentially saying that you trust the company that operates the root CA to do a good job of verifying someone's identity before issuing a digital certificate to them.
When you obtain a Class III digital certificate—commonly called a code-signing certificate—the CA (which may be a commercial CA or a private CA that exists within your organization) must verify your identity. That digital certificate is like an electronic passport or identification card. Before giving me an ID that says I'm Don Jones, for example, the CA needs to take some steps to ensure I really am Don Jones. When you use your certificate to digitally sign a Windows PowerShell script, which you can do using the Set-AuthenticodeSignature cmdlet, you're signing your name to the script. Of course, if you're able to obtain a false certificate containing someone else's name, you can sign his name to the script, which is why it's so important that only trustworthy CAs show up on the list in Figure 2.
Figure 2 Default trusted root CAs in Windows Vista (Click the image for a larger view)
When Windows PowerShell checks to see if a script is trusted—which it does under the AllSigned and RemoteSigned Execution Policy settings—it asks three questions:
  • Is this script signed? If not, the script is untrusted.
  • Is the signature intact? In other words, has the script changed since it was signed? If the signature is not intact, the script is untrusted.
  • Was the signature created using a digital certificate that was issued by a trusted root CA? If not, the script is untrusted.
CMDLET of the Month: Set-AuthenticodeSignature
Set-AuthenticodeSignature is the key to digitally signing your Windows PowerShell scripts, allowing you to use the shell's safest execution policy, AllSigned. To use this cmdlet, you start with another—Get-ChildItem—that fetches an installed code-signing certificate:
$cert = Get-ChildItem –Path cert:\CurrentUser\my –codeSigningCert
You need to replace that file path with one that points to an installed certificate—any installed certificate will be accessible via the cert: drive. Once the certificate is loaded, run this to sign a script:
Set-AuthenticodeSignature MyScript.ps1
–cert $cert
Of course, provide the complete path to your .ps1 script file. The shell will add a signature block to the file.

How does trust improve security? Sure, a hacker could potentially write a malicious script, sign it, and convince someone in your environment to execute it. Since the script was signed, it will run. But because it was signed, you can use the signature to find the identity of the author and take appropriate action (such as calling law enforcement authorities). A person would have to be extremely stupid, though, to create a malicious script and then put his real name on it!
Of course, if a malicious user were able to get a certificate for someone else's identity—say, from a CA that didn't have a good identity-checking process—you wouldn't be able to use the signature to identify the actual culprit. This is why the root CAs you trust should have an identity-verification process you've found satisfactory.
If you use the AllSigned Execution Policy setting, you even have to digitally sign every script you produce yourself before it will run. The Set-AuthenticodeSignature cmdlet is pretty easy to use, but this can still be quite a hassle. That's where third-party software may come in handy. I recommend you select a script editor or visual development environment that will automatically sign your scripts using the certificate you specify. That way, using signatures is transparent and requires no extra effort. If you'd like suggestions for editors and development environments that support this, visit some of the online scripting forums (such as my site at ScriptingAnswers.com) and post a message asking what other Windows PowerShell fans are using.
Once you have a certificate, you can also run the following one-liner to sign all the scripts in a particular location:
Get-Childitem *.ps1 | %{Set-AuthenticodeSignature $_.fullname $cert}

Centrally Secured
The Windows PowerShell Execution Policy can, obviously, be configured on a computer-by-computer basis. But that's not a good solution for enterprise environments. Instead, you can use Group Policy. (You can download the Windows PowerShell Administrative Templates from go.microsoft.com/fwlink/?LinkId=93675.) Simply drop the file into a Group Policy Object (GPO) that affects your entire domain and set it to Restricted. That way, no matter where Windows PowerShell is installed, you can be sure that scripts won't run. Then you can apply a more permissive setting (say, AllSigned) on just those computers that should be running scripts (such as your own workstation).

Alternate Credentials
Unlike any previous administrative scripting language for Windows, Windows PowerShell even comes prepared to deal with alternate credentials in a secure fashion. For example, the Get-WMIObject cmdlet has a –credential parameter, which allows you to specify an alternate credential for remote WMI connections. The parameter will accept a user name but not a password, thus preventing you from hard-coding sensitive passwords into a clear text script. Instead, when you provide the user name, Windows PowerShell prompts you for the password using a dialog box. If you plan to use an alternate credential again, you can store the authentication information by using the Get-Credential cmdlet:
$cred = Get-Credential DOMAIN\USER
You'll be prompted immediately for the password and the final credential will be stored in the variable $cred. The $cred variable can then be passed to the –credential parameter as often as needed. You can even use the ConvertTo-SecureString and ConvertFrom-SecureString cmdlets to convert the credential into an encrypted string or to convert a previously encrypted string back into a credential.
The problem with this is that your encryption key winds up being stored in a plain text script, which completely defeats the security. So instead of doing this, you can add a call to Get-Credential to your Windows PowerShell profile. Then, when Windows PowerShell runs, you're immediately prompted for a user name and password, which are then stored in a variable named $cred. This way, you always have a $cred variable available in the shell representing a domain administrator account. And you never have to bother storing that credential anywhere—since the credential is recreated each time you open the shell, there's no need to store it.

Secure by Default
By default, Windows PowerShell is installed and configured with the most secure settings you could probably come up with for an administrative shell that supports scripting. Unless you change any of those settings, Windows PowerShell will stay as secure as it can be. In other words, anything that reduces security in Windows PowerShell is a result of your decision and your action. So before you change any of the defaults—reconfiguring file extension associations, changing the Execution Policy, and so forth—make sure you fully understand the consequences of your actions and be prepared to take responsibility for your changes.

Don Jones is the Lead Scripting Guru for SAPIEN Technologies and an instructor for ScriptingTraining.com. You can reach Don through his Web site, scriptingAnswers.com.
© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.
Page view tracker