emailfunctions.ps1

Function Enable-EmailReminder {
    #this function requires the PSScheduledJob module
    [cmdletbinding(SupportsShouldProcess)]
    [OutputType("None")]

    Param(
        [Parameter(Position = 0, HelpMessage = "What time do you want to send your daily email reminder?")]
        [ValidateNotNullOrEmpty()]
        [datetime]$Time = "8:00AM",
        [Parameter(HelpMessage = "What is your email server name or address?")]
        [ValidateNotNullOrEmpty()]
        [string]$SMTPServer = $PSEmailServer,
        [Parameter(Mandatory, HelpMessage = "Enter your email address")]
        [ValidateNotNullOrEmpty()]
        [ValidatePattern("\S+@*.\.\w{2,4}")]
        [string]$To,
        [Parameter(HelpMessage = "Enter the FROM email address. If you don't specify one, the TO address will be used.")]
        [ValidatePattern("\S+@*.\.\w{2,4}")]
        [string]$From,
        [Parameter(HelpMessage = "Include if you need to use SSL?")]
        [switch]$UseSSL,
        [Parameter(HelpMessage = "Specify the port to use for your email server")]
        [ValidateNotNullOrEmpty()]
        [int32]$Port = 25,
        [Parameter(HelpMessage = "Specify any credential you need to authenticate to your mail server.")]
        [PSCredential]$MailCredential,
        [Parameter(HelpMessage = "Send an HTML body email")]
        [switch]$AsHtml,
        [ValidateNotNullOrEmpty()]
        [ValidateScript( {$_ -gt 0})]
        [int]$Days = 3,
        [Parameter(Mandatory, HelpMessage = "Re-enter your local user credentials for the scheduled job task")]
        [ValidateNotNullOrEmpty()]
        [PSCredential]$TaskCredential,
        [ValidateNotNullOrEmpty()]
        [string]$TaskPath = $mytaskHome
    )
    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Using these mail parameters:"

        if (-Not $From) {
            $From = $To
        }
        $hash = @{
            To         = $To
            From       = $From
            SMTPServer = $SMTPServer
            Port       = $Port
        }
        if ($MailCredential) {
            $hash.Add("Credential", $MailCredential)
        }
        If ($UseSSL) {
            $hash.add("UseSSL", $True)
        }

        $hash | Out-String | Write-Verbose
        #define the job scriptblock
        $sb = {
            Param([hashtable]$Hash, [int]$Days, [string]$myPath)
            #uncomment Write-Host lines for troubleshooting
            #$PSBoundParameters | out-string | write-host -ForegroundColor cyan
            #get tasks for the next 3 days as the body

            Set-MyTaskPath -Path $myPath
            #get-variable mytask* | out-string | Write-Host
            write-host "[$((Get-Date).ToString())] Getting tasks for the next $days days."
            $data = Get-MyTask -Days $Days
            if ($data) {
                if ($hash.BodyAsHTML) {
                    Write-Host "[$((Get-Date).ToString())] Sending as HTML" -ForegroundColor green
                    #css to be embedded in the html document
                    $head = @"
<Title>Upcoming Tasks</Title>
<style>
body { background-color:rgb(199, 194, 194);
    font-family:Tahoma;
    font-size:12pt; }
td, th { border:1px solid black;
            border-collapse:collapse; }
th { color:white;
        background-color:black; }
table, tr, td, th { padding: 2px; margin: 0px }
tr:nth-child(odd) {background-color: lightgray}
table { width:95%;margin-left:5px; margin-bottom:20px;}
.alert {color: red ;}
.warn {color:#ff8c00;}
</style>
<br>
<H1>My Tasks</H1>
"@

                    [xml]$html = $data | ConvertTo-HTML -Fragment

                    #parse html to add color attributes
                    for ($i = 1; $i -le $html.table.tr.count - 1; $i++) {
                        $class = $html.CreateAttribute("class")
                        #check the value of the percent free memory column and assign a class to the row
                        if ($html.table.tr[$i].td[4] -eq 'True') {
                            $class.value = "alert"
                            $html.table.tr[$i].Attributes.Append($class) | Out-Null
                        }
                        elseif ((($html.table.tr[$i].td[3] -as [DateTime]) - (Get-Date)).totalHours -le 24 ) {
                            $class.value = "warn"
                            $html.table.tr[$i].Attributes.Append($class) | Out-Null
                        }
                    }

                    $Body = ConvertTo-HTML -body $html.InnerXml -Head $head | Out-String

                }
                else {
                    Write-Host "[$((Get-Date).ToString())] Sending as TEXT" -ForegroundColor Green
                    $body = $data | Out-string
                }
            }
            else {
                Write-Warning "No tasks found due in the next $days days."
                #bail out
                return
            }
            $hash.Add("Body", $body)
            $hash.Add("Subject", "Tasks Due in the Next $days Days")
            $hash.Add("ErrorAction", "Stop")
            Try {
                Send-MailMessage @hash
                #if you receive the job I wanted to display some sort of result
                Write-Output "[$((Get-Date).ToString())] Message ($($hash.subject)) sent to $($hash.to) from $($hash.from)"
            }
            Catch {
                throw $_
            }
        } #define scriptblock
    } #begin

    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Testing for an existing job"
        Try {
            $job = Get-ScheduledJob -Name myTasksEmail -ErrorAction stop
            if ($job) {
                Write-Warning "An existing mail job was found. Please remove it first with Disable-EmailReminder and try again."
                #bail out
                return
            }
        }
        Catch {
            Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] No existing job found"
        }
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Validating Requirements"
        if ((Get-Module PSScheduledJob) -And (($PSVersionTable.Platform -eq 'Win32NT') -OR ($PSVersionTable.PSEdition -eq 'Desktop'))) {

            Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Creating a Daily job trigger for $($Time.TimeofDay)"
            $trigger = New-JobTrigger -Daily -At $Time

            $opt = New-ScheduledJobOption -RunElevated -RequireNetwork
            Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Registering the scheduled job"
            if ($AsHtml) {
                $hash.Add("BodyAsHTML", $True)
            }
            #hash table of parameters to splat Register-ScheduledJob
            $regParams = @{
                ScriptBlock        = $sb
                Name               = "myTasksEmail"
                Trigger            = $Trigger
                ArgumentList       = $hash, $Days, $TaskPath
                MaxResultCount     = 5
                ScheduledJobOption = $opt
                Credential         = $TaskCredential
            }
            $regParams | Out-String | Write-Verbose
            Register-ScheduledJob  @regParams
        }
        else {
            Write-Warning "This command requires the PSScheduledJob module on a Windows platform."
        }
    } #process

    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
    } #end

} #close Enable-MailReminder

Function Disable-EmailReminder {
    [cmdletbinding(SupportsShouldProcess)]
    [OutputType("None")]

    Param()
    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
    } #begin

    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing"
        if ((Get-Module PSScheduledJob) -And (($PSVersionTable.Platform -eq 'Win32NT') -OR ($PSVersionTable.PSEdition -eq 'Desktop'))) {
            Try {
                if (Get-ScheduledJob -Name myTasksEmail -ErrorAction stop) {
                    #The cmdlet appears to ignore -WhatIf so I'll handle it myself
                    if ($PSCmdlet.ShouldProcess("myTasksEmail")) {
                        Unregister-ScheduledJob -Name myTasksEmail -ErrorAction stop
                    } #should process
                } #if task found
            }
            Catch {
                Write-Warning "Can't find any matching scheduled jobs with the name 'myTasksEmail'."
            }
        }
        else {
            Write-Warning "This command requires the PSScheduledJob module on a Windows platform."
        }
    } #process

    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
    } #end

} #close Disable-EmailReminder

Function Get-EmailReminder {
    [cmdletbinding()]
    Param ()

    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"

    } #begin

    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Getting scheduled job myTasksEmail"
        if ((Get-Module PSScheduledJob -ListAvailable) -And (($PSVersionTable.Platform -eq 'Win32NT') -OR ($PSVersionTable.PSEdition -eq 'Desktop'))) {
            $t = Get-ScheduledJob myTasksEmail

            $hash = $t.InvocationInfo.Parameters[0].where( {$_.name -eq "argumentlist"}).value

            Try {
                #get the last run
                Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Getting last job run"
                $last = Get-Job -name $t.name -Newest 1 -ErrorAction stop
            }
            Catch {
                $last = [PSCustomObject]@{
                    PSEndTime = "11/30/1999" -as [datetime]
                    State     = "The task has not yet run"
                }
            }
            [pscustomobject]@{
                Task       = $t.Name
                Frequency  = $t.JobTriggers.Frequency
                At         = $t.JobTriggers.at.TimeOfDay
                To         = $hash.To
                From       = $hash.From
                MailServer = $hash.SMTPServer
                Port       = $hash.Port
                UseSSL     = $hash.UseSSL
                AsHTML     = $hash.BodyAsHTML
                LastRun    = $last.PSEndTime
                LastState  = $last.State
                Started    = $last.psBeginTime
                Ended      = $last.psEndTime
                Result     = $last.output
                Enabled    = $t.Enabled
                Errors     = $last.Errors
                Warnings   = $last.warnings
            }
        }
        else {
            Write-Warning "This command requires the PSScheduledJob module on a Windows platform."
        }
    } #process

    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"

    } #end

} #close Get-EmailReminder