function Get-ProcessFromService { <# .SYNOPSIS Retrieves the process for a Windows service by first interrogating CIM for the service properties .PARAMETER Service This should be an object with at minimum the [name] of a registered service object #> [CmdletBinding()] [OutputType([System.Diagnostics.Process[]])] Param( [Parameter(Mandatory=$true)] [object]$Service ) $logLead = (Get-LogLeadName) $imagePaths = @() $exeNames = @() $processes = @() $pids = @() $services = @(Get-ServiceInfoByCIMFragment $Service.Name) if (Test-IsCollectionNullOrEmpty $services) { Write-Warning "$logLead : No services returned from [Get-ServiceInfoByCIMFragment $($Service.Name)]" } foreach ($cimService in $services) { if ($null -eq $cimService) { Write-Warning "$logLead : Empty object returned from [Get-ServiceInfoByCIMFragment $($Service.Name)]" } else { # Ensure the path is "clean" for OS needs $exePath = $cimService.ExePath if ([string]::IsNullOrWhiteSpace($exePath)) { Write-Warning "$logLead : No exePath found for the CIM response on [Get-ServiceInfoByCIMFragment $($Service.Name)]" } else { $imagePath = [System.IO.Path]::GetFullPath($exePath) $exeName = [System.IO.Path]::GetFileNameWithoutExtension($imagePath) # should be a nonzero value if running and zero if stopped. Could be null maybe. if (($null -ne $cimService.ProcessID) -and ($cimService.ProcessID -gt 0)) { $pids += $cimService.ProcessID } if ($exeNames -notcontains $exeName) { $exeNames += $exeName } if ($imagePaths -notcontains $imagePath) { $imagePaths += $imagePath } } } } if (!(Test-IsCollectionNullOrEmpty $pids)) { return (Get-Process -Id $pids) } if (Test-IsCollectionNullOrEmpty $imagePaths) { Write-Warning "$logLead : No service paths found to process. Returning without results." return } # because we have an imagePath(s) we therefore must have an exeName(s) $processes = (Get-Process | Where-Object {$imagePaths -contains $PSItem.Path }) if ($processes.Count -gt 0) { return $processes } Write-Host "$logLead : Falling back to the legacy lookup pattern" # fallback to legacy lookup pattern on filename alone return (Get-Process -Name $exeNames) }