PowerShell: Send Email Notifications to Computer Users Before Maintentance

# sendEmailToUsers.ps1

# Query Active Directory for computers running a Server operating system 
#$targetServers = (Get-ADComputer -Filter {OperatingSystem -like "*server*"}).Name
$targetMachines='SHERVER007'

# Get today's date for the report 
$scheduledTime = "20/20/2020 8:00PM to 11:59PM Pacific Time" 
 
# Setup email parameters
$emailFrom = "helpdesk@kimconnect.com"
$cc="systemsteam@kimconnect.com"
$subject = "Server Maintenance Schedule @ $scheduledTime"
$telephone="(555) 555-5555"
$bodySuffix="We advise that you save all your work before that time to ensure that your data is unaffected.<br><br>Please don't hesitate to contact Helpdesk if you experience issues related to this activity.<br><br>KimConnect Helpdesk<br>Email: $emailFrom<br>Telephone: $telephone"
$emailBody = "There shall be a scheduled maintenance during $scheduledTime on these machines:<br><br>$($targetMachines|%{"- "+$_.ToString().ToUpper()+"<br>"})<br>"
$smtpServer = "relay.kimconnect.nowhere"
$priority = "Normal"
$manager="Kim Connect"
 
# Import the Active Directory module for the Get-ADComputer CmdLet 
if(!(get-command get-aduser)){
    Import-Module ServerManager
    Add-WindowsFeature RSAT-AD-PowerShell
    }
Import-Module ActiveDirectory 

function getRecentUserEmails($servers){
    # Local variables    
    $usersAndEmails=@();

    # Loop through the list to query each server for login sessions 
    ForEach ($server in $servers) {
        
        <#
        # Get current RDP sessions
        $rdpUsers=@();
        $queryResults = qwinsta /server:$server | foreach { (($_.trim() -replace "\s+",","))} | ConvertFrom-Csv      
        # parse the results
        ForEach ($queryResult in $queryResults) { 
            $rdpUser = $queryResult.USERNAME 
            $sessionLabel = $queryResult.SESSIONNAME 
       
            # Obtain a list of users
            If (($rdpUser -match "[a-zA-Z]") -and ($rdpUser -ne $NULL)) {  
                $rdpUsers+=,$rdpUser
                }elseif($sessionLabel -match "[a-zA-Z]"-and ($sessionLabel -ne $NULL)){
                    $rdpUsers+=,$sessionLabel
                    }
            } 
        #>

        # Get all logon recent sessions
        $recentLogons=.{
                            $lastLogons=@();                        
                            $logonEvents=Get-WmiObject -Class Win32_UserProfile -ComputerName $server | Sort-Object -Property LastUseTime -Descending |?{$_.SID -notmatch "(S-1-5-18|S-1-5-19|S-1-5-20)"}
                            if ($logonEvents){
                            $usersCount=$logonEvents.Length;
                            for ($i=0;$i -lt $usersCount; $i++){                
                                $sid=$logonEvents[$i].SID
                                try{
                                    $user=(New-Object System.Security.Principal.SecurityIdentifier($sid)).Translate([System.Security.Principal.NTAccount]).Value
                                    $user=.{
                                        $domain=.{[void]($user -match "^([A-Za-z0-9]*)\\");return $matches[1]}
                                        $serverHost=.{if($server -match "\."){[void]($server -match "^([A-Za-z0-9]*)\.");return $matches[1]}else{return $server}}
                                        if ($domain -ne $server){
                                            [void]($user -match "([A-Za-z0-9]*)$");
                                            return $matches[1]
                                            }
                                        }
                                    }
                                catch{
                                    #$user=$logonEvents[$i].SID
                                    }
                                #$logonTime=([WMI]'').ConvertToDateTime($logonEvents[$i].LastUseTime)                      
                                $count=$i+1;                 
                                #$lastLogons+=,@($user,$logonTime);
                                $lastLogons+=,$user
                                }
                            }        
                            return $lastLogons
                        }

        # Merge $rdpUsers with $recentLogons together
        #$users=($rdpUsers+$recentLogons)|Select-Object -Unique|sort
        $users=$recentLogons|Select -Unique|sort

        foreach ($user in $users){
            try{
                $userObject=get-aduser -Identity $user -Properties * -ErrorAction Stop
                $emailAddress=$userObject.mail
                $firstname=$userObject.GivenName
                $lastname=$userObject.Surname
                write-host "$firstName $lastName $emailAddress"
                $usersAndEmails+=,("$firstName $lastName",$emailAddress)
                }
            catch{
                #write-host "$user is invalid."
                }
            }
    }
    return $usersAndEmails|Select-Object -Unique
}

# Send the report email
function sendEmailToUsers($usersEmailArray){    
    # Notify Helpdesk
    $helpdeskEmailPrefix="Hello Helpdesk,<br><br>"
    $helpdeskEmailSuffix="Be advised that these users will be impacted:<br><br>$($usersEmailArray|%{"- "+$_[0]+": "+$_[1]+"<br>"})<br>Please contact $manager with any questions or concerns"
    $helpdeskEmailBody = $helpdeskEmailPrefix+$emailBody+$helpdeskEmailSuffix
    Send-MailMessage -From $emailFrom -To $emailFrom -Cc $cc -Subject $subject -Body $helpdeskEmailBody -SmtpServer $smtpServer -Priority $priority

    # Notify each user individually to avoid a 'reply-all' situation
    foreach ($item in $usersEmailArray){
        $name=$item[0];
        $emailTo=$item[1];
        #$machine=($item[0]).toString().toUpper();
        $bodyPrefix="Hello $name,<br><br>"
        $body = $bodyPrefix+$emailBody+$bodySuffix
        if ($emailTo -ne $null){
            Send-MailMessage -From $emailFrom -To $emailTo -Subject $subject -Body $body -SmtpServer $smtpServer -Priority $priority 
            write-host "$name with email address $emailTo has been processed successfully."
            sleep 1
            }else{
                write-warning "$name doesn't have an email address - skipping this record."
                }
        }
    }

function sendCorrectionEmail($usersEmailArray){
    # Notify Helpdesk
    $helpdeskEmailPrefix="Hello Helpdesk,<br><br>"
    $correctionMessage="Please allow a correction to the previous email: the maintenance time window is <strong style='color: red;'>$scheduledTime</strong><br><br>"
    $correctionEmailSuffix="Thank you,<br><br>-Systems Team"
    $correctionEmailBody = $helpdeskEmailPrefix+$correctionMessage+$correctionEmailSuffix
    Send-MailMessage -From $emailFrom -To $emailFrom -Cc $cc -Subject $subject -Body $correctionEmailBody -BodyAsHtml -SmtpServer $smtpServer -Priority $priority

    # Notify each user individually to avoid a 'reply-all' situation
    foreach ($item in $usersEmailArray){
        $name=$item[0];
        $emailTo=$item[1];
        #$machine=($item[0]).toString().toUpper();
        $bodyPrefix="Hello $name,<br><br>"
        $body = $bodyPrefix+$correctionMessage+$correctionEmailSuffix
        if ($emailTo -ne $null){
            Send-MailMessage -From $emailFrom -To $emailTo -Subject $subject -Body $body  -BodyAsHtml -SmtpServer $smtpServer -Priority $priority 
            write-host "$name with email address $emailTo has been processed successfully."
            sleep 1
            }else{
                write-warning "$name doesn't have an email address - skipping this record."
                }
        }    
    }

$usersEmailArray = getRecentUserEmails $targetMachines
sendEmailToUsers $usersEmailArray
# sendCorrectionEmail $usersEmailArray

Leave a Reply

Your email address will not be published. Required fields are marked *