PowerShell-E-Mail mit Texteingabe

653
David Shortall

Ich versuche, ein Skript zu schreiben, das vier Texteingabefelder aufwirft und ihre eingegebenen Werte in vier Variablen speichert, von denen jede Benutzername, Telefon-PIN, Voicemail-PIN und Telefonerweiterung darstellt. Sobald diese ausgefüllt sind, wird die E-Mail gesendet, die sie selbst verwendet Variablen als Platzhalter, bei denen jeder Wert angezeigt werden muss.

Ich habe einen Teil des Codes wegen der Anonymität verdunkelt und gelöscht, aber ich hoffe, er liest trotzdem logisch.

Das Skript funktioniert teilweise, aber mit einem bizarren Fehler, den ich nicht identifizieren kann.

Wenn zunächst ausgeführt, wirft das Skript die vier Texteingabefelder und hat erfolgreich einen Write-Host, das Ergebnis der in die Texteingabefelder (zB fred.bloggs, 1000, 1000, 1000) eingegebenen Daten anzeigt - Proving, dass der Benutzer -eingegebene Daten werden in den Variablen gespeichert. Es sendet dann die E-Mail, aber alle variablen Felder sind leer, wenn ich die E-Mail erhalte. (Ich teste, indem ich meinen eigenen Benutzernamen in das Eingabefeld Benutzername eingebe.)

Wenn ich das Skript ein zweites Mal starte, wirft das Skript die 4 Boxen hoch, führt einen erfolgreichen Schreibhost aus und zeigt die neuen Werte (z. B. fred.bloggs, 1001, 1001, 1001), die für jede Variable gespeichert sind, und sendet dann die E-Mail. Die E-Mail enthält die Werte, die ich beim ersten Ausführen des Skripts eingegeben habe . (fred.blogs, 1000, 1000, 1000)

Ich erhalte also leere Variablen in der E-Mail-Ausgabe, wenn ich sie das erste Mal starte (z. B. wenn ich Powershell_ISE schließe und wieder öffne). Ich bekomme die vorherigen Werte eingegeben, wenn ich es ein zweites Mal starte. Es scheint, als würde das Skript bei jeder Ausführung der E-Mail immer mit den Werten des vorherigen Versuchs gesendet.

So ist es so:

Versuch 1: Eingabe von fred.bloggs, 1000, 1000, 1000 - Ergebnis: In den Feldern der E-Mail-Variablen sind alle Felder leer

Versuch 2: Eingabe von fred.bloggs, 1001, 1001, 1001 - Ergebnis: E-Mail-Variablenfelder werden mit fred.bloggs, 1000, 1000, 1000 gefüllt

Versuch 3: Eingabe von fred.bloggs, 1002, 1002, 1002 - Ergebnis: E-Mail-Variablenfelder werden mit fred.bloggs, 1001, 1001, 1001 gefüllt

Ich vermute, es liegt an der Art, wie die Texteingabefeldwerte für die Variablen gespeichert werden, aber ich kann den Fehler nicht finden.

Code ist wie folgt. Jede Hilfe wäre sehr dankbar, da ich mit Powershell von Grund auf lerne.

$EmailFrom = "obscured@obscured.com" $EmailSubject = "Welcome to obscured + On-Boarding Details" $SMTPServer = "obscured" $SMTPPassword = Get-Content .\mailpw.txt | ConvertTo-SecureString $SMTPCred = New-Object System.Management.Automation.PSCredential "MailUser", $SMTPPassword $EmailBody = @"  Hi $StarterName,  Log in with obscured\$StarterName  Your Personalised details: Username: $StarterName<Br> Email: $StarterName@obscured.com<Br> Phone Extension: $PhoneExt (+obscured $PhoneExt) Dial 0 for external calls. <Br> Phone Username: $StarterName<Br> Phone PIN: $PhonePin <Br> Voicemail PIN: $VMPin <Br>  "@  #INPUT BOX: STARTER USER NAME  Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing  $form = New-Object System.Windows.Forms.Form $form.Text = 'Data Entry Form' $form.Size = New-Object System.Drawing.Size(300,200) $form.StartPosition = 'CenterScreen'  $OKButton = New-Object System.Windows.Forms.Button $OKButton.Location = New-Object System.Drawing.Point(75,120) $OKButton.Size = New-Object System.Drawing.Size(75,23) $OKButton.Text = 'OK' $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $OKButton $form.Controls.Add($OKButton)  $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = New-Object System.Drawing.Point(150,120) $CancelButton.Size = New-Object System.Drawing.Size(75,23) $CancelButton.Text = 'Cancel' $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.CancelButton = $CancelButton $form.Controls.Add($CancelButton)  $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,20) $label.Size = New-Object System.Drawing.Size(280,20) $label.Text = 'Enter Starter UserName:' $form.Controls.Add($label)  $textBox = New-Object System.Windows.Forms.TextBox $textBox.Location = New-Object System.Drawing.Point(10,40) $textBox.Size = New-Object System.Drawing.Size(260,20) $form.Controls.Add($textBox)  $form.Topmost = $true  $form.Add_Shown({$textBox.Select()}) $result = $form.ShowDialog()  if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $StarterName = $textBox.Text $StarterName }  #INPUT BOX: PHONE EXTENSION  $form = New-Object System.Windows.Forms.Form $form.Text = 'Data Entry Form' $form.Size = New-Object System.Drawing.Size(300,200) $form.StartPosition = 'CenterScreen'  $OKButton = New-Object System.Windows.Forms.Button $OKButton.Location = New-Object System.Drawing.Point(75,120) $OKButton.Size = New-Object System.Drawing.Size(75,23) $OKButton.Text = 'OK' $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $OKButton $form.Controls.Add($OKButton)  $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = New-Object System.Drawing.Point(150,120) $CancelButton.Size = New-Object System.Drawing.Size(75,23) $CancelButton.Text = 'Cancel' $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.CancelButton = $CancelButton $form.Controls.Add($CancelButton)  $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,20) $label.Size = New-Object System.Drawing.Size(280,20) $label.Text = 'Enter Starter Phone Extension' $form.Controls.Add($label)  $textBox = New-Object System.Windows.Forms.TextBox $textBox.Location = New-Object System.Drawing.Point(10,40) $textBox.Size = New-Object System.Drawing.Size(260,20) $form.Controls.Add($textBox)  $form.Topmost = $true  $form.Add_Shown({$textBox.Select()}) $result = $form.ShowDialog()  if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $PhoneExt = $textBox.Text $PhoneExt }  #INPUT BOX: PHONE PIN  $form = New-Object System.Windows.Forms.Form $form.Text = 'Data Entry Form' $form.Size = New-Object System.Drawing.Size(300,200) $form.StartPosition = 'CenterScreen'  $OKButton = New-Object System.Windows.Forms.Button $OKButton.Location = New-Object System.Drawing.Point(75,120) $OKButton.Size = New-Object System.Drawing.Size(75,23) $OKButton.Text = 'OK' $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $OKButton $form.Controls.Add($OKButton)  $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = New-Object System.Drawing.Point(150,120) $CancelButton.Size = New-Object System.Drawing.Size(75,23) $CancelButton.Text = 'Cancel' $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.CancelButton = $CancelButton $form.Controls.Add($CancelButton)  $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,20) $label.Size = New-Object System.Drawing.Size(280,20) $label.Text = 'Enter Starter Phone PIN:' $form.Controls.Add($label)  $textBox = New-Object System.Windows.Forms.TextBox $textBox.Location = New-Object System.Drawing.Point(10,40) $textBox.Size = New-Object System.Drawing.Size(260,20) $form.Controls.Add($textBox)  $form.Topmost = $true  $form.Add_Shown({$textBox.Select()}) $result = $form.ShowDialog()  if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $PhonePIN = $textBox.Text $PhonePIN }  #INPUT BOX: VM PIN  $form = New-Object System.Windows.Forms.Form $form.Text = 'Data Entry Form' $form.Size = New-Object System.Drawing.Size(300,200) $form.StartPosition = 'CenterScreen'  $OKButton = New-Object System.Windows.Forms.Button $OKButton.Location = New-Object System.Drawing.Point(75,120) $OKButton.Size = New-Object System.Drawing.Size(75,23) $OKButton.Text = 'OK' $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $OKButton $form.Controls.Add($OKButton)  $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = New-Object System.Drawing.Point(150,120) $CancelButton.Size = New-Object System.Drawing.Size(75,23) $CancelButton.Text = 'Cancel' $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.CancelButton = $CancelButton $form.Controls.Add($CancelButton)  $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,20) $label.Size = New-Object System.Drawing.Size(280,20) $label.Text = 'Enter Starter Voicemail PIN:' $form.Controls.Add($label)  $textBox = New-Object System.Windows.Forms.TextBox $textBox.Location = New-Object System.Drawing.Point(10,40) $textBox.Size = New-Object System.Drawing.Size(260,20) $form.Controls.Add($textBox)  $form.Topmost = $true  $form.Add_Shown({$textBox.Select()}) $result = $form.ShowDialog()  if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $VMPin = $textBox.Text $VMPin }   Write-Host "Sending email to $StarterName@obscured.com" -ForegroundColor Green Write-Host "PhoneExt: $PhoneExt" -ForegroundColor Green Write-Host "Phone PIN: $PhonePIN" -ForegroundColor Green Write-Host "Voicemail PIN: $VMPin" -ForegroundColor Green  Send-MailMessage -Credential $SMTPCred -To "$StarterName@obscured" -From  $EmailFrom -Subject $EmailSubject -SmtpServer $SMTPServer -Body $EmailBody -BodyAsHtml 
2

2 Antworten auf die Frage

4
postanote

Warum sind dies 4 Dialogfelder gegenüber einer einzelnen GUI-Instanz?

Was Sie tun, ist wirklich übertrieben für das, was Sie suchen

Der Grund, warum Sie die vorherigen variablen Daten in der ISE erhalten, ist, dass Sie sie nicht gelöscht haben, bevor Sie sie erneut verwendet haben. Sie befinden sich immer noch im Speicher.

Aufgefüllte Variablen werden nicht automatisch gelöscht. Sie müssen sie also explizit leeren sowie beenden, den Müll schließen, alles sammeln, was Sie instanziiert haben, oder die ISE / dev-Umgebung neu starten, was ohnehin nur eine Überarbeitung darstellt.

Unabhängig davon, ob Sie ein Formular verwenden oder nicht, sollten Sie solche Elemente immer löschen oder löschen, bevor sie wieder verwendet werden können. Dies kann bei jeder Programmiersprache passieren, also nicht bei einer PS-spezifischen Sache oder bei einer ISE-spezifischen Sache.

All dies hört sich an, als wären Sie neu in der PS-GUI-Entwicklung oder App-Entwicklung im Allgemeinen. Es gibt viele Videos auf YouTube, die die Erstellung von PS-GUI und deren Verwendung mit WPF und WinForms sowie zahlreiche Artikel im gesamten Web abdecken.

Sie brauchen nicht einmal ein benutzerdefiniertes Formular, es sei denn, Sie machen ein Branding. Sie könnten das einfach tun.

Verwenden Sie eine vereinfachte PS-GUI (mit dem Cmdlet Show-Command), und geben Sie die Informationen ein, die beim Klicken auf Ausführen an das Cmdlet Send-MailMessage als Funktion gesendet werden. Die einzigen Nachteile hier sind, es ist funktional, nicht hübsch, und Sie können die Parameter nicht bestellen. Daher mein Branding-Punkt oben.

Beispiel:

function New-UserOnboardingEmail { param ( [Parameter(Mandatory)] [string]$Username,  [Parameter(Mandatory)] [string]$PhonePin,  [Parameter(Mandatory)] [string]$VoicemailPin,  [Parameter(Mandatory)] [string]$PhoneExt )   $UserOnBoardDetails = " UserName : $Username`n PhonePin : $PhonePin`n VoiceMail : $VoicemailPin`n PhoneExt : $PhoneExt"  Send-MailMessage ` -From "$Admin@domain.com" ` -To "$Username@domain.com" ` -Subject 'Welcome to obscured + On-Boarding Details' ` -Body: $UserOnBoardDetails ` -SmtpServer $SmtpServer ` -Encoding UTF8 ` -Credential $Creds }  Show-Command -Name New-UserOnboardingEmail 

Um dies in einem Formular zu tun, verwenden Sie https://poshgui.com, ziehen Sie den Formulardesigner und fügen Sie ihn anschließend dem Code hinzu.

Für Ihren Code müssen Sie den Wert des Textfeldeintrags übergeben, um diesen für ein Klickereignis verwenden zu können.

Beispiel mit diesem Online-GUI-Designer

<# This form was created using POSHGUI.com a free online gui designer for PowerShell .NAME Untitled #>  Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.Application]::EnableVisualStyles()  #region begin GUI{   $frmUserOnBoarding = New-Object system.Windows.Forms.Form $frmUserOnBoarding.ClientSize = '400,400' $frmUserOnBoarding.text = "New User On-boarding " $frmUserOnBoarding.TopMost = $false  $lblUserName = New-Object system.Windows.Forms.Label $lblUserName.text = "UserName" $lblUserName.AutoSize = $true $lblUserName.width = 25 $lblUserName.height = 10 $lblUserName.location = New-Object System.Drawing.Point(17,22) $lblUserName.Font = 'Microsoft Sans Serif,10'  $txtUserName = New-Object system.Windows.Forms.TextBox $txtUserName.multiline = $false $txtUserName.width = 100 $txtUserName.height = 20 $txtUserName.location = New-Object System.Drawing.Point(157,17) $txtUserName.Font = 'Microsoft Sans Serif,10'  $lblPhonePin = New-Object system.Windows.Forms.Label $lblPhonePin.text = "PhonePin" $lblPhonePin.AutoSize = $true $lblPhonePin.width = 25 $lblPhonePin.height = 10 $lblPhonePin.location = New-Object System.Drawing.Point(17,60) $lblPhonePin.Font = 'Microsoft Sans Serif,10'  $txtPhonePin = New-Object system.Windows.Forms.TextBox $txtPhonePin.multiline = $false $txtPhonePin.width = 100 $txtPhonePin.height = 20 $txtPhonePin.location = New-Object System.Drawing.Point(156,51) $txtPhonePin.Font = 'Microsoft Sans Serif,10'  $lblVoicemailPin = New-Object system.Windows.Forms.Label $lblVoicemailPin.text = "VoiceMailPin" $lblVoicemailPin.AutoSize = $true $lblVoicemailPin.width = 25 $lblVoicemailPin.height = 10 $lblVoicemailPin.location = New-Object System.Drawing.Point(18,94) $lblVoicemailPin.Font = 'Microsoft Sans Serif,10'  $txtVoicemailPin = New-Object system.Windows.Forms.TextBox $txtVoicemailPin.multiline = $false $txtVoicemailPin.width = 100 $txtVoicemailPin.height = 20 $txtVoicemailPin.location = New-Object System.Drawing.Point(157,88) $txtVoicemailPin.Font = 'Microsoft Sans Serif,10'  $lblPhoneExt = New-Object system.Windows.Forms.Label $lblPhoneExt.text = "PhoneExt" $lblPhoneExt.AutoSize = $true $lblPhoneExt.width = 25 $lblPhoneExt.height = 10 $lblPhoneExt.location = New-Object System.Drawing.Point(20,126) $lblPhoneExt.Font = 'Microsoft Sans Serif,10'  $txtPhoneExt = New-Object system.Windows.Forms.TextBox $txtPhoneExt.multiline = $false $txtPhoneExt.width = 100 $txtPhoneExt.height = 20 $txtPhoneExt.location = New-Object System.Drawing.Point(154,124) $txtPhoneExt.Font = 'Microsoft Sans Serif,10'  $btnSubmit = New-Object system.Windows.Forms.Button $btnSubmit.text = "Submit" $btnSubmit.width = 60 $btnSubmit.height = 30 $btnSubmit.location = New-Object System.Drawing.Point(16,168) $btnSubmit.Font = 'Microsoft Sans Serif,10'  $btnCancel = New-Object system.Windows.Forms.Button $btnCancel.text = "Cancel" $btnCancel.width = 60 $btnCancel.height = 30 $btnCancel.location = New-Object System.Drawing.Point(87,167) $btnCancel.Font = 'Microsoft Sans Serif,10'  $frmUserOnBoarding.controls.AddRange(@($lblUserName,$txtUserName,$lblPhonePin,$txtPhonePin,$lblVoicemailPin,$txtVoicemailPin,$lblPhoneExt,$txtPhoneExt,$btnSubmit,$btnCancel))  #region gui events { $btnSubmit.Add_Click({  $UserName = $txtUserName.Text $PhonePin = $txtPhonePin.Text $VoicemailPin = $txtVoicemailPin.Text $PhoneExt = $txtPhoneExt.Text  $frmUserOnBoarding.Close()}) #endregion events }  #endregion GUI }   #Write your logic code here  [void]$frmUserOnBoarding.ShowDialog()   # Results from the submit button on the form $UserName $PhonePin $VoicemailPin $PhoneExt 
1
gronostaj

Ich kenne Powershell nicht, aber ich denke, dass Variablen in String interpoliert werden, wenn sie definiert sind und nicht verwendet werden.

Verschieben Sie die $EmailBodyDefinition nach unten unter den Dateneingabecode

Nachfolgende Läufe funktionieren, jedoch mit veralteten Werten, da Variablen zwischen den Ausführungen der Shell erhalten bleiben.

Vielen Dank - Dies war genau das Problem. Dies war eine sehr wertvolle Lektion in Bezug auf die Art der Variablen und die Art der nacheinander auszuführenden Skripts. Die Reihenfolge, in der die Elemente platziert werden, ist wesentlich. David Shortall vor 5 Jahren 0