tranministrator
Goto Top

PowerShell 2.0 sendMail Skript

Hallo liebe Admins,

ich kämpfe momentan(schon etwas länger) mit automatisiertem Mailversand. PowerShell 4 ist kein Problem, das läuft. Hier das Skript:

PowerShell 4 Skript:

#in Powershell eingeben: (Get-Credential).password | ConvertFrom-SecureString > V:\SVEN\BATCH\Mail\Statistik\password_statistik.txt

$SMTPServer = "webmail.test4test.com"  
$pw = Get-Content X:\BATCH\MAIL\Statistik\Password_statistik.txt | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PSCredential "statistik@test4test.com", $pw  
$From = "statistik@test4test.com"  
$To = '''  
$Cc = ''  
$Subject = ""  
$Body = @"  


"@  


# Optional Get-ChildItem -Recurse -Filter *.log
Get-ChildItem “X:\statexport\VILE\VILE.pdf” `
| Where {-NOT $_.PSIsContainer} `
| foreach {$_.fullname} `
|Send-MailMessage -To $To -Cc $Cc -From $From -Subject $Subject -Body $Body -SmtpServer $SMTPServer -Credential $cred -encoding ([System.Text.Encoding]::UTF8) 

Hier mein PowerShell 2 Skript

$SMTPServer = "webmail.test.at"  
$username = "statistik@test4test.com"  


$From = "statistik@test4test.com"  
$To = 'test@test4test.com'  
$Subject = "Test 11:11"  
$Body = @"  
Testnachricht
"@  

$secure2 = get-content V:\passwort.txt | convertto-securestring -key (1..16) 
$creds = New-Object System.Management.Automation.PSCredential ($username, $secure2) 

Get-ChildItem “V:\Test\*.txt” `
| Where {-NOT $_.PSIsContainer} `
| foreach {$_.fullname} `
|Send-MailMessage -To $To -From $From -Subject $Subject -Body $Body -SmtpServer $SMTPServer -Credential $creds -encoding ([System.Text.Encoding]::UTF8) 

Die Antwort vom Server wenn ich das 2.0 Skript ausführe ist dann folgende:

"Falsche Befehlsfolge. Die Serverantwort war: This mail
server requires authentication when attempting to send to a non-local
e-mail address. Please check your mail client settings or contact your
administrator to verify that the domain or address is defined for this
server."

Habt ihr eine Idee was das Problem sein kann? Ich vermute nach etwas Recherche etwas mit dem Passwort wie es an den SMTP weiter gegeben wird.

Viele Grüße

Robert

Content-Key: 248938

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

Printed on: April 19, 2024 at 01:04 o'clock

Member: colinardo
colinardo Sep 11, 2014 updated at 14:42:26 (UTC)
Goto Top
Hallo Robert,
ich vermute das System auf dem das 2.0 Script läuft hat keine Relay-Rechte auf dem Mailserver, oder du hast das Passwort-File mit einem anderen Useraccount, als dem der das Script jetzt ausführt, erzeugt; denn dann stimmt das Password nämlich nicht mehr.

Grüße Uwe
Member: Tranministrator
Tranministrator Sep 11, 2014 updated at 14:55:53 (UTC)
Goto Top
Hallo Uwe,

ein Gegentest mit Blat.exe war positiv. Versand war positiv.

Also kann es eigentlich am Mailserver nicht liegen denn die PowerShell 4.0 Variante geht ja ohne Probleme (momentan nicht da ich zu oft falsch gesendet habe via 2.0)

Ich werde es mal mit einem Klartext Versuch starten.

Sorry aber ich bin totaler Laie was das ganze Troubleshooting bzgl. SMTP angeht.

Die Grundbegriffe gehen, aber verstehen tue ich überhaupt nicht warum die Relay Rechte PowerShell versionsabhängig sind.

Das Passwort-File habe ich auf dem Rechner erzeugt, das sollte passen.

Update: der SMTP Server geht mit PowerShell 4.0 wieder face-smile

Viele Grüße

Robert
Member: colinardo
colinardo Sep 11, 2014 updated at 17:50:36 (UTC)
Goto Top
Das Passwort-File habe ich auf dem Rechner erzeugt, das sollte passen.
auch mit dem selben Useraccount ?

versuche mal diese Funktion:
Function sendmail($FROM,$TO,$SUBJECT,$BODY,$ATTACHMENTS = $null){
  $SMTPHOST = "smtp.server.de"  
  $SMTPPORT = 25
  $SMTPUSER = "USERNAME"  
  $SMTPPass = "PASSWORD"  
  $SMTPClient = New-object System.Net.Mail.SmtpClient($SMTPHOST,$SMTPPORT)
  $SMTPClient.EnableSsl = $true
  $Mail = new-object System.Net.Mail.MailMessage
  $Mail.from = $FROM 
  $Mail.to.add($TO)
  $SMTPClient.Credentials = new-object System.Net.NetworkCredential($SMTPUSER,$SMTPPass)
  $Mail.Subject = $SUBJECT
  $Mail.Body = $BODY
  # Add Attachments
  if ($ATTACHMENTS){
      foreach ($att in $ATTACHMENTS){
        $Mail.Attachments.Add($att)
      }
  }
  $SMTPClient.Send($Mail)
}

sendmail "absender@domain.com" "empfaenger@domain.com" "DEIN BETREFF" "DER INHALT"  
Member: Tranministrator
Tranministrator Sep 11, 2014 at 15:21:36 (UTC)
Goto Top
Ja auf dem PC gab es nur einen User Account.

Das Skript werde ich gleich im Anschluss testen. Feedback gibt es noch heute face-smile

Viele Grüße

Robert
Member: Tranministrator
Tranministrator Sep 11, 2014 at 15:42:49 (UTC)
Goto Top
Hey Uwe,

bei deinem Skript kommt die Nachricht problemlos an und der SMTP Server zickt auch nicht rum face-smile

Hier noch die genaue Fehlermeldung des SMTP Servers:

Send-MailMessage : Falsche Befehlsfolge. Die Serverantwort war: This mail server requires authentication when attempting to send to a n
on-local e-mail address. Please check your mail client settings or contact your administrator to verify that the domain or address is d
efined for this server.
Bei X:\sven\Batch\Mail\edi_ueberwachung_XXX.ps1:44 Zeichen:18
+ |Send-MailMessage <<<<  -To $To -From $From -Cc $CC -BCc $BCC -Subject $Subject -Body $Body -SmtpServer $SMTPServer -Credential $cred
s -encoding ([System.Text.Encoding]::UTF8) 
    + CategoryInfo          : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpException
    + FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage

Hast du noch Ideen?

Kann man in dein Beispiel die Verschlüsselung des Kennwortes integrieren?

Viele Grüße

Robert
Member: colinardo
colinardo Sep 11, 2014 updated at 15:48:33 (UTC)
Goto Top
Zitat von @Tranministrator:
Kann man in dein Beispiel die Verschlüsselung des Kennwortes integrieren?
ja, du könntest einfach deinen Secure-String zurück in Klartext wandeln:, und als Passwort verwenden.
das geht so:
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR((ConvertTo-SecureString -String $deinSecureText)))
Member: Tranministrator
Tranministrator Sep 11, 2014 at 16:36:50 (UTC)
Goto Top
Hmmm das ist wie die Nadel im Heuhaufen face-wink

Sagen wir mal ich integriere es und füge deine 2 Skripte zusammen:

Function sendmail($FROM,$TO,$SUBJECT,$BODY,$ATTACHMENTS = $null){
  $SMTPHOST = "webmail.xxx.at"  
  $SMTPPORT = 25
  $SMTPUSER = "edi@xxx.com"  
  # $SMTPPass = ""  
  
$SMTPClient = New-object System.Net.Mail.SmtpClient($SMTPHOST,$SMTPPORT)
  $SMTPClient.EnableSsl = $false
  $Mail = new-object System.Net.Mail.MailMessage
  $Mail.from = $FROM 
  $Mail.to.add($TO)

[System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR((ConvertTo-SecureString -String $deinSecureText)))


  $SMTPClient.Credentials = new-object System.Net.NetworkCredential($SMTPUSER,$deinSecureText))
  $Mail.Subject = $SUBJECT
  $Mail.Body = $BODY
  # Add Attachments
  if ($ATTACHMENTS){
      foreach ($att in $ATTACHMENTS){
        $Mail.Attachments.Add($att.FullName)
      }
  }
  $SMTPClient.Send($Mail)
}

sendmail "edi@xxx.com" "xxx@hotmail.com" "test" "DER INHALT"  

Woher bekomme ich den SecureString als Pfad? Wo stelle ich das ein? Passt sonst alles andere?

Viele Grüße

Robert
Member: colinardo
colinardo Sep 11, 2014 updated at 17:46:05 (UTC)
Goto Top
sorry das vorherige hatte ich gelöscht, gab's leider nur unter neueren .NET Versionen...

Function sendmail($FROM,$TO,$SUBJECT,$BODY,$ATTACHMENTS = $null){
  $SMTPHOST = "webmail.xxx.at"  
  $SMTPPORT = 25
  $SMTPUSER = "edi@xxx.com"  
  
  $SMTPClient = New-object System.Net.Mail.SmtpClient($SMTPHOST,$SMTPPORT)
  $SMTPClient.EnableSsl = $false
  $Mail = new-object System.Net.Mail.MailMessage
  $Mail.from = $FROM 
  $Mail.to.add($TO)

  # SecureString erstellen
  $SECURE= get-content "V:\passwort.txt" | convertto-securestring -key (1..16)  
  # Klartextpassword extrahieren
  $SMTPPASS = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SECURE)) 

  $SMTPClient.Credentials = new-object System.Net.NetworkCredential($SMTPUSER,$SMTPPASS)
  $Mail.Subject = $SUBJECT
  $Mail.Body = $BODY
  # Add Attachments
  if ($ATTACHMENTS){
      foreach ($att in $ATTACHMENTS){
        $Mail.Attachments.Add($att)
      }
  }
  $SMTPClient.Send($Mail)
}

sendmail "edi@xxx.com" "xxx@hotmail.com" "test" "DER INHALT"  
Grüße Uwe
Member: Tranministrator
Tranministrator Sep 11, 2014 at 17:06:14 (UTC)
Goto Top
Hey Uwe,

hab es jetzt getestet, leider noch immer eine Meldung, deutet darauf hin dass ich entweder ein Murks rein gemacht habe oder dass da etwas im Design nicht stimmt.

Function sendmail($FROM,$TO,$SUBJECT,$BODY,$ATTACHMENTS = $null){
  $SMTPHOST = "mail.gmx.net"  
  $SMTPPORT = "587"  
  $SMTPUSER = "Nummer"  
  $SMTPClient = New-object System.Net.Mail.SmtpClient($SMTPHOST,$SMTPPORT)
  $SMTPClient.EnableSsl = $true
  $Mail = new-object System.Net.Mail.MailMessage
  $Mail.from = $FROM 
  $Mail.to.add($TO)
  $SMTPSECUREPASS = get-content "V:\XXX\Batch\Mail\passwort_gmx.txt" | convertto-securestring -key (1..16)  
  $SMTPClient.Credentials = new-object System.Net.NetworkCredential($SMTPUSER,$SMTPSECUREPASS) 
  $Mail.Subject = $SUBJECT
  $Mail.Body = $BODY
  # Add Attachments
  if ($ATTACHMENTS){
      foreach ($att in $ATTACHMENTS){
        $Mail.Attachments.Add($att.FullName)
      }
  }
  $SMTPClient.Send($Mail)
}

sendmail "XXX@gmx.at" "XXX@hotmail.com" "test" "DER INHALT"  



Passwort wurde so erzeugt:

$secure = read-host -assecurestring 

$encrypted = convertfrom-securestring -secureString $secure -key (1..16) 

#Pfad zur Passwort Datei
$encrypted | set-content V:\XXX\Batch\Mail\passwort_gmx.txt


Fehlermeldung:

PS V:\XXX\Batch\Mail> V:\XXX\Batch\Mail\neu_ps2.ps1
Ausnahme beim Aufrufen von "Send" mit 1 Argument(en):  "Für den SMTP-Server ist eine sichere Verbindung erforderlich, oder der Client w  
urde nicht authentifiziert. Die Serverantwort war: Authentication required"  
Bei V:\XXX\Batch\Mail\neu_ps2.ps1:20 Zeichen:19
+   $SMTPClient.Send <<<< ($Mail)
    + CategoryInfo          : NotSpecified: (:) , MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
 

____________________________________________________________________________________________________________________________________

Hast du noch eine Idee? Das ist mal jetzt ein GMX Account den ich ausgegraben habe um den anderen SMTP zu entlasten face-wink


Viele Grüße

Robert
Member: Tranministrator
Tranministrator Sep 11, 2014 at 17:31:31 (UTC)
Goto Top
Hey Uwe,

eine Glanzleistung, läuft Bombe face-smile

Jetzt fehlen nur mehr die Anhänge, BCC + CC habe ich gerade positiv getestet.

Hast du ein Tipp für mich wo die Pfade eingetragen werden?

Viele Grüße

Robert
Member: colinardo
colinardo Sep 11, 2014 updated at 17:47:34 (UTC)
Goto Top
Du kannst die Anhänge einfach als String-Array hinter das Body Argument anhängen. Das hatte ich ja schon mit eingebaut.
sendmail "XXX@gmx.at" "XXX@hotmail.com" "test" "DER INHALT" @("c:\doc1.xlsx","c:\doc2.xlsx")  
Grüße Uwe

Äh Moment dann noch die Zeile 23 so ändern (Ich hatte die Funktion damals für was anderes verwendet sorry)
$Mail.Attachments.Add($att) 
Member: Tranministrator
Tranministrator Sep 11, 2014 at 17:49:52 (UTC)
Goto Top
Genau das habe ich auch gemacht.


Habe es mal so:

($FROM,$TO,$SUBJECT,$BODY,$ATTACHMENTS = $null)

@("V:\test\test.txt")  

Und so probiert:

($FROM,$TO,$SUBJECT,$BODY,$ATTACHMENTS )

@("V:\test\test.txt")  
Fehlermeldung war immer diese:

Ausnahme beim Aufrufen von "Add" mit 1 Argument(en):  "Der Wert darf nicht NULL sein.  
Parametername: item"  
Bei V:\sven\Batch\Mail\neu_ps2_work.ps1:22 Zeichen:30
+         $Mail.Attachments.Add <<<< ($att.FullName)
    + CategoryInfo          : NotSpecified: (:) , MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
 

Als Array meinst du auch sicher *.* oder *.txt oder?

Viele Grüße

Robert
Member: Tranministrator
Tranministrator Sep 11, 2014 at 17:52:54 (UTC)
Goto Top
Hey Uwe,

passt gut, jetzt kann man mehrere Dateinamen angeben.

Gibt es da auch etwas einfaches für *.* oder *.log Dateien? Also alle Dateien eines Ordners?

Viele Grüße

Robert
Member: colinardo
Solution colinardo Sep 11, 2014 updated at 18:05:01 (UTC)
Goto Top
Zitat von @Tranministrator:

Gibt es da auch etwas einfaches für *.* oder *.log Dateien? Also alle Dateien eines Ordners?

Hättest du auch gleich sagen können, dann hätten wir es so lassen können face-wink
Und zwar änderst du dann Zeile 23 wieder so ab
$Mail.Attachments.Add($att.FullName)
Dann erstellst du dir ein Objekt mit den Files (aber bitte außerhalb der Funktion face-wink)
$files = dir "c:\temp\*.log"  
Welches du dann an den Funktionsaufruf als Parameter übergibst
sendmail "XXX@gmx.at" "XXX@hotmail.com" "test" "DER INHALT" $files  

Sorry ich schreibe auf dem Tablet da geht es etwas länger ...

Die Funktion ist schon etwas älter und nicht mehr auf dem aktuellen Stand , sonst hätte ich das schon alles optimiert, ..

Schönen Abend noch
Uwe
Member: Tranministrator
Tranministrator Sep 11, 2014 at 18:08:51 (UTC)
Goto Top
Hey Uwe,


vielen Dank für deinen Einsatz! Bist spitze face-smile

Viele Grüße und ebenso einen schönen Abend!

Robert