Электронная почта PowerShell с вводом текста

445
David Shortall

Я пытаюсь написать скрипт, который выбросит четыре поля ввода текста и сохранит введенные значения в четыре переменные, каждая из которых представляет имя пользователя, PIN-код телефона, PIN-код голосовой почты и добавочный номер телефона. После заполнения он отправляет электронное письмо, которое само использует переменные как заполнители, где каждое значение должно появляться.

Я скрыл и удалил часть кода для анонимности, однако надеюсь, что он по-прежнему читается логически.

Сценарий частично работает, но со странным недостатком, который я не могу определить.

При первоначальном выполнении сценарий выбрасывает 4 поля ввода текста и успешно выполняет запись-хост, отображая результат данных, введенных в поля ввода текста (например, fred.bloggs, 1000, 1000, 1000) - доказательство того, что пользователь данные сохраняются в переменные. Затем он отправляет электронное письмо, но ВСЕ поля переменных остаются пустыми, когда я получаю электронное письмо. (Я тестирую, вводя свое имя пользователя в поле ввода имени пользователя.)

Если я запускаю сценарий второй раз, сценарий выдает 4 поля, выполняет успешную запись-хост, показывая новые значения (например, fred.bloggs, 1001, 1001, 1001), сохраненные для каждой переменной, затем отправляет электронное письмо - но, письмо содержит значения, которые я ввел при первом запуске скрипта. (фред.блоги, 1000, 1000, 1000)

Поэтому я получаю пустые переменные в выводе электронной почты при первом запуске (например, если я закрываю Powershell_ISE и снова открываю). И я получаю предыдущие значения, введенные, если я запускаю его во второй раз. Кажется, что когда я запускаю скрипт, он всегда отправляет электронное письмо, используя значения предыдущей попытки.

Итак, это так:

Попытка 1: введено fred.bloggs, 1000, 1000, 1000 - Результат: все пусто в переменных полей электронной почты

Попытка 2: введено fred.bloggs, 1001, 1001, 1001 - Результат: поля переменных электронной почты, заполненные fred.bloggs, 1000, 1000, 1000

Попытка 3: введено fred.bloggs, 1002, 1002, 1002 - Результат: поля переменных электронной почты, заполненные fred.bloggs, 1001, 1001, 1001

Я подозреваю, что это связано с тем, как значения текстового поля ввода сохраняются в переменных, но я не могу найти ошибку.

Код как ниже. Буду очень признателен за любую помощь, так как я очень много учусь с нуля с Powershell.

$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 ответа на вопрос

4
postanote

Почему это 4 диалоговых окна против одного экземпляра GUI?

То, что вы делаете, действительно излишне для того, что вы после

Причина, по которой вы получаете предыдущие переменные данные в ISE, состоит в том, что вы не очистили их, прежде чем использовать их снова, они все еще находятся в памяти.

Заполненные переменные не очищаются автоматически. Таким образом, вы должны явно очистить их, а также выйти, закрыть сборщик мусора, собрать все вещи, которые вы создали, или перезапустить среду ISE / dev, которая, в любом случае, просто перебор.

Независимо от того, используете ли вы форму или нет, вы всегда должны очищать / удалять подобные вещи, прежде чем их можно будет использовать снова. Это может случиться с любым языком программирования, поэтому не для вещей, специфичных для PS или ISE.

Все это звучит так, будто вы новичок в разработке PS GUI или разработке приложений в целом. На YouTube есть много видео, посвященных созданию и использованию PS GUI с WPF и WinForms, а также множество статей по всему Интернету.

Вам даже не нужна индивидуальная форма, если вы не занимаетесь брендингом. Вы могли бы просто сделать это.

Используйте упрощенный графический интерфейс PS (с помощью командлета Show-Command) и введите информацию, которая при нажатии кнопки запуска отправляет ее в командлет Send-MailMessage в качестве функции. Единственные недостатки здесь, это функционально, не красиво, и вы не можете заказать параметры. Отсюда и мой фирменный знак выше.

Пример:

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 

Что касается того, чтобы сделать это в одной форме, используйте https://poshgui.com, перетащите конструктор форм, а затем просто присоедините свой код, чтобы заставить его действовать.

Что касается вашего кода, вы должны передать значение в текстовое поле, чтобы иметь возможность использовать его в событии нажатия кнопки.

Пример использования этого интерактивного графического дизайнера

<# 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

Я не знаю Powershell, но, думаю, переменные интерполируются в строку, когда она определена, а не используется.

Переместить $EmailBodyопределение вниз, ниже кода ввода данных.

Последующие запуски работают, но с устаревшими значениями, потому что переменные сохраняются между выполнениями оболочкой.

Большое спасибо - это была именно проблема. Это был очень ценный урок природы переменных и природы сценариев, выполняемых последовательно. Порядок, в котором размещены элементы, имеет важное значение. David Shortall 5 лет назад 0