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.
- By Jeffery Hicks
- 09/22/2009
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
(xpsp.080413-2105)
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
(xpsp.080413-2105)
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
444
PS C:\> $apps | where {$_.company} | sort Company | select Company -unique
Company
-------
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
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
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:\qpw\DBD.EXE
c:\qpw\DBDLOCAL.EXE
c:\qpw\DMODELER.EXE
C:\Program Files\QuickTime\QTSystem\ExportController.exe
C:\Program Files\Common Files\GTK\2.0\bin\gspawn-win32-helper.exe
C:\ODAPI\ODAPICFG.EXE
C:\Program Files\Common Files\GTK\2.0\bin\pango-querymodules.exe
c:\qpw\QPW.EXE
C:\Program Files\QuickTime\QTSystem\QuickTimeUpdateHelper.exe
c:\qpw\UNINSTAL.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 Petri.com, and a frequent speaker at technology conferences and user groups.