Prof. Powershell

More Fun with Get-Command

You can pull a library's worth of info with this very useful command. Here's the trick.

I find myself using the Get-Command cmdlet more and more these days. I'm always amazed at the little tidbits of information I can pull out. The cmdlet not only can tell you about other cmdlets and aliases, but also applications:

PS C:\> get-command c:\windows\notepad.exe | select *

FileVersionInfo : File:             C:\windows\notepad.exe
                  InternalName:     Notepad
                  OriginalFilename: NOTEPAD.EXE
                  FileVersion:      5.1.2600.5512
                  FileDescription:  Notepad
                  Product:          Microsoftr Windowsr
                                     Operating System
                  ProductVersion:   5.1.2600.5512
                  Debug:            False
                  Patched:          False
                  PreRelease:       False
                  PrivateBuild:     False
                  SpecialBuild:     False
                  Language:         English (United States)

Path            : C:\windows\notepad.exe
Extension       : .exe
Definition      : C:\windows\notepad.exe
Name            : notepad.exe
CommandType     : Application

The FileVersionInfo property looks especially useful. However the property is a little tricky to get by itself. Using my trusty Get-Member cmdle, I do thist:

PS C:\> get-command c:\windows\notepad.exe | select FileVersionInfo | gm

I can see that the property is a custom object with a FileVersionInfo property. As goofy as it looks, that means I can do something like this:

PS C:\> (get-command c:\windows\notepad.exe | select FileVersionInfo).FileVersionInfo | Select *

Comments :
CompanyName        : Microsoft Corporation
FileBuildPart      : 2600
FileDescription    : Notepad
FileMajorPart      : 5
FileMinorPart      : 1
FileName           : C:\windows\notepad.exe
FilePrivatePart    : 5512
FileVersion        : 5.1.2600.5512 (xpsp.080413-2105)
InternalName       : Notepad
IsDebug            : False
IsPatched          : False
IsPrivateBuild     : False
IsPreRelease       : False
IsSpecialBuild     : False
Language           : English (United States)
LegalCopyright     : c Microsoft Corporation. All rights reserved.
LegalTrademarks    :
OriginalFilename   : NOTEPAD.EXE
PrivateBuild       :
ProductBuildPart   : 2600
ProductMajorPart   : 5
ProductMinorPart   : 1
ProductName        : Microsoftr Windowsr Operating System
ProductPrivatePart : 5512
ProductVersion     : 5.1.2600.5512
SpecialBuild       :

Wow! There's even more information. Let me narrow it down:

PS C:\> (get-command c:\windows\notepad.exe | select FileVersionInfo).FileVersionInfo | Select FileName,CompanyName,FileVersion

FileName                  CompanyName             FileVersion
--------                  -----------             -----------
C:\windows\notepad.exe    Microsoft Corporation   5.1.2600.5512

Alright. I can get info for one command, how can I do it for all applications that Get-Command knows about?

I'll need to use the -CommandType parameter to limit Get-Command to applications. This command type also includes DLLs so I'll further restrict results to EXE files:

PS C:\> gcm -CommandType Application *.exe

Did you remember that gcm is the alias for Get-Command? To limit the properties I'll use hashtables with Select-Object to retrieve specific items from that FileVersionInfo property. To give myself a little flexibility I'll also assign the results to a variable:

$apps=gcm -CommandType Application *.exe | Select Name,`
@{name="Filename";Expression={$_.FileVersionInfo.Filename }},`
@{name="FileVersion";Expression={$_.FileVersionInfo.FileVersion }},`
@{name="Company";Expression={$_.FileVersionInfo.CompanyName }}

Now I can slice and dice this information any way I want:

PS C:\> $apps.count
PS C:\> $apps | where {$} | sort Company | select Company -unique

U.S. Robotics Corporation
ALWIL Software
Apple Inc.
ATI Technologies Inc.
ATI Technologies, Inc.
Borland International
Creative Technology Ltd
Creative Technology Ltd.
InstallShield Corporation, Inc.
InstallShield Software Corporation
Intel Corporation
Lexmark International, Inc.
Luis Cobian
Microsoft Corp
Microsoft Corp.
Microsoft Corp. and Executive Software International, Inc.
Microsoft Corp., Veritas Software
Microsoft Corporation
Northern Codeworks
Raxco Software, Inc.
Smart Link
Sonic Solutions
Twain Working Group

PS C:\> $apps | where {$_.filename -notmatch "^c:\\windows\\"} | Select Filename

C:\Program Files\ATI Technologies\ATI Control Panel\atiadaxx.exe
C:\Program Files\ATI Technologies\ATI Control Panel\atiiprxx.exe
C:\Program Files\ATI Technologies\ATI Control Panel\atiphexx.exe
C:\Program Files\ATI Technologies\ATI Control Panel\atiprbxx.exe
C:\Program Files\ATI Technologies\ATI Control Panel\atiptaxx.exe
C:\Program Files\QuickTime\QTSystem\ExportController.exe
C:\Program Files\Common Files\GTK\2.0\bin\gspawn-win32-helper.exe
C:\Program Files\Common Files\GTK\2.0\bin\pango-querymodules.exe
C:\Program Files\QuickTime\QTSystem\QuickTimeUpdateHelper.exe

From my perspective this is some useful information.

You may not necessarily need the code I've shown in today's lesson but I hope you'll take away the process. Start with single items and getting the information you want then slowly build more complex expressions adding a little more each time. Don't try to write a monolithic expression in one pass. Take your time and you'll be pipelining like a pro.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular