Retrieve List of Services Running True or False

Hi,

I am trying to get a list of computers that is running a particular service or not. I seem to be missing something I cant wrap around. The output still gives me true even when the service is stopped during a test run. Any help greatly appreciated.

$Computers = Get-Content -Path "C:\Users\Administrator\Desktop\computers.txt"
$cred = Get-Credential
 
$ProcessRunning = 
Foreach ($computer in $computers) {
    
    If (Test-Connection -ComputerName $computer -Quiet -Count 1 -ErrorAction SilentlyContinue) {
    
    Invoke-command -Computername $computer -ErrorAction SilentlyContinue -scriptblock  {
    # Commands to be executed on remote machine
 
 [PSCustomObject]@{
                Computer       = $ENV:COMPUTERNAME 
                Online         = $True
                ProgramRunning = if (Get-Service -Name SEMgrSvc -ErrorAction SilentlyContinue) { $True } else { $false }  
            }
        } |
            Select-Object -ExcludeProperty RunspaceId
    }
    else {
     PSCustomObject]@{
            Computer       = $computer 
            Online         = $false
            ProgramRunning = 'n/a'  
        }
    }
} 
$ProcessRunning | Format-Table -AutoSize

$ProcessRunning | Export-Csv -Path  C:\Users\Administrator\Desktop\path.csv -NoTypeInformation

on mobile for now, but Invoke-Command relies on WinRM being running in order to work. Feels like a chicken and egg scenario. Get-service has a -ComputerName parameter where you can run it against a remote computer to check the status of WinRM and I donā€™t believe it requires it to be running to work.

EDIT: also, you gotta format your code so we can read it. Theres a ā€œPreformatted Textā€ option in the tool bad or you can wrap your code in 3 back tick characters.

1 Like

@grey0ut Apologies should look better. Yeah WinRM was just an example, the real service was SEMgrSvc. It would be Stopped and when I run the command I get a true Value.

on the if statement, try specifying the status eq to running or stopped. otherwise test @grey0ut approach with running get-service and adding the computername.

something like this should work to check the status

if ((get-service -Name WinRM).Status -eq 'running' ){
    write-host "service is running"
}
else {
    write-host "service is stopped"
} 
1 Like

Looks Good but shows me the output but not on the table

$Computers = Get-Content -Path "C:\Users\Administrator\Desktop\computers.txt"
$cred = Get-Credential
 
$ProcessRunning = 
Foreach ($computer in $computers) {
    
    If (Test-Connection -ComputerName $computer -Quiet -Count 1 -ErrorAction SilentlyContinue) {
    
    Invoke-command -Computername $computer -ErrorAction SilentlyContinue -scriptblock  {
    # Commands to be executed on remote machine
 
 [PSCustomObject]@{
                Computer       = $env:COMPUTERNAME 
                ProgramRunning = if ((get-service -Name SEMgrSvc -ComputerName $env:COMPUTERNAME).Status -eq 'running' ){
    write-host "service is running"
}
else {
    write-host "service is stopped"
}  
      }|
            Select-Object -ExcludeProperty RunspaceId
    }
    }
    else {
        [PSCustomObject]@{
            Computer       = $computer 
            ProgramRunning = 'n/a'  
        }
    }
}
                   
$ProcessRunning | Format-Table -AutoSize
$ProcessRunning | Export-Csv -Path  C:\Users\Administrator\Desktop\path.csv -NoTypeInformation

sorry mine was just an example with write host. replace write host with what you had before with true/false

if ((get-service -Name SEMgrSvc).Status -eq 'running' ){
    $true
}
else {
    $false
}
  
1 Like

This works. Perfect Thank you.

##Add -ComputerName $computer to Get-Service
##Add if ((get-service -Name Themes -ComputerName $env:COMPUTERNAME ).Status -eq ā€˜runningā€™ ){
$true
}
else {
$false
}

$Computers = Get-Content -Path "C:\Users\Administrator\Desktop\computers.txt"
$cred = Get-Credential
 
$ProcessRunning = 
Foreach ($computer in $computers) {
    
    If (Test-Connection -ComputerName $computer -Quiet -Count 1 -ErrorAction SilentlyContinue) {
    
    Invoke-command -Computername $computer -ErrorAction SilentlyContinue -scriptblock  {
    # Commands to be executed on remote machine
 
 [PSCustomObject]@{
                Computer       = $env:COMPUTERNAME 
                Online         = $True
                ProgramRunning = if ((get-service -Name Themes -ComputerName $env:COMPUTERNAME ).Status -eq 'running' ){
    $true
}
else {
    $false
}
        } |
            Select-Object -ExcludeProperty RunspaceId
    }
    }
    else {
        [PSCustomObject]@{
            Computer       = $computer 
            Online         = $false
            ProgramRunning = 'n/a'  
        }
    }
}

$ProcessRunning | Format-Table -AutoSize

$ProcessRunning | Export-Csv -Path  C:\Users\Administrator\Desktop\path.csv -NoTypeInformation

Ok Iā€™m back on a computer and thought I would look at this again. One thing I would change is that youā€™re using Invoke-Command to then run Get-Service against a remote computername, so weā€™re remotely invoking a command that does stuff remotely. Itā€™s redundant and I donā€™t know if it would cause problems.
Since Invoke-Command is reliant on WinRM to be working and set up and Get-Service with the -ComputerName parameter isnā€™t, I think we should just rely on Get-Service.

I also like to try as best I can to only create my output objects in one spot. Meaning instead of ā€œIf this output object like this, else output object like thisā€ we just gather up all our values ahead of time and create the output object accordingly at the bottom of the loop.
Example:

$Computers = Get-Content -Path "C:\Users\Administrator\Desktop\computers.txt"
 
$ProcessRunning = Foreach ($computer in $computers) {
    $Online = If (Test-Connection -ComputerName $Computer -Quiet -Count 1 -ErrorAction SilentlyContinue) {
        $true
    } else {
        $false
    }
    $Service = try {
            $Result = Get-Service -Name Themes -ComputerName $Computer -ErrorAction Stop
            if ($Result.Status -eq "Running") {
                $true
            } else {
                $false
            }
        } catch {
            "error"
        }
    [PSCustomObject]@{
        Computer        = $Computer
        Online          = $Online
        ProgramRunning  = $Service
    }
}
$ProcessRunning | Format-Table -AutoSize
$ProcessRunning | Export-Csv -Path  C:\Users\Administrator\Desktop\path.csv -NoTypeInformation

Notice iā€™ve omitted the $cred variable as Get-Service doesnā€™t require credentials to operate. Thereā€™s also no reason to get the environment variable for the computername because we already know the computename as itā€™s in our text list weā€™re working with.
I havenā€™t tested it but I also used a try/catch block on the service status such that if Get-Service fails to retrieve the service status the value becomes ā€œerrorā€ instead of just a boolean.

2 Likes

Nice @grey0ut , It ran a little longer than the last one but its more compacted and still output the needed true/false variables. With that said on the $cred. Iā€™ll be trying this in the next few days, I would like to see if this can be retrieve without the $cred to domain computers that require admin credential for remote session.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.