none
PowerShell script output to email RRS feed

  • Question

  • Hello.
    I have a script which successfully logs the info to a text file but I would like it to output to an email. I don't mean just attaching the logfile, but actually the contents directly into an email. Can someone help please?

    # Script invokes Citrix PowerShell SDK Cmdlet on remote Xenpp server and checks server logons.

    Invoke-Command -computername ServerName -Scriptblock {
    Add-PSSnapin *Citrix*

    Remove-Item "C:\Scripts\logfile.log"
    $log_file="C:\Scripts\logfile.log"
    $servers = Get-XAServer
    $date = get-date -format dd/MM/yyyy

    foreach($server in $servers){
        echo "`n**** $server ****" | Out-File $log_file -width 240 -Append #logs the result

        if($server.LogOnsEnabled -eq $false){
            echo "Logons are disabled on this server!" | Out-File $log_file -width 240 -Append #logs the result
        }

        ElseIf
            ($server.LogOnsEnabled -eq $true){
            echo "Logons are enabled on this server!" | Out-File $log_file -width 240 -Append #logs the result
        }
    }
    }

    $body = $svcReport | ConvertTo-Html | out-String
    Send-MailMessage -From user@domainname -To user@domainname -Subject "Citrix XenApp Logon check -$date" -body $body -BodyAsHtml -SmtpServer ExchangeCAS

    Wednesday, April 11, 2012 9:50 AM

Answers

  • If your code were better lined up and indented, you would see why:  It's included in the foreach loop.  I thought that would be obvious by the behaviour (an email for every server).  And the last command is wrong:  $body is a string.  You can't issue Get-Content on a string like that, it makes no sense.  What do you want to do there?

    Remove-Item "C:\Scripts\logfile.log"
    $log_file="C:\Scripts\logfile.log"
    $servers = Get-XAServer
    $date = get-date -format dd/MM/yyyy
    foreach($server in $servers){
        echo "`n**** $server ****" | Out-File $log_file -width 240 -Append #logs the result
        if($server.LogOnsEnabled -eq $false){
            echo "Logons are disabled on this server!" | Out-File $log_file -width 240 -Append #logs the result
          }
        ElseIf 
            ($server.LogOnsEnabled -eq $true){
            echo "Logons are enabled on this server!" | Out-File $log_file -width 240 -Append #logs the result
            }
        } # end foreach
        
    $body = Get-Content $log_file | Out-String
    Send-MailMessage -From user@DomainName -To user@domainname -Subject "Citrix XenApp Logon check -$date" -body $body -SmtpServer ExchangeCAS


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    • Marked as answer by Millsyboy Monday, April 16, 2012 2:44 PM
    Friday, April 13, 2012 3:09 PM
  • Here is a sample I had floating arounf.  I cleaned it up a bit to make it easier to use.  It demos sending colorful multi-table reports in email.

    # Demo-CompoundHtmlReport.ps1
    Param(
        [switch]$sendmail,
        $to='reportusers@domain.com',
        $from='reportadmin@domain.com',
        $smtpserver='smtp.domain.com'
    )
    # generate four body segments tagged and wrapped in a div speccifying the CSSClass
    $rpt1=Get-WmiObject -class Win32_Service -filter "StartMode = 'Auto' and state <> 'Running'" |
        Select-Object Name, DisplayName,State |
        ConvertTo-HTML -Fragment -pre '<h2>System for Report</h2><div class="rpt1">' -post '</div>' |
        Out-String
    $rpt2 = Get-EventLog -LogName Application -newest 10 | 
         Select-Object EventID, MachineName,Category,EntryType,source |
         ConvertTo-HTML -Fragment -pre '<h2>Eventlog Error Report</h2><div class="rpt2">' -post '</div>' |
         Out-String
    $rpt3 = Get-Process |
         Select-Object Name,Handles, VM, WS, PM, NPM, Path |
         ConvertTo-HTML -Fragment -pre '<h2>Running Processes Report</h2><div class="rpt3">' -post '</div>' |
         Out-String
    $rpt4 = Get-WmiObject -class Win32_OperatingSystem |
     Select-Object -property Caption,BuildNumber,ServicePackMajorVersion,
                             @{n='LastBootTime';e={$_.ConvertToDateTime($_.LastBootUpTime)}} |
         ConvertTo-HTML -Fragment -pre '<h2>Operating System</h2><div class="rpt4">' -post '</div>' |
         Out-String
    # combine fragments into one report - point to web based style sheet.
    # style sheet used her is a dem and can be downloaded and modified.
    # style sheet can be embedded in report or placed on corporate intranet server on a share.
    $reportbanner="<h1>System Status Report for $env:computername</h1>"
    $reportHTML=ConvertTo-HTML `
                   -Body "$reportbanner $rpt4 $rpt1 $rpt2 $rpt3" `
                   -Title 'Server Status Report' `
                   -head '<link rel="StyleSheet" href="http://www.designedsystemsonline.com/style/defaultreport.css" type="text/css" media="screen">'
    $reportHTML | Out-File .\report.htm
    .\report.htm
    if($sendmail){
    Write-Warning "sending"
         $htmlBody=$reportHTML | Out-String
         Send-MailMessage `
              -to $to `
              -from $from `
              -smtpserver $smtpserver `
              -subject 'HTML Test Report' `
              -body $htmlBody `
              -BodyAsHtml
    }


    ¯\_(ツ)_/¯

    • Marked as answer by Millsyboy Monday, April 16, 2012 2:44 PM
    Saturday, April 14, 2012 7:12 PM

All replies

  • I don't understand what you are doing with "body".  You are creating it using an object called $svcReport, which isn't mentioned anywhere else in the script.

    Clear this up for me, and I think I could help.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Wednesday, April 11, 2012 11:18 AM
  • Sorry I added the last 2 steps but had difficulty getting it to work correctly with the main code. You can remove the $body line.

    Thank you

    Wednesday, April 11, 2012 11:24 AM
  • Try this:

    $body = get-content $log_file | out-string 

    ...and leave off the -BodyAsHTML switch.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)


    Wednesday, April 11, 2012 12:46 PM
  • Thank you

    Email not coming through, getting :

    Get-Content : Cannot bind argument to parameter 'Path' because it is null.
    At C:\Scripts\Check_Xenapp_Logons.ps1:31 char:20
    + $body = Get-Content <<<<  $log_file
        + CategoryInfo          : InvalidData: (:) [Get-Content], ParameterBindingValidationException
        + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentC
       ommand

    Send-MailMessage : Cannot validate argument on parameter 'Body'. The argument is null or empty. Supply an argument that
     is not null or empty and then try the command again.
    At C:\Scripts\Check_Xenapp_Logons.ps1:32 char:153
    + Send-MailMessage -From user@DomainName -To User@DomainName -Subject "Citrix XenApp Logon check -$date" -body <<<<  $body -SmtpServer ExchangeCAS
        + CategoryInfo          : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
        + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage

    Wednesday, April 11, 2012 2:30 PM
  • Hi,

    The error message tells you what is wrong. You are specifying a null argument for the -path parameter. Also, the -body parameter has an argument that is null or empty.

    Bill

    Wednesday, April 11, 2012 2:57 PM
    Moderator
  • What I suggested is really basic.  Troubleshoot this yourself:  Do a Get-Content on the variable $log_file.  I suggest you use the ISE for debugging purposes.

    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Wednesday, April 11, 2012 3:24 PM
  • Thank you for the help.
    I tried testing the output and could view the $log_file but not the $body so the way $body is reading the contents of $log_file and converting to HTML. I tried following :

    $body = Get-Content $log_file | ConvertTo-HTML | Out-String

    Send-MailMessage -From user@domainname -To user@domainname -Subject "Citrix XenApp Logon check -$date" -body $body -BodyAsHtml -SmtpServer ExchangeCAS
    Get-Content $body

    Also got issue when trying the following :

    $body = Get-Content $log_file

    Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Body'. Specified method is not supported.

    Friday, April 13, 2012 10:27 AM
  • $body = Get-Content $log_file | Out-String

    You cannot simply use ConvertTo-HTML in this way.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Friday, April 13, 2012 11:26 AM
  • Thank you.
    I tried that but I received a separate email for each log_file entry.

    Friday, April 13, 2012 2:34 PM
  • Hi,

    Remember that we cannot see your screen. What is your question? Please be specific.

    Bill

    Friday, April 13, 2012 2:46 PM
    Moderator
  • Sorry here is the script I am using. It reads the $log_file for the information but sends a separate email for each entry.

    Invoke-Command -computername XenApp_Server -Scriptblock {
    Add-PSSnapin *Citrix*

    Remove-Item "C:\Scripts\logfile.log"
    $log_file="C:\Scripts\logfile.log"
    $servers = Get-XAServer
    $date = get-date -format dd/MM/yyyy

    foreach($server in $servers){
        echo "`n**** $server ****" | Out-File $log_file -width 240 -Append #logs the result

        if($server.LogOnsEnabled -eq $false){
            echo "Logons are disabled on this server!" | Out-File $log_file -width 240 -Append #logs the result
          }

        ElseIf
            ($server.LogOnsEnabled -eq $true){
            echo "Logons are enabled on this server!" | Out-File $log_file -width 240 -Append #logs the result

    $body = Get-Content $log_file | Out-String

    Send-MailMessage -From user@DomainName -To user@domainname -Subject "Citrix XenApp Logon check -$date" -body $body -SmtpServer ExchangeCAS
    Get-Content $body

        }
    }
    }

    Friday, April 13, 2012 2:52 PM
  • If your code were better lined up and indented, you would see why:  It's included in the foreach loop.  I thought that would be obvious by the behaviour (an email for every server).  And the last command is wrong:  $body is a string.  You can't issue Get-Content on a string like that, it makes no sense.  What do you want to do there?

    Remove-Item "C:\Scripts\logfile.log"
    $log_file="C:\Scripts\logfile.log"
    $servers = Get-XAServer
    $date = get-date -format dd/MM/yyyy
    foreach($server in $servers){
        echo "`n**** $server ****" | Out-File $log_file -width 240 -Append #logs the result
        if($server.LogOnsEnabled -eq $false){
            echo "Logons are disabled on this server!" | Out-File $log_file -width 240 -Append #logs the result
          }
        ElseIf 
            ($server.LogOnsEnabled -eq $true){
            echo "Logons are enabled on this server!" | Out-File $log_file -width 240 -Append #logs the result
            }
        } # end foreach
        
    $body = Get-Content $log_file | Out-String
    Send-MailMessage -From user@DomainName -To user@domainname -Subject "Citrix XenApp Logon check -$date" -body $body -SmtpServer ExchangeCAS


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    • Marked as answer by Millsyboy Monday, April 16, 2012 2:44 PM
    Friday, April 13, 2012 3:09 PM
  • Thank you that worked. I did try the $body and SMTP at the end but had issues. I had to put before very last }

    Would like to get some color in the wording now!!

    Friday, April 13, 2012 3:28 PM
  • Thank you that worked. I did try the $body and SMTP at the end but had issues. I had to put before very last }

    Would like to get some color in the wording now!!

    You can only get color if you learn how to generate HTML and use an HTML body.  FOr this you need to study CSS and style sheets.

    Start here: http://w3schools.com/css/default.asp


    ¯\_(ツ)_/¯

    Friday, April 13, 2012 5:20 PM
  • Here is a sample I had floating arounf.  I cleaned it up a bit to make it easier to use.  It demos sending colorful multi-table reports in email.

    # Demo-CompoundHtmlReport.ps1
    Param(
        [switch]$sendmail,
        $to='reportusers@domain.com',
        $from='reportadmin@domain.com',
        $smtpserver='smtp.domain.com'
    )
    # generate four body segments tagged and wrapped in a div speccifying the CSSClass
    $rpt1=Get-WmiObject -class Win32_Service -filter "StartMode = 'Auto' and state <> 'Running'" |
        Select-Object Name, DisplayName,State |
        ConvertTo-HTML -Fragment -pre '<h2>System for Report</h2><div class="rpt1">' -post '</div>' |
        Out-String
    $rpt2 = Get-EventLog -LogName Application -newest 10 | 
         Select-Object EventID, MachineName,Category,EntryType,source |
         ConvertTo-HTML -Fragment -pre '<h2>Eventlog Error Report</h2><div class="rpt2">' -post '</div>' |
         Out-String
    $rpt3 = Get-Process |
         Select-Object Name,Handles, VM, WS, PM, NPM, Path |
         ConvertTo-HTML -Fragment -pre '<h2>Running Processes Report</h2><div class="rpt3">' -post '</div>' |
         Out-String
    $rpt4 = Get-WmiObject -class Win32_OperatingSystem |
     Select-Object -property Caption,BuildNumber,ServicePackMajorVersion,
                             @{n='LastBootTime';e={$_.ConvertToDateTime($_.LastBootUpTime)}} |
         ConvertTo-HTML -Fragment -pre '<h2>Operating System</h2><div class="rpt4">' -post '</div>' |
         Out-String
    # combine fragments into one report - point to web based style sheet.
    # style sheet used her is a dem and can be downloaded and modified.
    # style sheet can be embedded in report or placed on corporate intranet server on a share.
    $reportbanner="<h1>System Status Report for $env:computername</h1>"
    $reportHTML=ConvertTo-HTML `
                   -Body "$reportbanner $rpt4 $rpt1 $rpt2 $rpt3" `
                   -Title 'Server Status Report' `
                   -head '<link rel="StyleSheet" href="http://www.designedsystemsonline.com/style/defaultreport.css" type="text/css" media="screen">'
    $reportHTML | Out-File .\report.htm
    .\report.htm
    if($sendmail){
    Write-Warning "sending"
         $htmlBody=$reportHTML | Out-String
         Send-MailMessage `
              -to $to `
              -from $from `
              -smtpserver $smtpserver `
              -subject 'HTML Test Report' `
              -body $htmlBody `
              -BodyAsHtml
    }


    ¯\_(ツ)_/¯

    • Marked as answer by Millsyboy Monday, April 16, 2012 2:44 PM
    Saturday, April 14, 2012 7:12 PM