How to split services into different cells

This topic contains 13 replies, has 4 voices, and was last updated by  Cory 4 months ago.

  • Author
    Posts
  • #73448

    Cory
    Participant

    Currently this script outputs to an HTM file with the computername in cell 1, all the servicenames in cell 2, and all the status in cell 3. What I would like is to split it up so each line has the computer name, 1 service, and 1 status.

    Function servicestatus ($serverlist, $serviceslist)

    {

    foreach ($machineName in $serverlist)

    {
    foreach ($service in $serviceslist)

    {

    $serviceStatus = get-service -ComputerName $machineName -Name $service

    if ($serviceStatus.status -eq "Running") {

    Write-Host $machineName `t $serviceStatus.name `t $serviceStatus.status -ForegroundColor Green
    $svcName = $serviceStatus.name
    $svcState = $serviceStatus.status
    Add-Content $report ""
    Add-Content $report " $machineName"
    Add-Content $report " $svcName"
    Add-Content $report "$svcState"
    Add-Content $report ""
    }

    elseif ($serviceStatus.status -eq "Stopped")
    {
    Write-Host $machineName `t $serviceStatus.name `t $serviceStatus.status -ForegroundColor Yellow
    $svcName = $serviceStatus.name
    $svcState = $serviceStatus.status
    Add-Content $report ""
    Add-Content $report "$machineName"
    Add-Content $report "$svcName"
    Add-Content $report "$svcState"
    Add-Content $report ""
    }
    else
    {
    Write-Host $machineName `t $serviceStatus.name `t $serviceStatus.status -ForegroundColor Yellow
    $svcName = $serviceStatus.name
    $svcState = $serviceStatus.status
    Add-Content $report ""
    Add-Content $report "$machineName"
    Add-Content $report "$svcName"
    Add-Content $report "$svcState"
    Add-Content $report ""

    }

    }
    }
    }

  • #73451

    Don Jones
    Keymaster

    Oh my. The Write-Hosts.

    Have you considered:

    $computers = "SERVER1","SERVER2"
    foreach ($computer in $computers) {
      Get-Service -Computername $computer |
      Select-Object @{n='ComputerName';e={$computer}},Name,Status |
      ConvertTo-HTML |
      Out-File Report.html
    }
    

    Rather than manually building HTML as you're doing? PowerShell's perfectly willing to create HTML for you. I even wrote an EnhancedHTML2 module that lets you do very granular and dynamic HTML reports. Even wrote a free ebook about it.

  • #73454

    Cory
    Participant

    forgive me if I sound ignorant or not understanding as I am learning this on the fly but you have $computers = "Server1", "Server2" etc. I am using a txt document that have over 5000 computer names in it to run the scan from and the Service is also from a txt document as I need the service name to be a wildcard.

    Basically I have found on my computers that some software that gets updated creates a new service everytime but doesn't delete the old service. So some computers will have clientservice010117, clientservices010217 and so forth. So I need to use a scan that searches each computer in the list for a services clientservice* any that are stopped need to be delete.

    Right now the report runs just fine except for the fact that it will report like this

    COmputer1 clientservice010117 clientservice010217 clientservice 010317 Stopped Running Stopped

    obviously each computer is alittle different

    I would like it to be formatted like
    Computer1 Clientservice010117 Stopped
    Computer1 Clientservice010217 Running
    Computer1 Clientservice010317 Stopped

  • #73465

    Chris
    Participant

    Hi Cory,

    Presuming you have them all listed in a column, you could use Get-Content, to read data from the txt file. then add the wildcard into the foreach loop:

    $computers = Get-Content -Path C:\computer.txt 
    foreach ($computer in $computers) {
      Get-Service clientservice* -Computername $computer |
      Select-Object @{n='ComputerName';e={$computer}},Name,Status |
      ConvertTo-HTML |
      Out-File C:\Report.html
    }
    

    Give that a whirl, see how you get on.

  • #73466

    Cory
    Participant

    Here is the full powershell script as that might make it easier to understand. Again I am piecing this together from different how-to I have read and have got it working just now trying to figure out how to fix the format. After that is done I can go onto how to delete the bad services but that is another topic.

    ############################Define Server & Services Variable ###############

    $serverList = Get-Content ".\server.txt"
    $servicesList = Get-Content ".\services.txt"

    #############################Define other variables##########################

    $report = ".\report.htm"

    $smtphost = "mail.mycompany.com"
    $from = "myself@mycompany.com"
    $to = "myself@mycompany.com"

    ##############################################################################

    $checkrep = Test-Path ".\report.htm"

    If ($checkrep -like "True")

    {

    Remove-Item ".\report.htm"
    }

    New-Item ".\report.htm" -type file
    ################################ADD HTML Content#############################

    Add-Content $report ""
    Add-Content $report ""
    Add-Content $report ""
    Add-Content $report 'Service Status Report'
    add-content $report "
    add-content $report ""
    add-content $report ""
    Add-Content $report ""
    Add-Content $report ""
    add-content $report ""
    add-content $report ""
    add-content $report ""
    add-content $report "Service Status Report"
    add-content $report ""
    add-content $report ""
    add-content $report ""

    add-content $report ""
    Add-Content $report ""
    Add-Content $report "Server Name"
    Add-Content $report "Service Name"
    Add-Content $report "Status"
    Add-Content $report ""
    ########################################################################################################
    ################################## Get Services Status #################################################

    Function servicestatus ($serverlist, $serviceslist)
    {
    foreach ($machineName in $serverlist)
    {
    foreach ($service in $serviceslist)
    {
    $serviceStatus = get-service -ComputerName $machineName -Name $service

    if ($serviceStatus.status -eq "Running") {

    Write-Host $machineName `t $serviceStatus.name `t $serviceStatus.status -ForegroundColor Green
    $svcName = $serviceStatus.name
    $svcState = $serviceStatus.status
    Add-Content $report ""
    Add-Content $report " $machineName"
    Add-Content $report " $svcName"
    Add-Content $report "$svcState"
    Add-Content $report ""
    }

    else
    {
    Write-Host $machineName `t $serviceStatus.name `t $serviceStatus.status -ForegroundColor Red
    $svcName = $serviceStatus.name
    $svcState = $serviceStatus.status
    Add-Content $report ""
    Add-Content $report "$machineName"
    Add-Content $report "$svcName"
    Add-Content $report "$svcState"
    Add-Content $report ""

    sc.exe \\$machineName delete "$SvcName" #This does not work
    }
    }
    }
    }
    ############################################Call Function#############################################
    servicestatus $serverList $servicesList
    ############################################Close HTMl Tables#########################################
    Add-content $report ""
    Add-Content $report ""
    Add-Content $report ""
    #####################################################################################################
    #############################################Send Email##############################################
    $subject = "Daily Service Monitor"
    $body = Get-Content ".\report.htm"
    $smtp= New-Object System.Net.Mail.SmtpClient $smtphost
    $msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body
    $msg.isBodyhtml = $true
    $smtp.send($msg)

    #####################################################################################################

  • #73471

    Don Jones
    Keymaster

    Cory, would you consider looking at the two short examples we've posted, and letting us know – obviously, using a couple of your own servers rather than SERVER1 and SERVER2 – if the basic output form is what you want? We're trying to help, but the approach you're taking with all that Add-Content is just a bad approach. We're not going to be able to help you fix your existing script – it's a bad direction. We're trying to get you going in a good direction.

    • #73480

      Cory
      Participant

      I appreciate the help

  • #73474

    Cory
    Participant

    OK I have shrunk down the script to what I think it should look like with everyones input. However I now do not get any information in my report.html it is just blank. Also when I watch the script run instead of reporting back the names and services it is reporting back all HTML code. If I removed something I shouldn't have removed please let me know.

    ############################Define Server & Services Variable ###############
    $serverList = Get-Content ".\server.txt"
    #############################Define other variables##########################

    $report = ".\report.html"

    $smtphost = "mail@mycompany.com"
    $from = "myself@mycompany.com"
    $to = "myself@mycompany.com"

    ##############################################################################

    $checkrep = Test-Path ".\report.html"

    If ($checkrep -like "True")

    {

    Remove-Item ".\report.html"

    }

    New-Item ".\report.html" -type file

    ################################## Get Services Status #################################################
    foreach ($computer in $serverList)
    {
    Get-Service clientservice* -ComputerName $computer |
    Select-Object @{n='ComputerName';e={$computer}},Name,Status |
    ConvertTo-Html
    Out-File ".\report.html"
    }

    #############################################Send Email##############################################

    $subject = "Daily Service Monitor"
    $body = Get-Content ".\report.htm"
    $smtp= New-Object System.Net.Mail.SmtpClient $smtphost
    $msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body
    $msg.isBodyhtml = $true
    $smtp.send($msg)

    #####################################################################################################

  • #73477

    Don Jones
    Keymaster

    You did – you're missing the pipe character after ConvertTo-HTML. As a result, the converted HTML is spewing to the screen, and Out-File isn't being given anything to work with.

  • #73483

    Cory
    Participant

    Don/Chris

    After fixing the type of not having the Pipe behind the ConvertTo-html I was able to get content on my report.html.
    However it only reported the last scanned computer, it did not report any other computers that were scanned.

    Any thoughts on that

  • #73495

    Cory
    Participant

    -Append appears to have added all the computers now. Thanks for that.
    It also added the header for the Computername, Service, and Status. I can live with editing that out manually unless someone knows how to only show the Header fields once

    Again thank you everyone for the help.

  • #73496

    Don Jones
    Keymaster

    Yeah, you really want to refactor it a bit probably.

    Rather than:

    foreach ($computer in $serverList)
    {
    Get-Service clientservice* -ComputerName $computer |
    Select-Object @{n='ComputerName';e={$computer}},Name,Status |
    ConvertTo-Html
    Out-File ".\report.html"
    }
    

    Do something like:

    function x {
     foreach ($computer in $serverList)
     {
      Get-Service clientservice* -ComputerName $computer |
      Select-Object @{n='ComputerName';e={$computer}},Name,Status
     }
    }
    x | 
    ConvertTo-Html |
    Out-File ".\report.html"
    }
    

    That'll give you one report without all the headers, I think. The idea is to generate all the objects and only call ConvertTo-HTML once.

  • #73507

    Cory
    Participant

    Thank you that did the trick

You must be logged in to reply to this topic.