我正在尝试编写一个脚本,它将抛出四个文本输入框并将其输入的值保存到四个变量中,每个变量代表用户名、电话 PIN、语音邮件 PIN 和电话分机号 - 一旦填充,它就会发送电子邮件,电子邮件本身使用上述变量作为每个值必须出现的占位符。
为了匿名,我隐藏并删除了部分代码,但我希望它仍然符合逻辑。
该脚本部分可以运行,但是有一个我无法识别的奇怪缺陷。
什么时候最初执行后,脚本会抛出 4 个文本输入框并成功执行 Write-Host,显示输入到文本输入框的数据的结果(例如 fred.bloggs、1000、1000、1000)——证明用户输入的数据已保存到变量中。然后它会发送电子邮件,但当我收到电子邮件时,所有变量字段都是空白的。(我通过将自己的用户名放入用户名输入框来进行测试。)
如果我运行脚本第二脚本抛出了 4 个框,并显示成功的写入主机新的值(例如 fred.bloggs,1001, 1001, 1001)保存在每个变量上,然后发送电子邮件 - 但是,电子邮件包含我在输入时输入的值第一的运行脚本。(fred.blogs,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 = "[email protected]"
$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: [email protected]<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 [email protected]" -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
答案1
我不知道 Powershell,但我猜测变量是在定义时插入到字符串中的,而不是使用时。
$EmailBody
将定义向下移动到数据输入代码下方。
后续运行仍然有效,但值已经过时,因为变量在 shell 执行之间保持不变。
答案2
为什么这是 4 个对话框而不是单个 GUI 实例?
你所做的确实比你想要的要多得多
您在 ISE 中获取先前变量数据的原因是,您在再次使用它们之前没有清除它们,它们仍然在内存中。
填充的变量不会自动清除。因此,您必须明确清空它们并退出,关闭垃圾收集并实例化任何内容,或者重新启动 ISE/dev 环境,这无论如何都是重做所有事情。
无论您是否使用表单,您都应该始终清理/清除删除内容,然后才能再次使用。任何编程语言都可能发生这种情况,因此不是 PS 或 ISE 特有的事情。
所有这些听起来都像是你对 PS GUI 开发或应用程序开发一无所知。YouTube 上有很多视频介绍了 PS GUI 的创建以及使用 WPF 和 WinForms 的使用,网络上也有很多文章。
您甚至不需要定制表格,除非您要进行品牌推广。您可以这样做。
使用简单的 PS GUI(使用 Show-Command cmdlet)并输入信息,当您单击运行时,该信息会作为函数发送到 Send-MailMessage cmdlet。这里唯一的缺点是,它功能齐全,但不够美观,并且您无法对参数进行排序。因此,我在上面提到了品牌点。
例子:
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 "[email protected]" `
-To "[email protected]" `
-Subject 'Welcome to obscured + On-Boarding Details' `
-Body: $UserOnBoardDetails `
-SmtpServer $SmtpServer `
-Encoding UTF8 `
-Credential $Creds
}
Show-Command -Name New-UserOnboardingEmail
至于以一种形式执行此操作,使用https://poshgui.com,拖放表单设计器然后只需附加您的代码即可使其采取行动。
至于您的代码,您必须传递文本框条目的值才能在按钮单击事件中使用它。
使用在线 GUI 设计器的示例
<# 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