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.