swissbull
Goto Top

PowerShell, Log Datei auslesen, bei Änderungen E-Mail senden

Hallo zusammen,

mein Vorhaben mit Power Shell…

Mit Robocopy, 2 Ordner vergleichen. Danach soll das Log File ausgelesen werden und bei Änderungen automatisch ein E-Mail versendet werden.

Was ich bi jetzt habe.
Robocopy funktioniert.
E-Mail versenden geht auch.

Wo ich noch Hilfe benötige ist wie mache ich das die Log File ausgelesen wird und nur bei Änderungen eine E-Mail versendet wird.


$SourceFolder = "C:\Test\Original"
$DestinationFolder = "C:\Test\Ziel"
$Logfile = "C:\Test\Ziel\log.txt"
$EmailFrom = "swissbull@xxxx.com"
$EmailTo = "swissbull@xxxx.com"
$EmailBody = "Starte Sicherung"
$EmailSubject = "Robocopy Results: Copy Purpose - Location to Location"
$SmtpServer = "smtp-xxx.com"
$SMTPPort = "25"

  1. Change robocopy options as needed.
Robocopy $SourceFolder $DestinationFolder /XO /FFT /E /COPY:DAT /R:5 /W:20 /LOG:$Logfile /NP /NDL /NJH

  1. Send E-mail message with log file attachment
$Message = New-Object Net.Mail.MailMessage($EmailFrom, $EmailTo, $EmailSubject, $EmailBody)
$Attachment = New-Object Net.Mail.Attachment($Logfile, 'text/plain')
$Message.Attachments.Add($Attachment)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, $SMTPPort)
$SMTPClient.Send($Message)

$datei = Get-Content C:\Test\Ziel\log.txt
$a = 0
$datei ¦ ForEach-Object { $a++; "Zeile" + $a + ": " + $_ }
"Gesamtzahl der Zeilen: " + $a

Content-Key: 317707

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

Ausgedruckt am: 19.03.2024 um 03:03 Uhr

Mitglied: askus-scriba
askus-scriba 13.10.2016 aktualisiert um 12:01:44 Uhr
Goto Top
Hallo swissbull,

ich kann dir zwar nicht so ganz folgen, was du unter einer "Änderung" des Logfiles verstehst, aber aus deinem geposteten Code meine ich zu erkennen, dass du als Grundlage die Anzahl der Zeilen des fraglichen Logfiles heranziehst.
Diese kannst du dir unter Powershell einfach folgendermaßen ausgeben lassen:

Get-Content <Dateiname> | Measure-Object -Line

Oder zielt deine Frage eher dahin ab wie du einen Mechanismus implementieren könntest, welcher am Ende dauerhaft die Größe des fraglichen Logfiles überwacht?
In diesem Fall wirf mal einen Blick in diesen Artikel hier.

Viele Grüße,
Thorsten
Mitglied: swissbull
swissbull 13.10.2016 aktualisiert um 12:49:56 Uhr
Goto Top
Der Log File vom Robocopy sieht so aus.


Insgesamt KopiertšbersprungenKeine šbereinstimmung FEHLER Extras
Verzeich.: 1 0 0 0 0 0
Dateien: 4 0 4 0 0 3
Bytes: 199 0 199 0 0 2.7 k
Zeiten: 0:00:00 0:00:00 0:00:00 0:00:00
Beendet: Mittwoch, 12. Oktober 2016 16:41:02


Bein Änderungen wird bei der Position 0 (Fett und unterstrichen) der wert verändert. Diese Wert muss ich auslesen, bei einen höheren Wert als 0 , muss eine E-Mail senden.
Mitglied: askus-scriba
askus-scriba 13.10.2016 aktualisiert um 13:32:00 Uhr
Goto Top
Hallo,

ausgehend davon, dass der von dir gepostete Ausschnitt der gesamte Inhalt des Logfiles ist, also die Zeile beginnend mit "Dateien:" nur einmal vorkommt, könnte dir so etwas weiterhelfen?

$a = Get-Content <Dateiname> | Select-String 'Dateien:' -SimpleMatch  
$a.ToString().Substring(11,1)

Dann ist das von dir unterstrichene Zeichen enthalten. Im folgenden könntest du dann überprüfen, ob dieses einen bestimmten Wert hat.

Viele Grüße,
Thorsten
Mitglied: swissbull
swissbull 13.10.2016 um 14:34:51 Uhr
Goto Top
Hi,

Super funktioniert. Fehlt nur noch eins. Er soll nur bei einem höheren Wert als 0, ein E-Mail versenden.


$SourceFolder = "C:\Test\Original"
$DestinationFolder = "C:\Test\Ziel"
$Logfile = "C:\Test\Ziel\log.txt"
$EmailFrom = "swissbull@xxxx.com"
$EmailTo = "swissbull@xxxx.com"
$EmailBody = "Starte Sicherung"
$EmailSubject = "Robocopy Results: Copy Purpose - Location to Location"
$SmtpServer = "smtp-xxx.com"
$SMTPPort = "25"

Change robocopy options as needed.

Robocopy $SourceFolder $DestinationFolder /XO /FFT /E /COPY:DAT /R:5 /W:20 /LOG:$Logfile /NP /NFL /NDL /NJH

Send E-mail message with log file attachment

$Message = New-Object Net.Mail.MailMessage($EmailFrom, $EmailTo, $EmailSubject, $EmailBody)
$Attachment = New-Object Net.Mail.Attachment($Logfile, 'text/plain')
$Message.Attachments.Add($Attachment)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, $SMTPPort)
$SMTPClient.Send($Message)

$a = Get-Content C:\Test\Ziel\log.txt | Select-String 'Dateien:' -SimpleMatch
$a.ToString().Substring(21,10)
Mitglied: 131026
131026 13.10.2016 aktualisiert um 14:42:46 Uhr
Goto Top
Ob Dateien kopiert/geändert werden lässt sich auch so ganz einfach mit einem Robocopy-Testlauf ermitteln:
(robocopy "C:\quelle" "C:\ziel" /S /ZB /L /NS /NC /NJH /NJS /NDL ).length -1  
Gruß R.
Mitglied: swissbull
swissbull 13.10.2016 um 14:56:53 Uhr
Goto Top
Hello,

Das bringt mich nicht weiter! Das Resultat von dem muss ausgewertet werden. Alles über ein höheren Wert über 0 muss ein E-Mail senden. Wie mache ich das??

$a = Get-Content C:\Test\Ziel\log.txt | Select-String 'Dateien:' -SimpleMatch
$a.ToString().Substring(21,10)
Mitglied: 131026
131026 13.10.2016 aktualisiert um 15:01:01 Uhr
Goto Top
Zitat von @swissbull:
Das bringt mich nicht weiter! Das Resultat von dem muss ausgewertet werden.
Wieso? , obige Zeile liefert die die Anzahl an Dateien die geändert/kopiert wurden

Alles über ein höheren Wert über 0 muss ein E-Mail senden. Wie mache ich das??
Meine Zeile einer Variablen zuweisen und dann per IF testen
$changes = (robocopy "C:\quelle" "C:\ziel" /S /ZB /L /NS /NC /NJH /NJS /NDL ).length -1  
if ($changes -gt 0){
   # mindestens eine Änderung
}else{
  # keine Änderung
}

IF, ELSE, SWITCH: Bedingte Anweisungen in PowerShell

Üble Grundlagen ...
Mitglied: askus-scriba
askus-scriba 13.10.2016 aktualisiert um 15:35:47 Uhr
Goto Top
Hallo,

Ranger hat in der Tat die einfachere Lösung beschrieben.
Um aber deine Frage zu beantworten:

$a = Get-Content C:\Test\Ziel\log.txt | Select-String 'Dateien:' -SimpleMatch  
if ($a.ToString().Substring(21,10) -gt 0)
{
# versende ein Mail
} 

Wobei dein angegebener Substring schon komisch ist - ich dachte es geht nur um die von dir im obigen Post unterstrichene Position? Also
$a.ToString().Substring(11,1)
?

Viele Grüße,
Thorsten
Mitglied: swissbull
swissbull 13.10.2016 um 15:29:06 Uhr
Goto Top
Geht nicht. Es werden E-Mails versendet, obwohl keine Veränderungen vorgenommen worden sind.


  1. Change robocopy options as needed.
$changes = (robocopy "C:\Test\Original" "C:\Test\Ziel" /S /ZB /L /NS /NC /NJH /NJS /NDL).length -1
if ($changes -gt 0){
$Message = New-Object Net.Mail.MailMessage($EmailFrom, $EmailTo, $EmailSubject, $EmailBody)
$Attachment = New-Object Net.Mail.Attachment($Logfile, 'text/plain')
$Message.Attachments.Add($Attachment)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, $SMTPPort)
$SMTPClient.Send($Message)
}else{
      1. keine Änderung
      }
Mitglied: swissbull
swissbull 13.10.2016 um 15:46:09 Uhr
Goto Top
Habe dies noch getestet, passiert gar nichts!

  1. Change robocopy options as needed.
Robocopy $SourceFolder $DestinationFolder /XO /FFT /E /COPY:DAT /R:5 /W:20 /LOG:$Logfile /NP /NFL /NDL /NJH

$a = Get-Content C:\Test\Ziel\log.txt | Select-String 'Dateien:' -SimpleMatch
if ($a.ToString().Substring(21,10) -gt 0)
{
  1. Send E-mail message with log file attachment
$Message = New-Object Net.Mail.MailMessage($EmailFrom, $EmailTo, $EmailSubject, $EmailBody)
$Attachment = New-Object Net.Mail.Attachment($Logfile, 'text/plain')
$Message.Attachments.Add($Attachment)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, $SMTPPort)
$SMTPClient.Send($Message)
}
Mitglied: askus-scriba
askus-scriba 13.10.2016 um 15:53:20 Uhr
Goto Top
Ich verstehe noch immer nicht, warum dein Substring (21,10) ist.
Oben hast du geschrieben, dass dich bei "Dateien: 4 0 4 0 0 3" nur die unterstrichene Position interessiert. Diese wäre jedoch Substring(11,1), der eben dann nur diese Position beachtet.
Bei deinem Substring(21,10) liest du ja zehn Zeichen aus. Das wird auch für Powershell schwierig zu überprüfen, ob eine zehnstellige Zeichenfolge größer als "0" ist. ;o)
Mitglied: swissbull
swissbull 13.10.2016 um 16:03:41 Uhr
Goto Top
Ich habe die Lösung. --> if ($a.ToString().Substring(21,10) -replace ' ','' -eq '0')

Das ist der gesamter Skript

$SourceFolder = "C:\Test\Original"
$DestinationFolder = "C:\Test\Ziel"
$Logfile = "C:\Test\Ziel\log.txt"
$EmailFrom = "swissbull@xxxx.com"
$EmailTo = "swissbull@xxxx.com"
$EmailBody = "Starte Sicherung"
$EmailSubject = "Robocopy Results: Copy Purpose - Location to Location"
$SmtpServer = "smtp-xxx.com"
$SMTPPort = "25"

  1. Change robocopy options as needed.
Robocopy $SourceFolder $DestinationFolder /XO /FFT /E /COPY:DAT /R:5 /W:20 /LOG:$Logfile /NP /NFL /NDL /NJH

$a = Get-Content C:\Test\Ziel\log.txt | Select-String 'Dateien:' -SimpleMatch
if ($a.ToString().Substring(21,10) -replace ' ','' -eq '0')
{
#echo "Keine Aenderung"
}
else
{
#echo "Änderung"
$Message = New-Object Net.Mail.MailMessage($EmailFrom, $EmailTo, $EmailSubject, $EmailBody)
$Attachment = New-Object Net.Mail.Attachment($Logfile, 'text/plain')
$Message.Attachments.Add($Attachment)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, $SMTPPort)
$SMTPClient.Send($Message)
}