Repository: microsoft/CSS-Exchange
File: M365/MDO/ResendFailedMail.ps1 (PowerShell)

Code before:

if ($null -eq $acceptedDomains) {
    Write-Host "We do not get accepted domains." -ForegroundColor Red
    exit
}

if ($acceptedDomains.count -eq 0) {
    Write-Host "No accepted domains found." -ForegroundColor Red
    exit
} else {
    $acceptedDomainList = New-Object System.Collections.Generic.List[string]
    $acceptedDomains | ForEach-Object { $acceptedDomainList.Add($_.DomainName.ToString()) }
}

$failedMessages = $null
$failedMessages = Get-MessageTrace -StartDate (Get-Date).AddDays(-$Days) -EndDate (Get-Date) | Where-Object { $_.Status -eq "Failed" }

if ($Sender) { $failedMessages = $failedMessages | Where-Object { $Sender -contains $_.SenderAddress } }
if ($Subject) { $failedMessages = $failedMessages | Where-Object { $Subject -contains $_.Subject } }
if ($Recipient) { $failedMessages = $failedMessages | Where-Object { $Recipient -contains $_.RecipientAddress } }
if ($MessageId) { $failedMessages = $failedMessages | Where-Object { $MessageId -contains $_.MessageId } }
if (-not $IncludeDuplicates) { $failedMessages = $failedMessages | Sort-Object MessageId -Unique }

$failedMessages = $failedMessages | Where-Object { $acceptedDomainList -contains $_.SenderAddress.Split("@")[1] }

$verifiedAcceptedSenderMessages = @()
foreach ($failedMessage in $failedMessages) {
    Write-Verbose "Checking $($failedMessage.SenderAddress)"
    $tempAddress = $null
    if ($recipientCache.ContainsKey($failedMessage.SenderAddress)) {
        Write-Verbose "Recipient $($failedMessage.SenderAddress) found in cache"
        $verifiedAcceptedSenderMessages += $failedMessage
    } else {
        try {
            $tempAddress = Get-EXORecipient $failedMessage.SenderAddress -ErrorAction Stop
            if ($null -eq $tempAddress) {
                Write-Host "Sender $($failedMessage.RecipientAddress) is not a recipient in this tenant." -ForegroundColor Yellow
                Write-Host "Discarded $($failedMessage.MessageId) - Subject: $($failedMessage.Subject)" -ForegroundColor Yellow
            } else {
                Write-Verbose "Added to cache Recipient $($failedMessage.SenderAddress) with Id $($failedMessage.SenderAddress)"
                $recipientCache[$failedMessage.SenderAddress] = $failedMessage.SenderAddress
                Write-Verbose "Verified $($failedMessage.SenderAddress)"
                $verifiedAcceptedSenderMessages += $failedMessage
            }
        } catch {
            Write-Host "Error getting Sender $($failedMessage.SenderAddress)" -ForegroundColor Yellow
            Write-Host "Discarded $($failedMessage.MessageId) - Subject: $($failedMessage.Subject)" -ForegroundColor Yellow
            Write-Verbose "$_"
        }
    }
}

Review comment (performance):
This will slow down the script if there are a lot of items to add to the list. Recommend to use `New-Object System.Collections.Generic.List[object]` instead of `@()` for a generic static array. 

Code after:

$verifiedAcceptedSenderMessages = New-Object System.Collections.Generic.List[object]
$count = 0
$totalMessages = $failedMessages.Count
foreach ($failedMessage in $failedMessages) {
    $count++
    Write-Progress -Activity "Checking Progress" -Status "$count of $totalMessages" -PercentComplete ($count / $totalMessages * 100) -CurrentOperation "Checking message $($failedMessage.MessageId) - Subject: $($failedMessage.Subject)"
    Write-Verbose "Checking $($failedMessage.SenderAddress)"
    $tempAddress = $null
    if ($recipientCache.ContainsKey($failedMessage.SenderAddress)) {
        Write-Verbose "RecipientAddress  $($failedMessage.SenderAddress) found in cache"
        if ($recipientCache[$failedMessage.SenderAddress]) {
            $verifiedAcceptedSenderMessages.Add($failedMessage)
        } else {
            Write-Verbose "Sender $($failedMessage.SenderAddress) is not a recipient in this tenant."
            Write-Verbose "Discarded $($failedMessage.MessageId) - Subject: $($failedMessage.Subject)"
        }
    } else {
        try {
            $tempAddress = Get-EXOMailbox $failedMessage.SenderAddress -ErrorAction Stop
            if ($null -eq $tempAddress) {
                Write-Verbose "Sender $($failedMessage.SenderAddress) is not a recipient in this tenant."
                Write-Verbose "Discarded $($failedMessage.MessageId) - Subject: $($failedMessage.Subject)"
                $recipientCache[$failedMessage.SenderAddress] = $false
            } else {
                Write-Verbose "Added to cache Recipient $($failedMessage.SenderAddress) with Id $($failedMessage.SenderAddress)"
                $recipientCache[$failedMessage.SenderAddress] = $true
                Write-Verbose "Verified $($failedMessage.SenderAddress)"
                $verifiedAcceptedSenderMessages.Add($failedMessage)
            }
        } catch {
            Write-Verbose "Error getting Sender Address $($failedMessage.SenderAddress)"
            Write-Verbose "Discarded $($failedMessage.MessageId) - Subject: $($failedMessage.Subject)"
            $recipientCache[$failedMessage.SenderAddress] = $false
            Write-Verbose "$_"
        }
    }
}

$totalMessages = $verifiedAcceptedSenderMessages.Count
if ($totalMessages -gt 0) {
    if (-not $Force) {
        Write-Host "`nWe are going to resend the following messages:"
        Write-Host ($verifiedAcceptedSenderMessages | Format-Table -AutoSize Received, MessageId, SenderAddress, RecipientAddress, Subject | Out-String)
        Write-Host "Total number of messages: $totalMessages`n"
    }

    if ($Force -or $PSCmdlet.ShouldContinue("Are you sure you want to do it?", "Resend messages")) {
        $count = 0
        $resendCount = 0
        foreach ( $failedMessage in $verifiedAcceptedSenderMessages ) {