Anleitung: E-Mail versenden mit Powershell
Hallo Administratoren und Freunde der Shell,
Voraussetzung ist ein SMTP-Server.
In der Shell mit dem Befehl Send-MailMessage -?, erhaltet Ihr wie gewohnt eine Hilfsübersicht. Hier ist der Auszug der Syntax:
Wichtig ist hier, dass im String für –To und –From ein @ vorkommt.
+++++ 3.2 Inhalt aus Logdatei
Im nächsten Schritt wird der Body, also der Inhalt der E-Mail so verändert, dass dieser als Inhalt den Inhalt einer Logdatei enthält.+++++ 3.3 Absender automatisch generieren
Die nächste Modifizierung ist es, dass der Absender automatisch an Hand des Computernamens festgelegt wird. Dazu wird eine Variable zum Auslesen des Computernamens erstellt.
+++++ 3.4 Batch
Und was ist mit Batch? Auch aus Batch heraus, kann eine E-Mail versandt werden. Warum wird die ExecutionPolicy mit angegeben? Die Standardeinstellung von Powershell erlaubt keine Ausführung von Skripten. Es muss also erst bestätigt bzw. erlaubt werden, ansonsten werdet Ihr eine Fehlermeldung erhalten. Falls die ExecutionPolicy bereits gesetzt wurden, kann dieser Befehl ignoriert werden.
3.4.1 Batch mit Variablen
Natürlich können auch Variablen an den Powershell Befehl übergeben werden. Mit dem folgenden Beispiel seht Ihr wie es gemacht wird:Wichtig hier bei sind die Anführungszeichen. Ihr müsst die Variablen in die Anführungszeichen schreiben, ansonsten führt es zu einer Fehlermeldung.
3.4.1 Batch: Inhalt aus Logdatei
Auch in Batch ist es möglich den Wert einer Logdatei an den Powershell Befehl zu übergeben. Und schon wird der Inhalt eurer Logdatei versendet.
Wie zu sehen ist, werden die Befehle nun in Variablen unterteilt und sie befinden sich in einer Funktion.
Einige werden sich jetzt fragen, wieso?
Wird das Skript durchlaufen und es trifft aus diesen Code, wird automatisch eine E-Mail verschickt. Dies wird durch die Funktion aufgehoben, denn eine Funktion in Powershell muss explizit aufgerufen werden, damit der Code der sich innerhalb der Funktion befindet ausgeführt wird.
Variablen- und Funktionsnamen können für jeweiligen Zwecke angepasst werden.
In der Zeileist zu sehen, dass der Variable des Textkörpers eine Funktion zugewiesen ist.
Der Code für die Generierung des HTML Textkörpers sieht wie folgt aus:In diesem sind HTML-Stylesheet Informationen verbaut. Des Weiteren wird der Inhalt der Logdatei in einer tabellarischen Form im Textkörper ausgegeben. Dieses Konzept kann man nun beliebig erweitern, um z.B. Reports, Farbmarkierungen etc.
Die Funktion aus dem Punkt 4. Als HTML muss anschließend um die folgenden Zeilen erweitert bzw. geändert werden. Dabei entfällt die Hilfsvariable $MailLog.Alle Einträge die mit ein Ereignis Debug, Warning oder Exception gekennzeichnet bzw. beinhalten, werden in der jeweiligen Farbe markiert. Die Farbinformation wird einfach als Stylesheet hinzugefügt.Die Stichwörter für die Ereignisse können auf Eure Wünsche angepasst werden.
Das bereits vorhandene Grundkonstrukt aus dem Punkt 4 Als HTML wird erweitert:Somit übergeben wir der Funktion die Variable $MailSubject, welche gleichzeitig unser Titel für den jeweiligen Zustand sein wird.Der Aufruf der Funktion GenerateMail wird durch die neue Funktion SendGeneratedWarningMail für den Zustand „Warnung“ ersetzt. Dies können wir jetzt beliebig wiederholen.Mit dieser Struktur werden viele Zeilen Code, als auch jede Menge doppelte Zeilen Code abgelöst.
Die Anleitung wird in den nächsten Tagen noch um die folgenden Punkte erweitert.
Gruß, Sascha
Inhaltsverzeichnis
1. Allgemeines
hier ist eine Anleitung zur Versendung von E-Mails via Powershell.Voraussetzung ist ein SMTP-Server.
2. Erläuterung des Cmdlet
Ausschlaggebend zum Versenden von E-Mails ist das Send-MailMessage Cmdlet, welches seit Version 2.0 zur Verfügung steht.In der Shell mit dem Befehl Send-MailMessage -?, erhaltet Ihr wie gewohnt eine Hilfsübersicht. Hier ist der Auszug der Syntax:
Send-MailMessage [-To] <string> [-Subject] <string> -From <string> [[-Body] <string>] [[-SmtpServer] <string>] [-Attachments <string[]>] [-Bcc <string[]>] [-BodyAsHtml] [-Cc <string[]>] [-Credential <PSCredential>] [-DeliveryNotificationOption {None | OnSuccess | OnFailure | Delay | Never}] [-Encoding <Encoding>] [-Priority {Normal | Low | High}] [-UseSsl] [<CommonParameters>]
3 Die Basis
Eine einfache E-Mail kann mit dem folgenden Befehl über die Shell versandt werden:Send-MailMessage –To "Empfänger@Adresse.de" –Subject "Test E-Mail" –Body "Dies ist meine erste E-Mail mit Powershell." –SmtpServer "ServerAdresse" –From "Absender@Powershell.de"
3.1 Erste Modifizierung
Darauf aufbauend können weitere Werte hinzugefügt werden, wie z.B. -Cc, -Bcc oder -PrioritySend-MailMessage –To "Empfänger@Adresse.de" –CC „Empfänger@Adresse.de“ –Subject "Test E-Mail" –Body "Dies ist meine erste E-Mail mit Powershell." –SmtpServer "ServerAdresse" –From "Absender@Powershell.de"
Im nächsten Schritt wird der Body, also der Inhalt der E-Mail so verändert, dass dieser als Inhalt den Inhalt einer Logdatei enthält.
$Logfile = “C:\meine_kleine.log”
Send-MailMessage –To "Empfänger@Adresse.de" –Subject "Test E-Mail" –Body (gc $Logfile | Out-String) –SmtpServer "ServerAdresse" –From "Absender@Powershell.de"
Die nächste Modifizierung ist es, dass der Absender automatisch an Hand des Computernamens festgelegt wird. Dazu wird eine Variable zum Auslesen des Computernamens erstellt.
$PC = gc env:computername
$Logfile = “C:\meine_kleine.log”
Send-MailMessage –To "Empfänger@Adresse.de" –Subject "Test E-Mail" –Body (gc $logfile | Out-String) –SmtpServer "ServerAdresse" –From "Absender@$PC"
Und was ist mit Batch? Auch aus Batch heraus, kann eine E-Mail versandt werden.
powershell -ExecutionPolicy Unrestricted -c "Send-MailMessage -To 'Empfänger@Adresse.de' -Subject 'Test E-Mail aus Batch' -Body ‘Meine erste E-Mail aus Batch mit Powershell.’ -SmtpServer 'ServerAdresse' -From 'Absender@Powershell.de'"
Natürlich können auch Variablen an den Powershell Befehl übergeben werden. Mit dem folgenden Beispiel seht Ihr wie es gemacht wird:
powershell -ExecutionPolicy Unrestricted -c "Send-MailMessage -To '%TO%' -Subject '%SUBJECT%' -Body ‘%BODY%’ -SmtpServer '%SMTP%' -From '%FROM%'"
Auch in Batch ist es möglich den Wert einer Logdatei an den Powershell Befehl zu übergeben.
powershell -ExecutionPolicy Unrestricted -c "Send-MailMessage -To '%TO%' -Subject '%SUBJECT%' -Body (gc ‘%LOGFILE%’ | Out-String) -SmtpServer '%SMTP%' -From '%FROM%'"
4 Als HTML
Ab hier wird der E-Mail Typ als HTML-Objekt versendet, somit ändert sich der gesamte Aufbau (dies ist für die weitere Verarbeitung notwendig).function GenerateMail {
$SmtpClient = New-Object System.Net.Mail.SmtpClient
$SmtpClient.host = 'ServerAdresse'
$PC = gc env:computername
$Mail = New-Object System.Net.Mail.MailMessage
$Mail.From = 'Absender@'+$PC
$Mail.To.Add('Empfänger@Adresse.de')
$Mail.IsBodyHtml = 1
$Mail.Subject = ‘Meine Erste HTML Mail’
$Mail.Body = GenerateHTMLBody
$SmtpClient.Send($Mail)
}
Einige werden sich jetzt fragen, wieso?
Wird das Skript durchlaufen und es trifft aus diesen Code, wird automatisch eine E-Mail verschickt. Dies wird durch die Funktion aufgehoben, denn eine Funktion in Powershell muss explizit aufgerufen werden, damit der Code der sich innerhalb der Funktion befindet ausgeführt wird.
Variablen- und Funktionsnamen können für jeweiligen Zwecke angepasst werden.
In der Zeile
$Mail.Body = GenerateHTMLBody
Der Code für die Generierung des HTML Textkörpers sieht wie folgt aus:
function GenerateHTMLBody {
$MailLog = gc $Logfile
Write-Output "
<html><head><title></title><style type=""text/css"">
table{margin-bottom:0px; margin-left:15px;}
.Borderless{border:none; font-family:Arial, Helvetica, sans-serif; font-size:12px; color:#666666; border-collapse:collapse;}
</style>
</head><body>
"
Foreach ($Log in $MailLog){
Write-Output "
<table>
<tr>
<td class="Borderless">$($Log)</td>
</tr>
</table>
</body></html>
"
}
4.1 HTML Erweiterung I: Farbmarkierungen
Wie oben als Beispiel bereits erwähnt ist eine Erweiterung dieses Grundkonstrukts nun beliebig erweiterbar. Die erste Erweiterung wird es sein, dass gewissen Ereignissen Farbinformationen zu gewiesen werden.function LogColor {
Param([Parameter(Position=0)]
[String]$LogEntry)
process {
IF ($LogEntry.Contains("Debug")) {Return '<p class="Debug">'}
ELSEIF ($LogEntry.Contains("Warning")) {Return '<p class="Warning">'}
ELSEIF ($LogEntry.Contains("Exception")) {Return '<p class="Exception">'}
ELSE {Return ''}
}
}
gc $Logfile | ForEach {Write-Output "<table><tr><td class="Borderless">"(LogColor $_</p>)$_"</tr></table>"}
P{font-family:Arial, Helvetica, sans-serif; font-size:12px; color:#666666; margin-top:0px; margin-bottom:0px;}
P.Exception{color:#DB0000; font-weight:bold;}
P.Warning{color:#ff9900; font-weight:bold;}
P.Debug{color:#000000; font-weight:bold;}
5. Code Optimierung
Zuallererst sollte versucht werden, den Code so lesbar, schlank und übersichtlich wie nur möglich zu halten. Was ist das gewünschte Ziel? Für Ereignisse mit unterschiedlichen Zuständen, wird die jeweilige Information per E-Mail versandt, um dies zu realisieren sind hier einige Beispiele.Das bereits vorhandene Grundkonstrukt aus dem Punkt 4 Als HTML wird erweitert:
function GenerateMail ($MailSubject){
$SmtpClient = New-Object System.Net.Mail.SmtpClient
$SmtpClient.host = 'ServerAdresse'
$PC = gc env:computername
$Mail = New-Object System.Net.Mail.MailMessage
$Mail.From = 'Absender@'+$PC
$Mail.To.Add('Empfänger@Adresse.de')
$Mail.IsBodyHtml = 1
$Mail.Subject = $MailSubject
$Mail.Body = GenerateHTMLBody
$SmtpClient.Send($Mail)
}
Function SendGeneratedWarningMail {
GenerateMail –MailSubject "Prozess XY hat eine Warnung auf $PC"
}
Function SendGeneratedSuccessMail {
GenerateMail –MailSubject "Prozess XY war Erfolgreich auf $PC"
}
Die Anleitung wird in den nächsten Tagen noch um die folgenden Punkte erweitert.
- Ereignis Logging
- Weitere Methoden
- mit/ohne Authentifizierung
- SSL / TLS
- Dateianhänge
Gruß, Sascha
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 275508
Url: https://administrator.de/contentid/275508
Ausgedruckt am: 05.11.2024 um 06:11 Uhr
6 Kommentare
Neuester Kommentar
Moin Sascha,
erstmal schöne Sache. Warum du aber das Konstrukt wegen HTML vollkommen änderst verstehe ich nicht, denn Send-MailMessage kennt ja den Parameter -BodyAsHTML
Die Funktionen würde ich dann etwas mehr generalisieren und mit Funktionsparametern versehen so das sie universeller weiterverwendbar sind. So wie hier z.B.
PowerShell 2.0 sendMail Skript
Auch wären ein paar Hinweise zur Authentifizierung und die Verwendung des Credential-Parameters noch eine sinnvolle Ergänzung. (New-Object PSCredential)
Gruß jodel32
erstmal schöne Sache. Warum du aber das Konstrukt wegen HTML vollkommen änderst verstehe ich nicht, denn Send-MailMessage kennt ja den Parameter -BodyAsHTML
Die Funktionen würde ich dann etwas mehr generalisieren und mit Funktionsparametern versehen so das sie universeller weiterverwendbar sind. So wie hier z.B.
PowerShell 2.0 sendMail Skript
Auch wären ein paar Hinweise zur Authentifizierung und die Verwendung des Credential-Parameters noch eine sinnvolle Ergänzung. (New-Object PSCredential)
Gruß jodel32
Guten Abend Sascha,
ich kann mich den Worten von @114757 nur anschließen. Sogar die Formatierungen wurden genutzt. Normalerweise muss der Author dazu überredet werden.
Was ich vermisse, ist der Versand über Authentifizierung und via TLS. Sollte beides heute Standard sein, bei neuen Implementierungen.
Gruß,
Dani
ich kann mich den Worten von @114757 nur anschließen. Sogar die Formatierungen wurden genutzt. Normalerweise muss der Author dazu überredet werden.
Was ich vermisse, ist der Versand über Authentifizierung und via TLS. Sollte beides heute Standard sein, bei neuen Implementierungen.
Gruß,
Dani