Troubleshooting Powershell Script Problems

I'm trying to use a Technet Powershell script to check the status of various services on a few servers.  (The script can be found here: https://gallery.technet.microsoft.com/scriptcenter/PowerShell-Monitor-Notify-a5fe1538)  It involves a call command that specifies servers and services to be checked, and a function that actually checks the services and then inserts the results in an html table.  Not being very familiar with Powershell, I'm not sure how to set this up.  I've tried to call the function as mentioned in the article:

.\Get-ServiceSQLAlert.ps1 -ComputerList "C:\Fave_PowerShell_CMDlets\ServiceWatch.txt" -includeService Spooler -To jdoe@acme.com -From ServiceWatch@acme.com -SMTPMail mail.acme.com

Open in new window


But when I do nothing happens - no error, no nothing.  It seems like it runs but no htm file is created and no email is sent.  Is there anyway to troubleshoot this?

FYI:

  • I have write access to the C drive
  • I'm calling the function from the correct path
  • The path for the text file containing the server names is correct
  • On the server I'm using to test, I have shutdown the spooler service
Tim BallinAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jose Gabriel Ortega CastroCEOCommented:
OK 1st, the file: Server.txt
You need to have all the server's or computer's name in there, do you have them?

2nd: Did you run, in an elevated powershell console, like this https://www.youtube.com/watch?v=tY29YFgxo1k:
set -executionpolicy unrestricted
In the computer, you are running the script?

3. is it a domain or a workgroup infrastructure?
0
Tim BallinAuthor Commented:
Thanks for your response Jose...

  1. Yes, I have all the servers I want in that list.  For testing purposes though I have only one.  Also note that when I copy the path from the call command and paste it into an explorer window, the text file opens right up, so I know the path is good.
  2. It was run in an elevated Powershell console.
  3. Execution policy was set to "Unrestricted"
  4. This is a domain joined computer
0
Jose Gabriel Ortega CastroCEOCommented:
Ok I think that we would need to give it a look, do you have teamviewer? (if you want can send id and pwd over prv msj)
It looks like it's something going on with the script itself if it doesn't work.
So the next step is troubleshooting with powershell ise
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

footechCommented:
The downloaded file (default name ServiceStatusAlert.ps1) needs to be run first.  When it is run, it creates the functions which can then be called to do the actual work.
. .\ServiceStatusAlert.ps1  #the first dot is needed to load the function into the global scope
Get-ServiceSQLAlert -ComputerList "C:\Fave_PowerShell_CMDlets\ServiceWatch.txt" -includeService Spooler -To jdoe@acme.com -From ServiceWatch@acme.com -SMTPMail mail.acme.com

Open in new window

1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
footechCommented:
I took some time to look over the script.  There were a number of things I didn't like, so I made some revisions, including some spelling, proper indentation, etc. (I just picked the low-hanging fruit, I didn't change everything that bugged me).  One notable "feature" of the original was that it only matched a service name specified with the same case.  I changed a line so that it is now case-insensitive.  If you want to match a partial name you will have to use wildcards, like "spool*" to match against "Spooler".
ServicesStatusAlert.ps1.txt
1
David Johnson, CD, MVPOwnerCommented:
I also changed this script to put all functions before they were called and to use verb-nown refactoring.
#requires -Version 2.0
Function write-HtmlHeader
{
  <#
      .SYNOPSIS
      Describe purpose of "writeHtmlHeader" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER fileName
      Describe parameter -fileName.

      .EXAMPLE
      writeHtmlHeader -fileName Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online writeHtmlHeader

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  param($fileName)
  $date = ( Get-Date ).ToString('yyyy/MM/dd')
  Add-Content $fileName -Value '<html>'
  Add-Content $fileName -Value '<head>'
  Add-Content $fileName -Value "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"
  Add-Content $fileName -Value '<title>Service Status Report </title>'
  Add-Content $fileName -Value '<STYLE TYPE="text/css">'
  Add-Content $fileName  -Value '<!--'
  Add-Content $fileName  -Value 'td {'
  Add-Content $fileName  -Value 'font-family: Tahoma;'
  Add-Content $fileName  -Value 'font-size: 11px;'
  Add-Content $fileName  -Value 'border-top: 1px solid #999999;'
  Add-Content $fileName  -Value 'border-right: 1px solid #999999;'
  Add-Content $fileName  -Value 'border-bottom: 1px solid #999999;'
  Add-Content $fileName  -Value 'border-left: 1px solid #999999;'
  Add-Content $fileName  -Value 'padding-top: 0px;'
  Add-Content $fileName  -Value 'padding-right: 0px;'
  Add-Content $fileName  -Value 'padding-bottom: 0px;'
  Add-Content $fileName  -Value 'padding-left: 0px;'
  Add-Content $fileName  -Value '}'
  Add-Content $fileName  -Value 'body {'
  Add-Content $fileName  -Value 'margin-left: 5px;'
  Add-Content $fileName  -Value 'margin-top: 5px;'
  Add-Content $fileName  -Value 'margin-right: 0px;'
  Add-Content $fileName  -Value 'margin-bottom: 10px;'
  Add-Content $fileName  -Value ''
  Add-Content $fileName  -Value 'table {'
  Add-Content $fileName  -Value 'border: thin solid #000000;'
  Add-Content $fileName  -Value '}'
  Add-Content $fileName  -Value '-->'
  Add-Content $fileName  -Value '</style>'
  Add-Content $fileName -Value '</head>'
  Add-Content $fileName -Value '<body>'

  Add-Content $fileName  -Value "<table width='100%'>"
  Add-Content $fileName  -Value "<tr bgcolor='#CCCCCC'>"
  Add-Content $fileName  -Value "<td colspan='4' height='25' align='center'>"
  Add-Content $fileName  -Value "<font face='tahoma' color='#003399' size='4'><strong>Service Stauts Alert - $date</strong></font>"
  Add-Content $fileName  -Value '</td>'
  Add-Content $fileName  -Value '</tr>'
  Add-Content $fileName  -Value '</table>'
}

# Function to write the HTML Header to the file
Function write-TableHeader
{
  <#
      .SYNOPSIS
      Describe purpose of "writeTableHeader" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER fileName
      Describe parameter -fileName.

      .EXAMPLE
      writeTableHeader -fileName Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online writeTableHeader

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  param($fileName)

  Add-Content $fileName -Value '<tr bgcolor=#CCCCCC>'
  Add-Content $fileName -Value "<td width='10%' align='center'>ServerName</td>"
  Add-Content $fileName -Value "<td width='50%' align='center'>Service Name</td>"
  Add-Content $fileName -Value "<td width='10%' align='center'>status</td>"
  Add-Content $fileName -Value '</tr>'
}

Function write-HtmlFooter
{
  <#
      .SYNOPSIS
      Describe purpose of "writeHtmlFooter" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER fileName
      Describe parameter -fileName.

      .EXAMPLE
      writeHtmlFooter -fileName Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online writeHtmlFooter

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  param($fileName)

  Add-Content $fileName -Value '</body>'
  Add-Content $fileName -Value '</html>'
}

Function write-DiskInfo
{
  <#
      .SYNOPSIS
      Describe purpose of "writeDiskInfo" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER filename
      Describe parameter -filename.

      .PARAMETER Servername
      Describe parameter -Servername.

      .PARAMETER name
      Describe parameter -name.

      .PARAMETER Status
      Describe parameter -Status.

      .EXAMPLE
      writeDiskInfo -filename Value -Servername Value -name Value -Status Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online writeDiskInfo

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  param($fileName,$Servername,$name,$Status)
  if( $Status -eq 'Stopped')
  {
    increment $global:a
    Add-Content $fileName -Value '<tr>'
    Add-Content $fileName -Value "<td bgcolor='#FF0000' align=left ><b>$Servername</td>"
    Add-Content $fileName -Value "<td bgcolor='#FF0000' align=left ><b>$name</td>"
    Add-Content $fileName -Value "<td bgcolor='#FF0000' align=left ><b>$Status</td>"
    Add-Content $fileName -Value '</tr>'
  }
}
$global:a = 0

function increment 
{
  <#
      .SYNOPSIS
      Describe purpose of "increment" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .EXAMPLE
      increment
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online increment

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  $global:a++
}

Function sendEmail  
{
  <#
      .SYNOPSIS
      Describe purpose of "sendEmail" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER from
      Describe parameter -from.

      .PARAMETER to
      Describe parameter -to.

      .PARAMETER subject
      Describe parameter -subject.

      .PARAMETER smtphost
      Describe parameter -smtphost.

      .PARAMETER htmlFileName
      Describe parameter -htmlFileName.

      .EXAMPLE
      sendEmail -from Value -to Value -subject Value -smtphost Value -htmlFileName Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online sendEmail

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>

 
  param($From,$To,$subject,$smtphost,$htmlFileName)  
  [string]$receipients = "$To"
  $body = Get-Content $htmlFileName 
  $body = New-Object -TypeName System.Net.Mail.MailMessage -ArgumentList $From, $receipients, $subject, $body 
  $body.isBodyhtml = $TRUE
  $smtpServer = $MailServer
  $smtp = New-Object -TypeName Net.Mail.SmtpClient -ArgumentList ($smtphost)
  $smtp.Send($body)
}





Function Get-ServiceSQLAlert
{
  <#
      .SYNOPSIS
      Describe purpose of "Get-ServiceSQLAlert" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER ComputerList
      Describe parameter -ComputerList.

      .PARAMETER includeService
      Describe parameter -includeService.

      .PARAMETER To
      Describe parameter -To.

      .PARAMETER From
      Describe parameter -From.

      .PARAMETER SMTPMail
      Describe parameter -SMTPMail.

      .EXAMPLE
      Get-ServiceSQLAlert -ComputerList Value -includeService Value -To Value -From Value -SMTPMail Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online Get-ServiceSQLAlert

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  param(
    [String]$ComputerList,
    [String[]]$includeService,
    [String]$To,
    [String]$From,
    [string]$SMTPMail
  )
  Write-Debug -Message ($ComputerList)
  #Make sure to check write acess on c:\ drive. if not, change the path
  $ServiceFileName = 'c:\test\ServiceFileName.htm'
  New-Item -ItemType file $ServiceFileName -Force
  # Function to write the HTML Header to the file
  write-HtmlHeader -fileName $ServiceFileName
  Add-Content $ServiceFileName -Value "<table width='100%'><tbody>"
  Add-Content $ServiceFileName -Value "<tr bgcolor='#CCCCCC'>"
  Add-Content $ServiceFileName -Value "<td width='100%' align='center' colSpan=3><font face='tahoma' color='#003399' size='2'><strong> Service Details</strong></font></td>"
  Add-Content $ServiceFileName -Value '</tr>'
  write-TableHeader -fileName $ServiceFileName
  #Change value of the following parameter as needed
  $InlcudeArray = @()
  #List of programs to exclude
  #$InlcudeArray = $inlcudeService
  if ((Test-Path -Path $ComputerList))
  {
    $servers = Get-Content $ComputerList
  
    Foreach($Servername in $servers)
    {
      if (Test-Connection -ComputerName $Servername -Quiet -Count 1)
      {
        Write-Debug -Message $Servername
        $service = Get-Service -ComputerName $Servername
        # write-debug -Message $service
        if ($service -ne $NULL)
        {
          foreach ($item in $service)
          {
            #Write-Host($item.DisplayName)
            Foreach($include in $includeService) 
            {                       
              Write-debug $include                                    
              if(($item.serviceName).Contains($include) -eq $TRUE)
              {
                Write-Host  $item.MachineName $item.name $item.Status 
                write-DiskInfo -fileName $ServiceFileName -Servername $item.MachineName -name $item.name -Status $item.Status 
              }
            }
          }
        }
      }
      else 
      {
        Write-Warning -Message ("$Servername not available")
      }
      Add-Content $ServiceFileName -Value '</table>' 
      write-HtmlFooter -fileName $ServiceFileName
    }
  }
  else
  {
    Write-Host('{0} not found'-f $ComputerList)
  }
  $date = ( Get-Date ).ToString('yyyy/MM/dd')
  if ($global:a -ge 1)
  {
    $date = ( Get-Date ).ToString('yyyy/MM/dd')
  #  sendEmail -from $From -to $To -subject "Service Status - $date" -smtphost $SMTPMail -htmlfilename $ServiceFileName
  }
}

Open in new window

1
Tim BallinAuthor Commented:
Footech - your answer and your code revision worked great.  Thanks!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.