Author Posts

January 1, 2012 at 12:00 am

by Bueno at 2013-02-10 17:30:32

Hi all,

First off, I am newb.

I'm trying to obtain a list of running processes and display each processes name, owner name and if possible the description. I plan to use this on remote machines. I am having difficulty in displaying the information exactly how I want it.

I started out using the get-process cmdlet;

get-process | select name,description | sort description, name | format-table -AutoSize

This displays the name and description exactly how I want but there are no properties or methods which can be used to obtain the owner. I then started looking at WMI.

Firstly, I noticed that the description is not as useful as the get-process cmdlet description property is. It always displays the same information as the process name. I do not know how to get around this.
I am able to list all process owners using the following;

Get-WmiObject win32_process | foreach {$_.getowner().user}

I don't know how to go about retrieving the name property of win32_process as well as returning the user parameter of the getowner method. I did find this which seems to do the job, but I dont really understand what is happening after the @ symbol. My understanding is that @ is used to create an array.

Get-WmiObject win32_process | Select-Object Name,@{n='Owner';e={$_.GetOwner().User}}

My last problem is that getowner only returns the SYSTEM, LOCAL SERVICE and NETWORK SERVICE user names on Windows 7 machines and below. On my windows 8 machine, the owner for the same processes is empty.

Server 2008 r2 Example;
PS C:\Windows\system32> Get-WmiObject win32_process | Select-Object Name,@{n='Owner';e={$_.GetOwner().User}} | sort nam
e

Name Owner
---- -----
conhost.exe bueno
conhost.exe bueno
csrss.exe SYSTEM
csrss.exe SYSTEM
dfsrs.exe SYSTEM
dfssvc.exe SYSTEM
dllhost.exe SYSTEM
dns.exe SYSTEM
dwm.exe bueno
explorer.exe bueno
ismserv.exe SYSTEM
lsass.exe SYSTEM
lsm.exe SYSTEM
Microsoft.ActiveDirectory.WebServices.exe SYSTEM
mmc.exe bueno
mmc.exe bueno
msdtc.exe NETWORK SERVICE
powershell.exe bueno
services.exe SYSTEM
smss.exe SYSTEM
spoolsv.exe SYSTEM
svchost.exe LOCAL SERVICE
svchost.exe NETWORK SERVICE
svchost.exe NETWORK SERVICE
svchost.exe LOCAL SERVICE
svchost.exe LOCAL SERVICE
svchost.exe SYSTEM
svchost.exe SYSTEM
svchost.exe NETWORK SERVICE
svchost.exe LOCAL SERVICE
svchost.exe LOCAL SERVICE
svchost.exe NETWORK SERVICE
svchost.exe SYSTEM
svchost.exe NETWORK SERVICE
System
System Idle Process
taskhost.exe bueno
TPAutoConnect.exe bueno
TPAutoConnSvc.exe SYSTEM
TrustedInstaller.exe SYSTEM
vds.exe SYSTEM
vmtoolsd.exe SYSTEM
vmtoolsd.exe bueno
VMToolsHookProc.exe bueno
wininit.exe SYSTEM
winlogon.exe SYSTEM
WmiPrvSE.exe NETWORK SERVICE
wuauclt.exe bueno

Windows 8 Professional Example

PS D:\Users\Bueno> Get-WmiObject win32_process | Select-Object Name,@{n='Owner';e={$_.GetOwner().User}} | sort name

Name Owner
---- -----
armsvc.exe
atieclxx.exe
atiesrxx.exe
CCC.exe Bueno
conhost.exe Bueno
conhost.exe Bueno
csrss.exe
csrss.exe
dwm.exe
explorer.exe Bueno
firefox.exe Bueno
hkcmd.exe Bueno
igfxpers.exe Bueno
KeePass.exe Bueno
lsass.exe
MOM.exe Bueno
MSIAfterburner.exe Bueno
MsMpEng.exe
PnkBstrA.exe
powershell.exe Bueno
powershell_ise.exe Bueno
RTSS.exe Bueno
RuntimeBroker.exe Bueno
SearchIndexer.exe
services.exe
smss.exe
spoolsv.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
System
System Idle Process
taskhostex.exe Bueno
Taskmgr.exe Bueno
vmnat.exe
vmnetdhcp.exe
vmplayer.exe Bueno
vmware-authd.exe
vmware-unity-helper.exe Bueno
vmware-usbarbitrator64.exe
vmware-vmx.exe Bueno
vprintproxy.exe Bueno
wininit.exe
winlogon.exe
wkspbroker.exe Bueno
WmiPrvSE.exe
wmpnetwk.exe
WWAHost.exe Bueno

Why is this?

Any and all advise will be appreciated! Please let me know if I make no sense!

by poshoholic at 2013-02-11 11:54:19

Hi there,

You ask a lot of great questions, and this is much more challenging than it seems like it should be. First I'll highlight a few important points about the problem, and then provide my recommendation on how you can solve it.

1. Get-Process returns objects of type System.Diagnostics.Process. These objects do not provide access to retrieve the process owner. This is why Get-Process does not include owner information, which you already discovered.
2. Get-WmiObject can be used to get the owner easily enough (again, as you discovered); however, it does not give you the process description (which is really the description property from the version information for the file that the process is running).
3. Both Get-Process and Get-WmiObject can be used to retrieve information remotely.
4. Neither Get-Process nor Get-WmiObject requires PowerShell Remoting to be enabled on the remote computer in order for them to work; however, Get-Process will only retrieve the process description from the local system (or the remote system if and only if you are running it through PowerShell remoting).
5. You can combine the results of Get-Process and Get-WmiObject to show the information you want to show.
6. The @ symbol is not just for arrays. @{} is a hashtable. @() is an array. @SomeVariable is used in splatting. In this case, when you're defining custom properties on the fly, you're using a hashtable, with the first hashtable value (name, or n for short) for the name of the property and the second hashtable value (expression, or e for short) as the expression used to calculate the value.

The biggest challenge in the list of points above is number 4. You want to get Name, Description, and Owner, however you can only get Description using Get-Process, and only when it is invoked locally or remotely using PowerShell Remoting. This is because WMI doesn't provide this information, not even in the CIM_Datafile class if you look up the file version properties. From what I found through Google search, it seems it is only accessible using Win32 APIs that run locally on a system. Since you want to query remote machines, that means you need PowerShell Remoting to be enabled on those systems in order to get the description.

If that isn't a big deal, well then your solution is pretty straightforward and it would look something like this:

# Identify the name of the remote computer you want to query
$computerName = 'SomeRemoteComputerName'
# Invoke the command on the remote system to get the information that is necessary
Invoke-Command -ComputerName $computerName -ScriptBlock {
# Build a hashtable that associates process ids with owners
$processOwners = @{}
Get-WmiObject -Class Win32_Process | ForEach-Object {
$processOwner = $_.GetOwner()
# Combine the domain and user information together to get the process owner
$processOwners[[int]$_.ProcessId] = $processOwner.Domain + '\' + $processOwner.User
}
# Now get all processes and add the owner information to them
Get-Process | ForEach-Object {
$processOwner = $null
# If we have process owner information for the process, look up the owner in the table
if ($processOwners.ContainsKey($_.Id)) {
$processOwner = $processOwners[$_.Id]
}
# Add the owner information to the current process object
Add-Member -InputObject $_ -MemberType NoteProperty -Name Owner -Value $processOwner
# Return the current process object from the script block
$_
} | Select-Object Name,Owner,Description
}

I think you need to decide if requiring PowerShell Remoting to be enabled on the remote systems is an issue or not. If not, this will do what you need. If so, you need to consider dropping description from your list of required properties because it isn't easily retrievable remotely without PowerShell Remoting.

by Bueno at 2013-02-14 06:02:37

Hi,

Many thanks for the prompt response.

I have never used hash tables before which most likely explains why I couldn't figure this problem out myself. I kind of knew that I would have to do this in 2 steps but I didn;t know how to correctly store the information.

I already have PS-Remoting enabled in my domain so this will not be a problem.

Again, many thanks!

September 4, 2014 at 4:23 am

hi

i used your script but since you copy pates it, it seems to be broken.
All spaces got transformed in weird characters.

Would it be possible to post a clean copy?

# Identify the name of the remote computer you want to query$computerName = "SomeRemoteComputerName"# Invoke the command on the remote system to get the information that is necessaryInvoke-Command -ComputerName $computerName -ScriptBlock { # Build a hashtable that associates process ids with owners $processOwners = @{} Get-WmiObject -Class Win32_Process | ForEach-Object { $processOwner = $_.GetOwner() # Combine the domain and user information together to get the process owner $processOwners[[int]$_.ProcessId] = $processOwner.Domain + "\" + $processOwner.User } # Now get all processes and add the owner information to them Get-Process | ForEach-Object { $processOwner = $null # If we have process owner information for the process, look up the owner in the table if ($processOwners.ContainsKey($_.Id)) { $processOwner = $processOwners[$_.Id] } # Add the owner information to the current process object Add-Member -InputObject $_ -MemberType NoteProperty -Name Owner -Value $processOwner # Return the current process object from the script block $_ } | Select-Object Name,Owner,Description}

Regards,
Dan.

September 4, 2014 at 5:12 am

I would create an object for each process. This allows you to combine properties from multiples sources/queries. This may be what you were trying to do, but I'm not sure as I'm having difficulty reading through the commands that were posted.

$Processes = Get-WMIObject -ComputerName localhost Win32_Process
$Processes2 = Invoke-Command -ComputerName localhost -ScriptBlock {Get-Process}

ForEach ($Process in $Processes)
{
    $obj = New-Object PSObject
    $obj | Add-Member -MemberType NoteProperty -Name Process -Value $Process.Name
    $obj | Add-Member -MemberType NoteProperty -Name Description -Value ($Processes2 | ? { $_.ID -eq $Process.ProcessID }).Description
    $obj | Add-Member -MemberType NoteProperty -Name Owner -Value $Process.getowner().User
    $obj | Add-Member -MemberType NoteProperty -Name ProcessID -Value $Process.ProcessID

    Write-Output $obj
}

September 4, 2014 at 5:19 am

lol... just realized this post is a year and a half old. forget I said anything. 🙂

March 18, 2016 at 1:58 am

Old post or not thank you so much Joshua 🙂