Claus Nielsen’s Favorite PowerShell Tips & Tricks

I use PowerShell practically every day, and I would like to share a few tips and tricks that I use quite often.

First a little bit about myself, I work as a System Administrator for a small financial institution, which has about 200 servers and 250 workstations. I am principally responsible for the Microsoft infrastructure Windows, Active Directly, DNS, Citrix XenAPP, and VMware. Fortunately, most of these products already have good PowerShell integration, so that makes my life a lot easier 🙂

Test-Online

I very often need to query a bunch of machines to gather some sort of information, or change a setting on them. One issue with querying a lot of machines using WMI for instance, is that if the machine is offline, it may take a while for the request to time out, prolonging the overall execution time of the script.

Because I do this quite often, I wrote a small function that I added to my profile—the script takes either a list of computers, a collection of Quest Active Roles Computer objects or Microsoft AD computer objects, it then tries to ping them, and depending on the result, the objects will have a property added which states if the computer is “pingable” or not.

function Test-Online {

    [CmdletBinding()]
 
    param(  
        [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
        $ComputerName
    )
	
    Process {

        Switch ($ComputerName.GetType().FullName) {
           "System.String" {$CompName = $ComputerName}
	        "Quest.ActiveRoles.ArsPowerShellSnapIn.Data.ArsComputerObject" {$CompName = $ComputerName.DnsName}
	        "Microsoft.ActiveDirectory.Management.ADComputer" {$CompName = $ComputerName.DNSHostName}
	        default {$CompName = "Input Type Not Matched"}
        }	
	
        Write-verbose "Server: $CompName"

        If(Test-Connection -Count 3 -ComputerName $CompName -TimeToLive 5 -AsJob | Wait-Job | Receive-Job | Where-Object { $_.StatusCode -eq 0 } ) {
            Add-Member -InputObject $_ -MemberType NoteProperty -Name OnlineStatus -Value $true
            Return $_
        }
        Else {
            Add-Member -InputObject $_ -MemberType NoteProperty -Name OnlineStatus -Value $false
            Return $_
        }
    }
}

With the above script, I can test a single computer or a collection of computers if they are online, and since I am using jobs I can test multiple computers at a time, thereby greatly reducing the time it takes.  I add a NoteProperty  called “OnlineStatus” , which is either $true or $false, I can then query this property to check if a computer is online or not, before I do a WMI query against the machine.

So, let’s say I want to test computer Server1 and Server2:

"Server1","Server2" | Test-Online

If I want to use the Quest AD cmdlets I can simply do:

Get-QADComputer | Test-Online | Select-Object Name, OnlineStatus

That will run through all computers in AD, and check if they are online, and output their name and “OnlineStatus”.

Show-ControlPanelItem

Another command I have only started using recently is the Show-ControlPanelItem cmdlet (works only in v3).

This allows you to start control panel applets from PowerShell without having to click the Start menu and choose “Control Panel”, or that I have to remember the *.cpl names, which for some applets are pretty gnarly.

So if I want Internet Explorer settings, I used to run inetcpl.cpl. Now, I can do scp *internet*  (scp is an alias I created for Show-ControlPanelItem, and *internet* is much easier to remember than inetcpl.cpl.

One thing to be aware of is that if you do Show-ControlPanelItem *i*, it will open all Control Panel applets containing the letter “I”.

You can also use Get-ControlPanelItem to get a list of all available Control Panel applets.

Get-Folder

Sometimes when looking for a folder, it is easier to use the graphical interface than traversing directories using cd and dir. A long time ago, I wrote a function to get a graphical folder browser using the Shell.Application COM object.

Function Get-Folder {
	$obj = New-Object -ComObject Shell.Application
	$bf = $obj.BrowseForFolder(0,"Choose Folder",0,"")
	$bf.Self.Path
}

By using the technique that the command within parenthesis gets evaluated first, we are now able to do something like:

Get-ChildItem (Get-Folder)

The above command will open a GUI which you can use to select a file. The Get-Folder is evaluated first, since it is enclosed in (), and then the folder you choose in the GUI is passed to Get-ChildItem which will list its content.

About the author: Claus Nielsen

Claus Thude Nielsen work as a Senior Systems Administrator at a large pension fund in Copenhagen, Denmark. He is primarily responsible for the company’s Microsoft Platform including Windows,Exchange, SharePoint etc, but also built the company’s VMware ESX and Citrix platforms. On a daily basis he spends most of his time automating processes using PowerShell across the different platforms. In 2011 Claus was awarded with the Microsoft Most Valuable Professional (MVP) Award for his work with PowerShell.

Related Posts

%d bloggers like this: