PowerShell Tips and Tricks

At last, Windows has a powerful scripting environment. Here are five real-world ways to put PowerShell through its paces.

Microsoft Windows PowerShell has been a long time coming.

Windows has never enjoyed the powerful shell scripting environments that its Unix rivals have long included. That's changed now with the inclusion of PowerShell, Microsoft's command-line shell and scripting language, in Windows Server 2008 and a passel of other Microsoft server products as well.

Finally, Windows has a classy, robust and powerful solution that can access just about every part of the operating system. Indeed, some administrative consoles of recent Microsoft server products are simply GUI front ends for bundled PowerShell commands and scripts — such is the power of PowerShell.

If you've had a chance to play around with PowerShell a bit, read on for five tips, tricks and ideas for putting PowerShell to work in your daily computing life. (If you're not yet familiar with PowerShell, check out these resources, then meet us back here for the next step in your scripting education.) There are code snippets, sample cmdlets (pronounced "command lets") and sample scripts from which you can build your own PowerShell solutions.

Ready, class? Off we go.

1. Create your own cmdlets in PowerShell

At the heart of PowerShell is the cmdlet, a cute moniker that refers to the simplest bit of .Net-based code you can execute that actually returns a result, either from the PowerShell prompt or from a script. For example, the Get-Process cmdlet lists all processes, while the Get-PSSnapin cmdlet shows all current PowerShell snap-ins that enable new functionality.

The real power comes from creating your own cmdlets, a convenient way to save any scripts that you have developed for use later or on other machines. For example, if you have a script that queries Active Directory, finds computer names and then records their service-pack level in a table, you'd want to save that and be able to run it at a later time, or perhaps even from a central workstation that could iterate that command over a range of computers.

To create your own cmdlets, follow these three easy steps:

A: Enable scripts to run

By default, PowerShell won't let scripts run for security precautions. You can enable personal script execution by using the set-executionpolicy RemoteSigned command at the PowerShell prompt.

B: Create your scripts

Just write your PowerShell commands in a text editor, like Notepad, and use line breaks to separate the commands. If you have written DOS batch files before, this is old hat. Make sure that you save the file name with a .ps1 extension, which indicates to PowerShell that the file contains a script.

C: Run the scripts from the command prompt

You can also create an alias for your new script. If I wanted to run my Active Directory query script as mentioned above, and the script was located at H:\Scripts\AD-OSbuild.ps1, I could use NewAlias GetOSRevs H:\Scripts\AD-OSBuild.ps1 to create an alias that lets me just use the GetOSRevs command from that point forward to access the script. This saves time and finger fatigue.

2. Use robust loops in PowerShell

As we all know, loops are one of the most fundamental, but most powerful, tools of the trade for performing repetitive actions. PowerShell can support the following types of loops:

You will see these loops in action in the code snippets further down in this piece.

3. Control Active Directory in PowerShell

PowerShell can interact directly with Active Directory, reading into its database, extracting information and displaying it for you. For example, with the following cmdlet, you can display all users in Active Directory:

$Dom = 'LDAP://DC=scribnertechmediacorp;DC=local'

$Root = New-Object DirectoryServices.DirectoryEntry $Dom


# Create a selector and start searching from the Root of AD

$selector = New-Object DirectoryServices.DirectorySearcher

$selector.SearchRoot = $root


$adobj= $selector.findall() |`

where {$_.properties.objectcategory -match "CN=Person"}

foreach ($person in $adobj){



Write-host "First name: $($prop.givenname) " `

"Last Name: $($prop.sn) Display Name: $($prop.cn)"


"Total AD Users Found: $i"

To query a specific part of Active Directory — for example, a specific Users container — just use a new LDAP path as the value of the $Dom variable. (And did you see the "foreach" loop in there?)

Querying is nice, but what about creating objects? PowerShell can do that, too. To create an organizational unit called EastCoast in the domain above, use the following (replace "mercury," which happens to be my domain controller (DC), with the name of a DC in your organization):

$Dom = [ADSI]"LDAP://mercury:389/dc=scribnertechmediacorp;dc=local"

$newOU = $Dom.Create("organizationalUnit", "ou=EastCoast")


You'll probably want to create new users in this new organizational unit, too. Let's create an account for Karen Smith:

$newOU = [ADSI]"LDAP://mercury:389/ou=eastcoast;dc=scribnertechmediacorp;dc=local"

$newUser = $newOU.Create("user", "cn=KSmith")

$newUser.Put("sAMAccountName", "KSmith")


PowerShell, and its hooks into Active Directory Services Integration (ADSI), provide a great environment for scripting Active Directory administration.

4. Manage your network with PowerShell

PowerShell is eminently more flexible at managing network connections than the tools provided for the Windows command line. For example, you can easily retrieve the MAC address of all network adapters on your current machine with the following script.

$strComputer = "."

$colItems = get-wmiobject -class "Win32_NetworkAdapterConfiguration" `

-computername $strComputer | Where{$_.IpEnabled -Match "True"}

foreach ($objItem in $colItems) {

write-host "Hardware Address:" $objItem.MACAddress


You can replace the $strComputer variable with any host name that can be reached by the machine running PowerShell, making it easy to get a list of MAC addresses from around your network.

You can also see what IP addresses are active on your network, using a simple Ping cmdlet that rotates through all possible IP addresses on your local subnet. This will return a table with IP addresses and status codes, 0 indicating that the address is in use.

1..254| ForEach -Process {WmiObject -Class Win32_PingStatus -Filter ("Address='192.168.16." + $_ + "'") -ComputerName .} | Select-Object -Property Address, StatusCode | ft

PowerShell is great for interacting with your network, be it through ping status reports, or through the use of Windows Management Instrumentation (WMI) objects that find out information about network hardware in use.

5. Use object-oriented features in PowerShell

PowerShell is, at its core, an object-oriented product. In other words, all of PowerShell's features, syntax and components are based on programmatic objects. So cmdlets reveal their results as objects, variables in fact are objects, and the various syntaxes that make up PowerShell provide the ability to manipulate objects.

You can use the properties of an object, and you can call the methods an object contains. While some PowerShell users may not make much direct use of this object orientation, PowerShell lets you make use of .Net and WMI objects, both at the command line and in scripts.

Using .Net objects is pretty easy, since much of it happens by default. You can either let PowerShell determine the .Net classes by default — for example, typing LS or DIR in a file system drive produces a set of file and directory objects. PowerShell can also access COM objects, which is useful for accessing legacy applications and some parts of Windows.

An example of this is using WMI to examine the Vista Firewall. Using PowerShell, you can use the firewall COM object to obtain details of how the Vista firewall is configured. For example, the following two commands grab information on the firewall from the COM object and store the details in a variable:

$fw = new-object -com HNetCfg.FwMgr

$profile = $fw.LocalPolicy.CurrentProfile

You can now run PowerShell commands against the profile variable to determine your firewall setup. For example, to display globally open ports:

$profile.GloballyOpenPorts | ft name, port

This may not return anything, as a properly configured firewall on a regular workstation shouldn't have any open ports. But a list of authorized applications is sure to return results, unless you're buried in the depths of the CIA.

Type in this:

$profile.AuthorizedApplications | ? {$_.Enabled} | ft name

And you'll get this in return (that's not a typo, by the way; that's how Skype shows up!).



TurboTax Update Manager



Skype. Take a deep breath



Microsoft Office Outlook

That's it for today's class. For homework, I urge you to take advantage of the object-oriented nature of PowerShell. With experience and expertise, you can touch many parts of the system and turn this scripting environment into a live programming environment.

Hassell, a frequent Computerworld contributor, specializes in IT topics ranging from networking and security to Windows administration.

To express your thoughts on Computerworld content, visit Computerworld's Facebook page, LinkedIn page and Twitter stream.
7 Wi-Fi vulnerabilities beyond weak passwords
Shop Tech Products at Amazon