June 9th, 2011

Use Console Apps to Supercharge PowerShell

Summary: Learn how to supercharge your Windows PowerShell experience by using freely available console applications.

Microsoft Scripting Guy, Ed Wilson, here. This week we will have one guest blogger for the entire week. Sean Kearney has written a series of blog posts about Windows PowerShell and the Legacy. I am not going to be redundant by reposting his biography each and every day.

Integrating Windows PowerShell with Legacy Environments—Part 4

Note: This is part four of a five part series of articles about interacting with the legacy. Part one talked about retrieving exit codes, part two discussed working with exit codes. Part three talked about passing parameters to legacy commands, and today we are going to talk about using legacy commands in a Windows PowerShell environment.

One of the things we should remember when we try to solve problems with Windows PowerShell is to not forget that we have a massive bag of tools already on the hard drive. In fact, if you were to query a directory of your standard System32 folder, you would find over 500 applications available to us. 

Netsh.exe, Net.exe, and Dsquery.exe are all great applications. Some apps are a bit pointless in the modern day (like Diskcopy.com and Graphics.com…but, yes, they are still sitting there for some legacy purposes in Windows 7). Some are dead, simple and perfect (like DriverQuery.exe, Ping.exe, and even Hostname.exe).

Some are incredibly powerful, but they have a command structure that renders them almost useless on a day-to-day basis, unless you memorize how to use that one application. I have found with these particular apps, even Albert Einstein would be butting his head against the wall. (Yes, Netsh.exe, Netdom.exe, and Iscsicli.exe, I am picking on you!)

Then there are third-party console applications that we can use to solve individual needs (like Handle.exe from Sysinternals). Speaking of Sysinternals, here is a picture of the Scripting Wife at TechEd 2011 getting her autographed copy of Mark Russinovich’s novel.

Photo of Scripting Wife and Mark Russinovich

All of these applications share a common brotherhood called the console. What we can do with all of them (as we see fit or have a need for) is to wrap them inside an advanced function or a Windows PowerShell script to make them more useful on a daily basis.

Let’s take Dsquery.exe, for example. I could install Quest Active Roles on my computer to manage Active Directory. But what if I wasn’t permitted to modify the software base, and I could only have company-sanctioned applications on the system? This is not a problem. Let us say that you wanted to query your domain for all domain Admins. With Dsquery.exe, you would normally execute the following:

dsquery group -name “Domain Admins” | dsget group -members | dsget user -Display –upn

Wow! That’s a mouthful! But it works. The problem is, do you want to execute that each time? No. You could write it into a batch file, too. Or you could do this in Windows PowerShell and make it into a brand new cmdlet by using an advanced function.

We’re going to make this so we can drop in any group name and make a one liner for our daily work:

function global:GET-HSGGroupMember {

param([string]$GroupName)

Return (dsquery.exe group -name $GroupName | dsget group -members | dsget user -Display -upn)

}

Although by itself, this would have met our needs, something we can do with it now is to pull out the data and return something that we can use in Windows PowerShell. For this particular example, we’re going pull the content out of each line and return it as two arrays ($DisplayName and $UPN).

To pull this off, we need to pull the content out of the object that is returned. Fortunately, it comes out in a clean format. The first line is the title, the final line is the status, and the middle contains the goodies we want.

So a slight change to our function…we’ll store the $Results and extract and clean them for our two new arrays:

function global:GET-HSGGroupMember {

param([string]$GroupName)

          $Results= (dsquery.exe group -name $GroupName | dsget group -members | dsget user -Display -upn)
          #
          # Start at the first line of actual information and stop BEFORE the status
          #
          Foreach ($line in 1..(($Results.Count)-2)) {

               $UPN=$Results[$line].substring(2,31).trim()
               $DisplayName=$Results[$line].substring(33).trim()
               [Array]$DataReturn+=@{UPN=$UPN;DisplayName=$DisplayName}

          }
     Return $DataReturn
}

Now we have the ability to simply execute the following:

GET-HSGGROUPMEMBER –Groupname “Domain Admins”

We can pull down that information in a more manageable fashion, and we did not need to add a third-party solution to the equation. Now that we know we can extend the native console applications, we could automate the things we could before and manipulate data in more interesting ways.

Is this the best way to build this? Of course not. This is simply an example of how you could leverage Windows PowerShell.

Windows PowerShell is a tool to meet your needs on your own terms. But it most certainly is not a foe to the Legacy. Remember, the Power of Shell is in you. Use it how it meets your needs.

Guest blogger week will continue tomorrow when Sean will continue to talk about Windows PowerShell and the Legacy. A special thank you to Sean for writing this week’s blog posts. Hope you enjoy them.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Author

0 comments

Discussion are closed.