【问题标题】:sending bulk mail with HTML formatted发送 HTML 格式的批量邮件
【发布时间】:2021-02-04 20:57:54
【问题描述】:

我有一个脚本,如果他们的帐户将在接下来的 30 天内到期,它将向员工的经理发送一封电子邮件。我正在逐个提取每个帐户 我已经代表支持部门向他们的经理发送了一封包含员工姓名和到期日期的 HTML 格式的电子邮件。

但我不想将通知邮件一一发送给他们的经理。例如,有时可能有 30 到 50 个用户从 Active Directory 向经理直接和间接报告。所以我的脚本将为每个过期用户发送邮件给经理。他们不想要这个。

我的问题是: 1- 我如何发送通知邮件这两个帐户将在接下来的 30 天内到期并批量发送给他们的经理而不是一个一个?

例如(John、Michael、Andy、Aaron 直接向 theirmanager@domain.com 汇报)

To: John, Michael, Andy, Aaron
Cc: theirmanager@domain.com

2- 我想发送 HTML 格式的邮件而不是短信。

消息:

"***The network account for $($name.name) will be expiring on $(($name.AccountExpirationDate).ToShortDateString()), as their manager, could you please confirm they will still be continuing with their role in order to extend their account.*** "

我想要的输出:

例如 HTML 表格格式

name    SamAccountName  AccountExpirationDate   EmployeeID
John    PRD192888     1/31/2021 12:00:00 AM     102928
Michael PRD192876     2/14/2021 12:00:00 AM     102924
Andy    PRD192834     1/12/2021 12:00:00 AM     102934
Aaron   PRD192234     1/31/2021 12:00:00 AM     102679

脚本:

$user = Search-ADAccount -AccountExpiring -TimeSpan 30.00:00:00 | Where-Object { ($_.Enabled -eq $true) -and  ($_.samAccountName -notlike "SCN*") -and ($_.samAccountName -notlike "CVB*") -and  ($_.samAccountName -notlike "PCN*") }

#pulling each account one by one and check to make sure they have a manager assigned. If not those names are piped into a file
foreach ($name in $user){
    If (( Get-ADUser -Identity $name.SamAccountName -Properties *).Manager -eq $null) {
        Write-Host "no manager listed for" $name.name ;
        Add-Content -Path \\path\Folder\No_manager_listed.txt `
        -Value "$(($name.AccountExpirationDate).ToShortDateString())`t $($name.name)"
        }
#accounts with manager are taken one at a time by username to pull out their managers email address.
#this will also send them an email with the employee's name and expiration date on behalf of desktop Support to thier manager
    else { 
    $manager = ( Get-ADUser -Identity $name.SamAccountName -Properties * ).Manager
    $manager_email = (Get-ADUser -Identity $manager -Properties *).mail
    Write-Host "sending notification email to" $manager_email;
    Send-MailMessage -From DesktopSupport@urdomain.com `
    -Subject "Team member account will expire soon" `
    -To $manager_email `
    -Body "***The network account for $($name.name) will be expiring on $(($name.AccountExpirationDate).ToShortDateString()), as their manager, could you please confirm they will still be continuing with their role in order to extend their account.  If they will need an extension, please reply to this email with your approval and we can extend their accounts another 90 days.  If the listed employee is to be transitioned over to a permanent FTE with urdomain, please forward your response to HumanResources@urdomain.com in order to begin the process.  Thank you.***  " `
    -BodyAsHtml -Priority High -SmtpServer postmaster.urdomain.com
            }
}
#this section will email the file that was created from the employees with no manager and email it to desktop support
if (Test-Path \\path\Folder\No_manager_listed.txt){
    Send-MailMessage -From DesktopSupport@urdomain.com `
    -Subject "Expiring accounts with no manager listed report " `
    -To IT-DesktopSupport@urdomain.com `
    -Attachments \\path\Folder\No_manager_listed.txt `
    -Body "****This an automated message. Please review the attachment.***" `
    -BodyAsHtml -Priority High -SmtpServer postmaster.urdomain.com ;
    Start-Sleep -Seconds "10"
    Remove-Item -Path \\path\Folder\\No_manager_listed.txt 
}

【问题讨论】:

    标签: powershell


    【解决方案1】:

    首先,我认为用户不应该知道其他用户,只有管理员才能看到他们。
    因为显然对您发送的每封电子邮件使用相同的样式(字体和字体颜色)很重要,所以我会将您的代码更改为如下内容:

    第 1 步:

    为 HTML 电子邮件定义样式,以便它们都具有相同的字体和颜色

    $style = @"
    <style>
        body, table {font-family: sans-serif; font-size: 11pt; color: #1F497D;}
        table {border: 1px solid black; border-collapse: collapse; color: #000000;}
        th {border: 1px solid black; background: #dddddd; padding: 3px;}
        td {border: 1px solid black; padding: 3px;}
    </style>
    "@
    

    第 2 步:

    查找帐户到期日期在未来 30 天内的用户

    # find expiring users and store the AD properties in variable $users
    $users = Search-ADAccount -AccountExpiring -TimeSpan 30.00:00:00 -UsersOnly | 
             Where-Object { ($_.Enabled -eq $true) -and  ($_.SamAccountName -notmatch '^(SCN|CVB|PCN)') } |
             ForEach-Object {
                Get-ADUser -Identity $_.SamAccountName -Properties EmailAddress, AccountExpirationDate, Manager
             }
    

    可能更快(取决于用户数量)的替代方案 以上是跳过Search-ADAccount cmdlet 并执行:

    $refDate = (Get-Date).AddDays(30).Date
    $users = Get-ADUser -Filter "Enabled -eq 'True'" -Properties EmailAddress, AccountExpirationDate, Manager | 
             Where-Object { ($_.AccountExpirationDate -le $refDate) -and  ($_.SamAccountName -notmatch '^(SCN|CVB|PCN)') }
    

    第 3 步:

    现在我们已经有了帐户即将过期的用户,我们可以将这些用户分为没有填写 Manager 属性的用户和填写 Manager 属性的用户

    # create a template to use for mailing the desk support people
    # this uses only 1 placeholder to fill in (style)
    $mailTemplate = @"
    <html><head>{0}</head><body>
    This an automated message.<br />Please review the attachment.<br /><br />Thank you.
    </body></html>
    "@
    
    $noManagerFile = '\\path\Folder\No_manager_listed.csv'
    # filter the users that have no manager listed
    $unmanagedUsers = @($users | Where-Object { [string]::IsNullOrEmpty($_.Manager) })
    if ($unmanagedUsers.Count) {
        Write-Host "There are $($unmanagedUsers.Count) users without manager."
        # output a summary of these users as CSV file to send as attachment to desktop support
        $unmanagedUsers | Select-Object @{Name = 'AccountExpirationDate'; Expression = {$_.AccountExpirationDate.ToShortDateString()}}, Name | 
                          Export-Csv -Path $noManagerFile -NoTypeInformation
    
        # send an email with attachment for unmanaged users
        $mailParams = @{
            To         = 'IT-DesktopSupport@urdomain.com'
            From       = 'DesktopSupport@urdomain.com'
            Subject    = 'Expiring accounts with no manager listed report'
            Body       = $mailTemplate -f $style
            BodyAsHtml = $true
            Priority   = 'High'
            SmtpServer = 'postmaster.urdomain.com'
            Attachments = $noManagerFile
            # more parameters go here
        }
        Send-MailMessage @mailParams
    }
    

    第 4 步:

    接下来,向每个经理发送一封电子邮件,列出所有即将到期的帐户

    # create a template to use for mailing the managers
    # this uses 3 placeholders to fill in (style, manager name, and the table of expiring user accounts)
    $mailTemplate = @"
    <html><head>{0}</head><body>
    Dear {1},<br /><br />
    
    The network accounts for the users below will be expiring within the next 30 days.<br />
    {2}
    <br />
    As their manager, could you please confirm they will still be continuing with their role in order to extend their account.<br />
    If they will need an extension, please reply to this email with your approval and we can extend their accounts another 90 days.<br /><br />
    If the listed employee is to be transitioned over to a permanent FTE with urdomain, please forward your response to 
    <a href="mailto:HumanResources@urdomain.com">Human Resources</a> in order to begin the process.  
    <br /><br />
    Thank you.
    </body></html>
    "@
    
    # filter out the users that have a Manager listed and group them using the Manager property
    # by grouping first, you only need to do Get-ADUser for each manager once.
    $managedUsers = $users | Where-Object { ![string]::IsNullOrEmpty($_.Manager) } | Group-Object Manager
    
    foreach ($mgrGroup in $managedUsers) {
        # get the manager AD object using the DN from the users Manager attribute to get properties we need from that
        $manager  = Get-ADUser -Identity $mgrGroup.Name -Properties EmailAddress
        $mgrName  = $manager.Name
        $mgrEmail = $manager.EmailAddress
    
        # if the manager has no email address, report it on screen
        if ([string]::IsNullOrWhiteSpace($mgrEmail)) {
            Write-Warning "Could not get email address for manager $($mgrGroup.Name)"
        }
        else {
            # create a table from the user data in the group
            $table = ($mgrGroup.Group | 
                      Select-Object Name, EmailAddress, @{Name = 'ExpiryDate'; Expression = {$_.AccountExpirationDate.ToShortDateString()}} | 
                      ConvertTo-Html -As Table -Fragment) -join [environment]::NewLine
    
            $mailParams = @{
                To         = $mgrEmail
                From       = 'DesktopSupport@urdomain.com'
                Subject    = 'Expiring Team member accounts'
                Body       = $mailTemplate -f $style, $mgrName, $table  # fill in the placeholders of the mail template
                BodyAsHtml = $true
                Priority   = 'High'
                SmtpServer = 'postmaster.urdomain.com'
                # more parameters go here
            }
            # send this manager an email with a table of all expiring users that report to him/her
            Send-MailMessage @mailParams
        }
    }
    

    第 5 步:

    接下来(如果需要)向每个用户分别发送电子邮件告知他们的帐户即将过期。他们无需了解其他用户

    # create a template to use for mailing the users
    # this uses 3 placeholders to fill in (style, first name and expiration date)
    $mailTemplate = @"
    <html><head>{0}</head><body>
    Dear {1},<br /><br />
    This is to inform you that your user account will expire on <strong>{2}</strong><br /><br />
    DesktopSupport
    </body></html>
    "@
    
    # send each expiring user that has an email address an email individually
    $users | Where-Object { ![string]::IsNullOrWhiteSpace($_.EmailAddress) } | ForEach-Object {
            $mailParams = @{
                To         = $_.EmailAddress
                From       = 'DesktopSupport@urdomain.com'
                Subject    = 'Your user account will expire soon!'
                Body       = $mailTemplate -f $style, $_.GivenName, ('{0:MMMM d, yyyy}' -f $_.AccountExpirationDate)
                BodyAsHtml = $true
                Priority   = 'High'
                SmtpServer = 'postmaster.urdomain.com'
                # more parameters go here
            }
            #Send-MailMessage @mailParams
    }
    

    第 6 步:

    查找任何没有电子邮件地址的“剩余用户”。
    只需将其作为警告输出到控制台

    # test if there were users without email address
    $noEmail = @($users | Where-Object { [string]::IsNullOrWhiteSpace($_.EmailAddress) })
    if ($noEmail.Count) {
        Write-Warning "These user do not have an email address:"
        $noEmail | Format-Table -Property Name, SamAccountName, AccountExpirationDate
    }
    

    【讨论】:

    • 谢谢,但我收到一条错误消息Add-Member : Cannot add a member with the name "ManagerName" because a member with that name already exists. To overwrite the member anyway, add the Force parameter to your command.
    • 就像你说的,我添加了Force参数($manager.Name,$manager.EmailAddress)。但没有运气。另外,我检查了managedUsers 变量。它是空的。通常,我需要 2 个 AD 帐户。
    • 同样的问题。(Add-Member : Cannot add a member with the name ....) 另外,我收到了Send-MailMessage : The specified string is not in the form required for an e-mail address.
    • 现在,我检查了 users 变量。有经理:CN=John,DC=contoso,DC,=local ManagerEmail:{}
    • 另外,我检查了 managedUsers 变量。结果:计数:2 名称 {} 组:{CN=user1,OU=TEST,DC=contoso,DC=local, CN=user2,OU=TEST,DC=contoso,DC=local} 正常吗?
    【解决方案2】:

    Powershell 具有用于 HTML 输出的 cmdlet。创建一个集合来保存您的表格数据。

    # Get specifics for a module, cmdlet, or function
    (Get-Command -Name ConvertTo-Html).Parameters
    (Get-Command -Name ConvertTo-Html).Parameters.Keys
    Get-help -Name ConvertTo-Html -Examples
    Get-help -Name ConvertTo-Html -Full
    Get-help -Name ConvertTo-Html -Online
    

    使用 MS powershellgallery.com 中的模块创建 HTML 电子邮件也是一个有据可查的事情

     Find-Module -Name '*html*'
    # Results
    <#
    Version  Name              Repository Description                                                                                                                                 
    -------  ----              ---------- -----------                                                                                                                                 
    0.0.130  PSWriteHTML       PSGallery  Module that allows creating HTML content/reports in a easy way.                                                                             
    2.2.2    MarkdownToHtml    PSGallery  Highly configurable markdown to HTML conversion using customizable templates....                                                            
    0.1.7    PowerHTML         PSGallery  Provides a wrapper for HTML Agility Pack for use where the IE HTML ...
    1.4.1.2  ReportHTML        PSGallery  A powerful module for creating HTML reports within PowerShell no HTML coding required....
    ...
    #>
    

    或者使用样式/CSS。 SO上有很多例子:

    PowerShell Display Table In HTML Email

    ...以及整个网络。

    'PowerShell html table email'

    点击示例

    How to Send SMTP Email Using PowerShell (Part 4)

    Sending HTML emails with PowerShell and zero HTML knowledge required

    示例:

    $disks = GET-WMIOBJECT win32_logicaldisk -filter "DriveType='3'"
    
    foreach($disk in $disks)
    {
        $DriveLetter = $disk.DeviceID;
        $SizeGB      = $disk.Size / 1GB -as [int]
        $FreeSpaceGB = $disk.FreeSpace / 1GB -as [int]
        $PercentFree = [math]::Round((1- ($freeSpaceGB/ $sizeGB)) * 100)
    
        $dataRow = "
        </tr>
            <td>$DriveLetter</td>
            <td>$SizeGB GB</td>
            <td>$FreeSpaceGB GB</td>
            <td>$PercentFree %</td>
        </tr>
        "
        $diskreport += $datarow
    }
    
    $report = "<html>
    <style>
        {font-family: Arial; font-size: 13pt;}
        TABLE{border: 1px solid black; border-collapse: collapse; font-size:13pt;}
        TH{border: 1px solid black; background: #dddddd; padding: 5px; color: #000000;}
        TD{border: 1px solid black; padding: 5px; }
    </style>
    <h2>Server Space Report</h2>
    <table>
        <tr>
            <th>Volume</th>
            <th>Total Space</th>
            <th>Free Space</th>
            <th>Percent Full</th>
        </tr>
    $diskreport
    </table>
    <tr>
    "
    
    
    $sendMailMessageSplat = @{
        From              = 'ServerReport@test.com'
        To                = 'luke@test.com'
        Subject           = "Server Disk Space Report"
        Body              = $report
        SmtpServer        = 'mysmtpserver.com'
    }
    Send-MailMessage @sendMailMessageSplat
    

    【讨论】:

      猜你喜欢
      • 2016-10-13
      • 1970-01-01
      • 2014-09-14
      • 2013-10-18
      • 2010-11-26
      • 2014-06-22
      • 2016-06-02
      相关资源
      最近更新 更多