robdox
Goto Top

Mehrere E-Mail empfänger, entsprechende Anhänge zusenden

Hallo zusammen,

ich versuche mittels eines Powershellskriptes mehrere E-Mails an versch. E-Mailadressen mit entsprechenden Anhängen zu verschicken. Ich scheitere jedoch daran, Powershell in einer Funktion den Inhalt des Arrays, in denen die E-Mail Adressen gespeichert sind, sauber zu übermitteln.

Das Skript erstellt zuerst eine SQL Abfrage die korrekte Werte liefert. Der erste Befehl sucht die entsprechenden Datein aus allen bekannten Ordnern und verschiebt diese in einen extra Ordner (MAIL) für die E-Mails. Die E-Mail Adressen werden ebenfalls korrekt ermittelt, anhand der Bedingungen des ersten SQL Befehls. Hierbei sollen dann die Anhänge, welche in den extra Order verschoben wurden, an die im Array befindlichen E-Mail-Adressen geschickt werden.

Powershell liefert mir jedoch zurück, dass das E-Mail Format ungültig ist sowie die Anhänge = NULL sind. Die Adressen stehen in der Datenbank als "mail1@mail.de;mail2@mail2.de;". Diese Splitte ich vorher, entferne die Leerzeichen und möchte Schritt für Schritt eine E-Mail verschicken, mit den dafür ermittelten Anhängen. Ich glaube syntaktisch mach ich etwas falsch oder meine Logik mit den Pipes in einer For-Schleife geht nicht auf.

PS: Wie kann ich abfragen, wenn die E-Mails erfolgreich verschickt wurden, verschiebe die gesendeten Dateien in einen Ordner Send? Hierzu habe ich keine Erfahrung / Idee, bzw. weiss ich nicht, wie ich die Abfrage richtig erstelle, Wenn alle E-Mails erfolgreich geschickt, verschiebe Datei in "SEND". Danke auch dafür!

Ich danke vorab für eure Hilfe!

# Variablen festlegen
$vPfad="C:\DB\"  
$vArchivPfad="C:\DB\MAIL"  
$vFinalPfad="C:\DB\MAIL\SEND"  
$vCommand="  
			select top 100 percent sb.Nr_ListeA from Send_Basis sb 
			left join Kund_Basis kb on kb.id=sb.ID_AG
			where kb.mc in (select ti.xs from Tabelle_Basis tb 
            left join Tabelle_Folgen tf on tf.ID=tb.ID_Tabelle_Folge 
            left join Tabelle_Item ti on ti.ID_Tabelle_Basis=tb.ID where tf.MC='CMR')  
			and sb.ID in (select ID_Send from Send_ListenPos where K_Listenart=4)
			order by sb.ID
		  "  
$vCMD_Mail="  
            select top 100 percent ti.Wert from Tabelle_Basis tb 
            left join Tabelle_Folgen tf on tf.ID=tb.ID_Tabelle_Folge 
            left join Tabelle_Item ti on ti.ID_Tabelle_Basis=tb.ID where tf.MC='CMR'   
			and ti.Xs in (select kb.mc from Kund_Basis kb left join Send_Basis sb on sb.ID_AG=kb.ID
			where sb.ID in (select ID_Send from Send_ListenPos where K_Listenart=4))
			order by ti.ID
           "  

$body = "Irgendein Text"  

# SQL Funktion zum zusammenstellen der Prüftabelle
function querySQL {
    Param(
        [string]$cSQL
    )
    # Connectionstring aus m3.config
    $connectionString = "Data Source=DB\m3db; Initial Catalog=db2_TBL; user id=sa; pwd=xxxxxxxxx"  

    # SQL Verbindung aufbauen
    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    $command = new-object system.data.sqlclient.sqlcommand($cSQL,$connection)
    $connection.Open()
    $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
    $dataset = New-Object System.Data.DataSet
    
    # Tabelle erstellen
    $adapter.Fill($dataSet) | Out-null
    $connection.Close()
    $dataSet.Tables
}

function CMR_Mail($Mail_Msg, $body, $Mail_File) {
       
        #Mail erzeugen
        $Mail_Host = new-object system.net.mail.smtpClient
        $Mail_Msg = New-Object system.net.mail.mailmessage

        $Mail_Att = new-object Net.Mail.Attachment($Mail_File)

        $Mail_Msg.Attachments.Add($Mail_Att)

        $Mail_Host.Host = "exchange2016.domain.de"  
        $Mail_Msg.from = "CMR@mail.it"   

        $Mail_Msg.To.add($Mail_Msg)
        $Mail_Msg.Subject = “CMR von Rollkarte: " + $Mail_File.BaseName  

        $Mail_Msg.IsBodyHtml = $false
        $Mail_Msg.Body = $body

        $Mail_Host.Send($Mail_Msg)

    }

# SQL Werte auslesen
[array]$result = (querySQL -cSQL $vCommand).Nr_ListeA

# E-Mail vom AG auslesen, und jede einzelne E-Mail
[array]$result_mail = (querySQL -cSQL $vCMD_Mail).Wert
[array]$Adresse = $result_mail.split(";")  

# Leerzeichen weg
$Adresse=$Adresse.TrimStart();
$Adresse=$Adresse.TrimEnd();

# Liste aller Dateien durchsuchen
$files = Get-ChildItem -Path $vPfad -Recurse -Include "*.pdf"  

#Pattern für regex-match vorbereiten
$pattern = ($result | %{[regex]::escape($_)}) -join "|"   

# Gefundene Dateien für Agenten bereitstellen
for($i=0; $i -lt $Adresse.Length; $i++) {
  $files | ?{$_.Basename -match $pattern} | Copy-Item -Destination $vArchivPfad | CMR_Mail $Adresse[$i] $body $files 
}

Content-ID: 535289

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

Ausgedruckt am: 22.11.2024 um 12:11 Uhr

Bitboy
Bitboy 15.01.2020 um 15:49:13 Uhr
Goto Top
Moin,

ohne genau zu gucken und ohne ausreichend Kaffee Zufuhr...
dieser Teil sieht komisch aus:

function CMR_Mail($Mail_Msg, $body, $Mail_File) {
#Mail erzeugen
$Mail_Host = new-object system.net.mail.smtpClient
$Mail_Msg = New-Object system.net.mail.mailmessage


Die Funktion nimmt ein $Mail_Msg als Parameter an und und danach überschreibst du $Mail_Msg mit New-Object.

In Zeile 59 dann $Mail_Msg.To.add($Mail_Msg) dabei steht da ja gar keine gültige Mailadresse mehr drin.

Grüße
robdox
robdox 16.01.2020 um 11:26:45 Uhr
Goto Top
Hey,

danke vorab! hab ich verstanden- jedoch wird nun NULL für den attachment zurückgeliefert und der SMTP server antwortet aufeinmal nicht mehr. Warum funktioniert meine Schleife nicht ?

function CMR_Mail($Mail, $body, $Mail_File) {
       
        #Mailobjekt erzeugen
        $Mail_Host = New-Object system.net.mail.smtpClient
        $Mail_Msg  = New-Object system.net.mail.mailmessage
        $Mail_Att  = New-object Net.Mail.Attachment($Mail_File)
                        
        $Mail_Msg.Attachments.Add($Mail_Att)

        $Mail_Host.Host = "exchange2016.domain.de"  
        $Mail_Msg.from  = "CMR@mail.it"   

        $Mail_Msg.To.add($Mail)
        $Mail_Msg.Subject = “CMR von Rollkarte: " + $Mail_File.BaseName  

        $Mail_Msg.IsBodyHtml = $false
        $Mail_Msg.Body       = $body

        $Mail_Host.Send($Mail_Msg)

}

# SQL Werte auslesen und entsprechende Dateien in Ordner verschieben
[array]$result = (querySQL -cSQL $vCommand).Nr_ListeA

# E-Mail vom AG auslesen, und jede einzelne E-Mail
[array]$result_mail = (querySQL -cSQL $vCMD_Mail).Wert
[array]$Adresse = $result_mail.split(";")  

# Leerzeichen weg
$Adresse=$Adresse.TrimStart();
$Adresse=$Adresse.TrimEnd();

# Liste aller Dateien durchsuchen
$files = Get-ChildItem -Path $vPfad -Recurse -Include "*.pdf"  

#Pattern für REGEX-Match vorbereiten
$pattern = ($result | %{[regex]::escape($_)}) -join "|"   

# Gefundene Dateien für Agenten bereitstellen
for($i=0; $i -lt $Adresse.Length; $i++) {
  $files | ?{$_.Basename -match $pattern} | Copy-Item -Destination $vArchivPfad | CMR_Mail $Adresse[$i] $body $files 
}

Danke euch wieder für konstruktive Hilfe!
Bitboy
Bitboy 16.01.2020 um 11:33:01 Uhr
Goto Top
Immer Stück für Stück an ein Problem rantasten.

Da heißt im ersten Schritt die Funktion mit "hardcoded" Parametern aufrufen.

CMR_Mail abc@abc "texttext" "C:\test.dat"

Funktioniert das, dann weißt du schonmal dass deine Funktion in Ordnung ist und musst dir Ansehen welche Parameter und wie von der Schleife übergeben werden.
Funktionierts nicht, musst in der Funktion schauen welcher Befehl nicht klappt und warum.

Ich finde am einfachsten geht das wenn man sich die problematischen Teile in die ISE kopiert und dort sozusagen live ausführt.
robdox
robdox 16.01.2020 um 12:31:27 Uhr
Goto Top
Gesagt getan face-smile bin nun einen Schritt weiter. Nun brauch ich Hilfe. Ich muss nun 2 arrays mit Schleifen durchlaufen, welche natürlich unterschiedlich lang sind. Sofern ein Index in $files zur Dateipasst, soll diese Datei an eine E-Mail geschickt werden. Ich überlege gerade Powershell zu sagen, wenn das -match stimmt, sende die E-Mail und fange wieder von vorn an. Nun werden natürlich die E-Mails doppelt verschickt.

Ergebnis IST:

CMR_Mail mail1@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\MAIL\SEND\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail2@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\MAIL\SEND\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail2@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\MAIL\SEND\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail1@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\MAIL\SEND\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail1@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail2@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail2@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail1@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf

Ergebnis SOLL:

CMR_Mail mail1@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\MAIL\SEND\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail2@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\MAIL\SEND\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail2@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\MAIL\SEND\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf
CMR_Mail mail1@mail.de Irgendein Text oder der Inhalt einer Variable C:\DB\MAIL\SEND\(LISTDOC3)RK1907086-001(RK)RK1907086.pdf

Codepart:

# Liste aller Dateien durchsuchen
[array]$files = Get-ChildItem -Path $vPfad -Recurse -Include "*.pdf"  

#Pattern für REGEX-Match vorbereiten
$pattern = ($result | %{[regex]::escape($_)}) -join "|"   

# Gefundene Dateien für Agenten bereitstellen

    for($x=0; $x -lt $files.Length; $x++)
    {
     for($i=0; $i -lt $Adresse.Length; $i++)
     {
        if($files[$x].Basename -match $pattern)
        {
          write-host CMR_Mail $Adresse[$i] $body $files[$x]
        } else { break; }
     } 
    }

Vielen Dank wieder vorab!
Bitboy
Lösung Bitboy 16.01.2020 um 13:15:15 Uhr
Goto Top
Offensichtlich liegt das ja daran, dass die Dateien in unterschiedlichen Ordnern vorhanden sind. Einmal in DB und in Send.
Get-ChildItem -Path $vPfad -Recurse -Include "*.pdf"
Wenn du Recursiv durchsuchst findest du natürlich alle PDF auch in unterrdnern.
robdox
robdox 16.01.2020 um 13:34:04 Uhr
Goto Top
Stimmt! So funktionierts! Vielen Dank!