Prof. Powershell

Process Buried Treaure

PowerShell can dig up information on processes pretty easily. It's all in the FileVersion property.

In a Windows environment, processes don't happen in a vacuum or spontaneously arise. There is always some file that was invoked or executed to launch the process. Unfortunately, this information is usually buried deep within the process. However, we have PowerShell, so digging up this buried treasure is pretty easy.

The file information is technically not stored with the process but with the modules that started the process. Because this is information an IT Pro might be interested in, the Windows PowerShell team drilled down and brought this information to the surface. If you look at the member properties for a process object, you'll see a property called FileVersion:

PS C:\> get-process -id $pid | get-member fileversion

TypeName: System.Diagnostics.Process

Name         MemberType      Definition
----         ----------      ----------
FileVersion  ScriptProperty  System.Object FileVersion {get=$this.Mainmodule.F...

Technically this is a ScriptProperty which simply means there is a bit of PowerShell code behind the scenes that generates the value. We really don't care about the code, only the result:

PS C:\> get-process winword | select Name,Fileversion

Name      FileVersion
----      -----------
WINWORD   14.0.6024.1000

Or you may want to get version information for all your processes:

PS C:\> ps | where {$_.Fileversion } | select name,fileversion -unique

Name                  FileVersion
----                  -----------
cAudioFilterAgent64   1, 7, 6, 0
cfp                   5, 8, 213334, 2131
chrome                15.0.874.121
communicator          4.0.7577.0 built by: lcs_se_w14_main...
conhost               6.1.7600.16385 (win7_rtm.090713-1255)
csrss                 6.1.7600.16385 (win7_rtm.090713-1255)
dpupdchk              8.20.469.0
...

This command gets all processes that have a FileVersion property and writes a unique list, so I can skip duplicates. Actually, you may want to run the opposite here and find files that do not have a fileversion property:

PS C:\> ps | where {! $_.Fileversion } | select name,path

Name         Path
----         ----
audiodg
Idle
NMSAccessU   C:\Program Files (x86)\CDBurnerXP\NM...
System

On my system, these are OK, although for some reason the CDBurnerXP file doesn't have complete file information. But you would want to investigate anything you didn't recognize.

The FileVersion property is retrieved from the underlying file found in the Path property:

PS C:\> get-process winword | select -ExpandProperty path | get-item | select -expand VersionInfo | format-list

OriginalFilename : WinWord.exe
FileDescription  : Microsoft Word
ProductName      : Microsoft Office 2010
Comments         :
CompanyName      : Microsoft Corporation
FileName         : C:\Program Files\Microsoft Office\Office14\WINWORD.EXE
FileVersion      : 14.0.6024.1000
ProductVersion   : 14.0.6024.1000
IsDebug          : False
IsPatched        : False
IsPreRelease     : False
IsPrivateBuild   : False
IsSpecialBuild   : False
Language         : Language Neutral
LegalCopyright   : © 2010 Microsoft Corporation. All rights reserved.
LegalTrademarks  :
PrivateBuild     :
SpecialBuild     :

The ProductVersion, Company and ProductName are also bubbled up as a ScriptProperties:

PS C:\> get-process | Where {$_.FileVersion} | select ID,Path,Name,*version,Product,Company

Id             : 3612
Path           : C:\Program Files\CONEXANT\cAudioFilterAgent\cAudioFilterAgent64.exe
Name           : cAudioFilterAgent64
FileVersion    : 1, 7, 6, 0
ProductVersion : 1, 7, 6, 0
Product        : Conexant High Definition Audio Filter Agent
Company        : Conexant Systems, Inc.

Id             : 4108
Path           : C:\Program Files\COMODO\COMODO Internet Security\cfp.exe
Name           : cfp
FileVersion    : 5, 8, 213334, 2131
ProductVersion : 5, 8, 213334, 2131
Product        : COMODO Internet Security
Company        : COMODO
...

There is one drawback to these techniques: They only work locally. Even though Get-Process has a -computername parameter, you can't get this type of version information remotely. You'll need to rely on PowerShell remoting and use either Invoke-Command or Start-Job.

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.

comments powered by Disqus
Most   Popular