QwertyBot
QwertyBot

Reputation: 51

Select repeated Keys value from 2 hashtables

My task is to associate running services with process in Windows.

$a = Get-CimInstance -ClassName Win32_Service | Where-Object {$_.State -match "Running"} | Select-Object -Property ProcessId,Name
$b = Get-CimInstance -ClassName Win32_Process | Select-Object -Property ProcessId,Name
$d = @{$b.ProcessId=$b.Name}
$c = @{$a.ProcessId=$a.Name}

So, I get two hastables, and now I want to make new hashtable, that will consist of $a.Name and $b.Name, but from these values, where $a.processid=$b.processid. Or may be somebody can advice how to combine value before putting them into hashtables. Thanks

Upvotes: 3

Views: 99

Answers (2)

Abraham Zinala
Abraham Zinala

Reputation: 4694

You can't have duplicate Key Names in a Hashtable.

So you're better off with a PSCustomObject thats basically a hashtable:

$Services  = Get-CimInstance -ClassName WIN32_Service | Sort-Object -Property Name

foreach($service in $Services){
    try{
        [PSCustomObject]@{
            "Service Name" = $Service.Name
            "Process Name" = (Get-Process -Id $service.ProcessID).Name
            "Process ID  " = $service.ProcessID
            "Description"  = $service.Description
            }
        } Catch {
        $Error[0].exception.message
        }
    }

I'm also sure you're looking for the associated service name and not the process name, since Get-Process returns that info for you already.

EDIT

Thinking about this a little more... Maybe if you swap the order in what you want i.e., Service Name first, then the Proccess name, you can use a hashtable:

$Services  = Get-CimInstance -ClassName WIN32_Service | Sort-Object -Property Name
$HashTable = @{}
$other = @{}


foreach($service in $Services){
    Try{
        $HashTable.Add($service.Name,$((Get-Process -ID $service.ProcessId).Name) ) 
    }Catch{
        $other.Add($service.Name,$((Get-Process -ID $service.ProcessId).Name) ) 
    }
}

I added a secondary hashtable just in case theres a same name service (which there shouldnt be), you will still be able to grab the key-value pair. Although this works, I still recommend sticking with a PSCustomObject since it gives you more to work with.

This works due to services being unique in names.

Upvotes: 2

OwlsSleeping
OwlsSleeping

Reputation: 1570

I tried it, and mostly got svchost.exe on my machine for services- is that expected?

$Services = Get-CimInstance -ClassName Win32_Service |
    Where-Object {$_.State -eq "Running"} |
    Select-Object -Property ProcessId,Name
    
$Processes = Get-CimInstance -ClassName Win32_Process |
    Select-Object -Property ProcessId,Name
    
$Combined = foreach ($Service in $Services) {
    $ProcessName = ($Processes.Where{$_.ProcessId -eq $Service.ProcessId}).Name
    if($ProcessName) {
        New-Object -TypeName PSCustomObject -Property @{
            Service = $Service.Name
            Process = $ProcessName
        }
    }
}

$Combined

Upvotes: 2

Related Questions