Powershell Ordner dauerhaft überwachen und neue Dateien automatisch versenden
Hallo zusammen,
ich würde gerne einen Ordner überwachen lassen und sobald eine CSV-Datei dort abgelegt wird, soll diese automatisch per E-Mail versendet werden.
Soweit funktioniert es auch, aber wie bekomme ich es hin, dass der Ordner C:\test dauerhaft oder in xx Sekunden überwacht wird?
so schaut mein code bisher aus...
ich würde gerne einen Ordner überwachen lassen und sobald eine CSV-Datei dort abgelegt wird, soll diese automatisch per E-Mail versendet werden.
Soweit funktioniert es auch, aber wie bekomme ich es hin, dass der Ordner C:\test dauerhaft oder in xx Sekunden überwacht wird?
so schaut mein code bisher aus...
$SmtpUser = "xxx@xxx.de"
$smtpPassword = "xxxx"
$MailtTo = 'xyz@xxx.de'
$MailFrom = "xxx@xxx,de"
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)
#Variablen für Mail Subject, Body einrichten
$MailSubject = 'blabla'
$MailBody =
"<p>xxx,</p>
<p>im Anhang finden Sie die Dateien.</p>"
#Variablen für den Bericht der Angehängt werden soll deklarieren
$AttachmentDirectory = "C:\test"
#$FileType= "csv"
#Get-ChildItem -path $AttachmentDirectory -Recurse | Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject "$MailSubject" -Body "$MailBody" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials -Encoding ([System.Text.Encoding]::UTF8)
#$Files | Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject "$MailSubject" -Body "$MailBody" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials -Encoding ([System.Text.Encoding]::UTF8)
$Files = @(Get-ChildItem -path $AttachmentDirectory )
if ($Files.length -eq 0) {
write-host "nothing todo"
exit
} else {
Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject "$MailSubject" -Body "$MailBody" -SmtpServer $SmtpServer -BodyAsHtml -Attachments $Files.Fullname -UseSsl -Credential $Credentials -Encoding ([System.Text.Encoding]::UTF8);
Remove-item $Files.Fullname
}
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 12734652017
Url: https://administrator.de/forum/powershell-ordner-dauerhaft-ueberwachen-und-neue-dateien-automatisch-versenden-12734652017.html
Ausgedruckt am: 02.04.2025 um 03:04 Uhr
7 Kommentare
Neuester Kommentar
Hallo,
war schonmal Thema hier. Wenn du mal suchst....
Ansonsten ist das hier eine gute Anlaufstelle für Files und Events: https://powershell.one/tricks/filesystem/filesystemwatcher
mfg Crusher
war schonmal Thema hier. Wenn du mal suchst....
Ansonsten ist das hier eine gute Anlaufstelle für Files und Events: https://powershell.one/tricks/filesystem/filesystemwatcher
mfg Crusher
Moin,
einfach ein scheduled task erstellen der alle X Minuten / Sekunden läuft.
Ich empfehle dir zumindest irgendein Log zu erstellen das die gelöschten Dateien / fehlerhaften Mails (Try-Catch) protokolliert.
Falls da mal was schief läuft löscht er die Dateien immer. Bspw. wenn Internet mal weg ist.
Weiß zwar nicht wie groß deine Anhänge sind aber wenn die mal zu groß sind können die Mails nicht zugestellt werden*.
Ggfs. nochmal die Größe der Anhänge auswerten und ein Limit setzen, damit daraus mehrere Mails generiert werden*
VG
einfach ein scheduled task erstellen der alle X Minuten / Sekunden läuft.
Ich empfehle dir zumindest irgendein Log zu erstellen das die gelöschten Dateien / fehlerhaften Mails (Try-Catch) protokolliert.
Falls da mal was schief läuft löscht er die Dateien immer. Bspw. wenn Internet mal weg ist.
Weiß zwar nicht wie groß deine Anhänge sind aber wenn die mal zu groß sind können die Mails nicht zugestellt werden*.
Ggfs. nochmal die Größe der Anhänge auswerten und ein Limit setzen, damit daraus mehrere Mails generiert werden*
VG
Moin,
wie @Crusher79 schon ganz richtig schrieb, ist der FileSystemWatcher wahrscheinlich die eleganteste Lösung. Leider gibt es da einige Fallstricke zu beachten, wie z.B. der Fakt, dass es einige Zeit dauern kann, bis eine Datei fertig geschrieben ist.
"Send-MailMessage" solltest du wirklich nicht mehr verwenden:
Eine Alternative wäre z.B. https://github.com/jstedfast/MailKit
@Doskias: Das er das nicht tun sollte mag ja stimmen. Ohne dem TO eine Alternative vorzuschlagen ist dein Post allerdings sinnlos
wie @Crusher79 schon ganz richtig schrieb, ist der FileSystemWatcher wahrscheinlich die eleganteste Lösung. Leider gibt es da einige Fallstricke zu beachten, wie z.B. der Fakt, dass es einige Zeit dauern kann, bis eine Datei fertig geschrieben ist.
"Send-MailMessage" solltest du wirklich nicht mehr verwenden:
Warning
The Send-MailMessage cmdlet is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage.
The Send-MailMessage cmdlet is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage.
Eine Alternative wäre z.B. https://github.com/jstedfast/MailKit
@Doskias: Das er das nicht tun sollte mag ja stimmen. Ohne dem TO eine Alternative vorzuschlagen ist dein Post allerdings sinnlos
Generell ist E-Mail doch eher langsam.
Der erwähnte Watcher ist für Echtzeit Aufgaben nett. Wenn wir einfach unterstellen dass eine E-Mail eh etwas länger braucht und wir somit nicht binnen 1 Sekunde eine Antwort erwarten, so wäre der Taskplaner noch im rennen.
Damit sowas nicht doppelt und dreifeach läuft, wäre eine lck-file ggf. eine Hilfe. Ich blockiere damit in der Form, dass man die Function nicht aufrufen kann, wenn sie gerade am verabeiten ist.
Nur ein Vorschlag! Dass kannst du dann in 1 min. oder 5 min Tag im Taskplaner abfeuern. Man kann Timeoutes für den Mail-Versand und Error-Handling noch mit reinnehmen. Bei kürzen Intervallen verhindert die lck eine ungewolltes ausführen.
Alternativ wäre eine Schleife. Script bleibt 24 Std. im Hintergrund auf und vearbeitet die Dateien. Taskplaner + Lck-File ist aber auch sehr robust.
Verwaiste Lck-Dateien werden nach frühestens 10 min. automatisch gelöscht und es geht weiter ....
Der erwähnte Watcher ist für Echtzeit Aufgaben nett. Wenn wir einfach unterstellen dass eine E-Mail eh etwas länger braucht und wir somit nicht binnen 1 Sekunde eine Antwort erwarten, so wäre der Taskplaner noch im rennen.
Damit sowas nicht doppelt und dreifeach läuft, wäre eine lck-file ggf. eine Hilfe. Ich blockiere damit in der Form, dass man die Function nicht aufrufen kann, wenn sie gerade am verabeiten ist.
Nur ein Vorschlag! Dass kannst du dann in 1 min. oder 5 min Tag im Taskplaner abfeuern. Man kann Timeoutes für den Mail-Versand und Error-Handling noch mit reinnehmen. Bei kürzen Intervallen verhindert die lck eine ungewolltes ausführen.
Alternativ wäre eine Schleife. Script bleibt 24 Std. im Hintergrund auf und vearbeitet die Dateien. Taskplaner + Lck-File ist aber auch sehr robust.
Verwaiste Lck-Dateien werden nach frühestens 10 min. automatisch gelöscht und es geht weiter ....
[string]$lckFile = "C:\temp\csv2mail.lck"
Function MailCSV() {
$SmtpUser = "xxx@xxx.de"
$smtpPassword = "xxxx"
$MailtTo = 'xyz@xxx.de'
$MailFrom = "xxx@xxx,de"
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)
#Variablen für Mail Subject, Body einrichten
$MailSubject = 'blabla'
$MailBody =
"<p>xxx,</p>
<p>im Anhang finden Sie die Dateien.</p>"
#Variablen für den Bericht der Angehängt werden soll deklarieren
$AttachmentDirectory = "C:\test"
#$FileType= "csv"
#Get-ChildItem -path $AttachmentDirectory -Recurse | Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject "$MailSubject" -Body "$MailBody" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials -Encoding ([System.Text.Encoding]::UTF8)
#$Files | Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject "$MailSubject" -Body "$MailBody" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials -Encoding ([System.Text.Encoding]::UTF8)
$Files = @(Get-ChildItem -path $AttachmentDirectory )
if ($Files.length -eq 0) {
write-host "nothing todo"
exit
} else {
Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject "$MailSubject" -Body "$MailBody" -SmtpServer $SmtpServer -BodyAsHtml -Attachments $Files.Fullname -UseSsl -Credential $Credentials -Encoding ([System.Text.Encoding]::UTF8);
Remove-item $Files.Fullname
}
}
Function Script:WriteLog() {
Param ([string]$LogString)
$LogFile = "C:\temp\logs\$(gc env:computername).log"
$DateTime = "[{0:dd/MM/yyyy} {0:HH:mm:ss}]" -f (Get-Date)
$LogMessage = "$Datetime $LogString"
Add-content $LogFile -value $LogMessage
}
Function CreateLckFile() {
$null = New-Item -ItemType "file" -Path $lckFile;
# Fix NTFS Tunnellig
$(Get-Item -Force $lckFile).CreationTime = $(Get-Item -Force $lckFile).LastWriteTime;
}
Function LckTimeDiff() {
$lckFileCreationTime = $((Get-Item $lckFile).CreationTime)
$Diffobj = $(Get-Date) - $lckFileCreationTime
[int]$Script:DiffInMin = [int]$Diffobj.TotalMinutes
}
Function LckAndStart() {
if (! (Test-path -path $lckFile)) {
CreateLckFile
WriteLog "Lck Erstellt"
MailCSV
WriteLog "Versand abgeschlossen"
Remove-Item $lckFile -Force
} else {
LckTimeDiff
IF ($DiffInMin -gt 10 ) {
WriteLog "Alte Lck vorhanden"
Remove-Item $lckFile -Force
CreateLckFile
WriteLog "Lck neu erstellt"
MailCSV
WriteLog "Versand abgeschlossen"
Remove-Item $lckFile -Force
}
}
}
LckAndStart;
Zitat von @Kraemer:
@Doskias: Das er das nicht tun sollte mag ja stimmen. Ohne dem TO eine Alternative vorzuschlagen ist dein Post allerdings sinnlos
@Doskias: Das er das nicht tun sollte mag ja stimmen. Ohne dem TO eine Alternative vorzuschlagen ist dein Post allerdings sinnlos
Nein ist es nicht. und ich erkläre dir auch gerne wieso: Um eine wirkliche Alternative vorzuschlagen, kenne ich die Umgebung nicht. Da fängt es ja schon an ob der Mail-Server intern oder extern ist, wie sein Zugriff auf den Mailserver ist und was die Firmenrichtlinien vorschreiben. Und es steht doch schon da:
Das könnte schon die Lösung sein, aber dazu kenne ich die Umgebung zu wenig.
Was ich aber, unabhängig von der Umgebung, sagen kann, ist, dass ein Passwort in Klartext in kein Skript gehört. Das ist eine grundlegende Sache, die nur am Rande etwas mit dem Problem zu tun hat.
Gruß
Doskias