Retrieving process list and owner name

This topic contains 4 replies, has 4 voices, and was last updated by Profile photo of Vlad Ion Orascu Vlad Ion Orascu 1 year, 3 months ago.

  • Author
    Posts
  • #5532

    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!

  • #18525
    Profile photo of Dan Stef
    Dan Stef
    Participant

    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.

  • #18527
    Profile photo of Joshua Taylor
    Joshua Taylor
    Participant

    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
    }
    
  • #18528
    Profile photo of Joshua Taylor
    Joshua Taylor
    Participant

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

  • #36690
    Profile photo of Vlad Ion Orascu
    Vlad Ion Orascu
    Participant

    Old post or not thank you so much Joshua 🙂

You must be logged in to reply to this topic.