itallrounder
Goto Top

Powershell - Versenden von EML Dateien

Guten Morgen,

kurz zum Hintergrund:
Unser Mailgateway hat sich leider verrannt und dadurch diverse Mails (327 Elemente) nicht versendet.
Diese E-Mails liegen uns als .EML Datei vor.

Nun möchten wir diese Mails gerne zustellen.

Problem dabei:
Ich würde die EML Files gerne via Powershell einlesen und an den organalen Empfänger und CC senden.
Das allerdings auch im Namen des eigentlichen Absenders.

Es sind davon nur ausgehende Mails betroffen.

Mein Plan:

Die EML Files in Powershell einlesen, mit den folgenden Werten:

Absender: Mitarbeiterxy@business.de
An: ExterneMailAdresse@kunde.de
CC: DiverseMailAdressen@extern.de
Attachment: Dateianhang
Betreff: Nachrichtenbetreff
Message: Die eigentliche Nachricht

Hat hier ggf. jemand einen Ansatz Punkt für mich?
Wie ich ne Mail per Powershell versende ist klar, doch wie verarbeite ich die Infos aus der EML Datei?
Muss ich diese Infos erst alle in eine CSV schreiben und diese dann zum versenden verwenden?

Ich bin für jede Hilfe sehr Dankbar!


Edit:
Folgendes Skript habe ich nun im Netz gefunden:
Get-ChildItem "C:\temp\Mails\" -Filter *.eml |  
ForEach-Object {
$adoDbStream = New-Object -ComObject ADODB.Stream
$adoDbStream.Open()
$adoDbStream.LoadFromFile($_.FullName)

$cdoMessage = New-Object -ComObject CDO.Message
$cdoMessage.DataSource.OpenObject($adoDbStream, "_Stream")  
$cdoMessage.Fields.Item("urn:schemas:mailheader:to").Value  
$cdoMessage.Fields.Item("urn:schemas:mailheader:from").Value  
$cdoMessage.Fields.Item("urn:schemas:mailheader:subject").Value  
$cdoMessage.Fields.Item("urn:schemas:mailheader:sent").Value  
}
Quelle: http://jon.glass/blog/reads-e-mail-with-powershell/
Leider bekomme ich das ganze nicht in eine CSV exportiert.

Bei dem Versuch mit
Get-ChildItem "C:\temp\Mail-Sophos\" -Filter *.eml | Export-CSV C:\temp\Mail-Sophos\list2.csv -Encoding UTF8 | ForEach-Object {  
Werden die Mailheader Wete nicht exportiert (Absender, Emfpänger etc.)

Content-ID: 618686

Url: https://administrator.de/contentid/618686

Ausgedruckt am: 22.11.2024 um 02:11 Uhr

colinardo
Lösung colinardo 04.11.2020, aktualisiert am 15.05.2023 um 09:55:15 Uhr
Goto Top
Servus @ITAllrounder .
Unser Mailgateway hat sich leider verrannt und dadurch diverse Mails (327 Elemente) nicht versendet.
Warum wiederholt ihr die Versendung der Nachrichten auf dem Gateway nicht nochmal? Eigentlich bietet sowas jedes einigermaßen vernünftige Gateway an, Nachrichten aus einem Queue erneut zu versenden, oder man schiebt diese erneut manuell in die Queue ... Soweit ich mich dumpf erinnern kann bietet das eigentlich auch eine Sophos an.

Wenn es Powershell sein muss, dann würde ich dringend dazu raten zu Mailkit greifen (Code siehe unten), die Send-MailMessage CDO und der .NET SMTP-Client sind ja sicherheitstechnisch nicht mehr auf aktuellem Stand.

(Ordner, SMTP-Server, Port, Username, Password etc. musst du natürlich anpassen / ab Zeile 56-70)
Der verwendete SMTP Account muss natürlich auf dem Mailserver das Recht haben im Namen der jeweiligen Absender zu senden. Außerdem muss in den EML-Dateien der Absender schon hinterlegt sein (wenn nicht kann man ihn auch noch per Code ergänzen/abändern wenn man möchte)
Zur Info: Der Code lädt automatisch 3 nötige DLLs für Mailkit von Nuget herunter sofern sie noch nicht im Skript- oder Temp-Verzeichnis heruntergeladen wurden.
<#
    Resend bunch of *.eml files in a folder / (c) @colinardo
#>

function Load-NugetAssembly {
    [CmdletBinding()]
    param(
        [string]$url,
        [string]$name,
        [string]$zipinternalpath,
        [switch]$downloadonly
    )
    if($psscriptroot -ne ''){  
        $localpath = join-path $psscriptroot $name
    }else{
        $localpath = join-path $env:TEMP $name
    }
    $tmp = "$env:TEMP\$([IO.Path]::GetRandomFileName())"  
    $zip = $null
    try{
        if(!(Test-Path $localpath)){
            Add-Type -A System.IO.Compression.FileSystem
            write-host "Downloading and extracting required library '$name' ... " -F Green -NoNewline  
            (New-Object System.Net.WebClient).DownloadFile($url, $tmp)
            $zip = [System.IO.Compression.ZipFile]::OpenRead($tmp)
            $zip.Entries | ?{$_.Fullname -eq $zipinternalpath} | %{
                [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_,$localpath)
            }
	        Unblock-File -Path $localpath
            write-host "OK" -F Green  
        }
        if(!$downloadonly.IsPresent){
            Add-Type -Path $localpath -EA Stop
        }
        
    }catch{
        write-host ($_.Exception.LoaderExceptions | fl | out-string)
        throw "Error: $($_.Exception.Message)"  

    }finally{
        if ($zip){$zip.Dispose()}
        if(Test-Path $tmp){del $tmp -Force}
    }  
}

# load required assemblies if not already loaded
if (!('MailKit.Net.Smtp.SmtpClient' -as [type])){  
    Load-NugetAssembly 'https://www.nuget.org/api/v2/package/Portable.BouncyCastle/1.8.8' -name 'BouncyCastle.Crypto.dll' -zipinternalpath 'lib/net40/BouncyCastle.Crypto.dll' -EA Stop  
    Load-NugetAssembly 'https://www.nuget.org/api/v2/package/System.Buffers/4.5.1' -name 'System.Buffers.dll' -zipinternalpath 'lib/net461/System.Buffers.dll' -EA Stop  
    Load-NugetAssembly 'https://www.nuget.org/api/v2/package/MimeKit/2.10.1' -name 'MimeKit.dll' -zipinternalpath 'lib/net45/MimeKit.dll' -EA Stop  
    Load-NugetAssembly 'https://www.nuget.org/api/v2/package/MailKit/2.10.1' -name 'MailKit.dll' -zipinternalpath 'lib/net45/MailKit.dll' -EA Stop     
}


# folder with eml files
$folder = "D:\temp\mails"  

$options = $null; $smtp = $null
try{
    # create parser options object
    $options = New-Object MimeKit.ParserOptions
    # create smtp client
    $smtp = New-Object MailKit.Net.Smtp.SmtpClient
    # set accepted tls protocols
    $smtp.SslProtocols = 'Tls11','Tls12','Tls13'  
    # connect to smtp server
    $smtp.Connect("smtp.domain.tld",587,$false)  
    # authenticate with smtp server with username/password
    $smtp.Authenticate("USERNAME",'PASSWORD')  
}catch{
    Write-Error -Message $_.Exception.Message
    return
}

# for each *.eml in folder
foreach($file in Get-ChildItem $folder -File -Filter *.eml){
    try{
        write-host "Sending mail '$($file.Fullname)' ... " -F Green -NoNewline  
        # load eml message
        $msg = [MimeKit.MimeMessage]::Load($options,$file.Fullname)

        # (optional) to add additional recipients (CC/BCC/TO) to the mails you can use the following scheme (uncomment and change recipient)
        # $msg.BCC.Add('user@domain.tld')  
        # $msg.CC.Add('user@domain.tld')  
        # $msg.TO.Add('user@domain.tld')  

        # send message
        $smtp.Send($msg)
        write-host "OK" -F Green  
    }catch{
        Write-Error -Message "Error loading or sending message: $($_.Exception.Message)"   
    }
}

# cleanup
if ($smtp){
    $smtp.Disconnect($true)
    $smtp.Dispose()
}
Viel Spaß damit
Grüße Uwe

Weiterer Support dazu gerne, aber von meiner Seite aus dazu nur per PN
ITAllrounder
ITAllrounder 04.11.2020 um 11:21:58 Uhr
Goto Top
Hallo Uwe,

tausend Dank an dich.
Das Skript lief ohne Fehler durch und die Mails wurden zugestellt face-smile

Leider konnten wir die Zustellung nicht nochmals triggern, da wir das bereits 2x versucht haben.
Das Problem bestand seit dem 02.11.2020 16:23
Alle E-Mails vom 03.11.2020 wurden zugestellt, doch die vom 02.11.20 hingen auf dem Gateway mit der Meldung "Delivery Timeout"

Beste Grüße
colinardo
colinardo 04.11.2020 aktualisiert um 11:27:17 Uhr
Goto Top
Zitat von @ITAllrounder:
tausend Dank an dich.
Immer gerne.
Das Skript lief ohne Fehler durch und die Mails wurden zugestellt face-smile
Freut mich für dich face-smile.

Grüße Uwe