带有文本输入的 PowerShell 电子邮件

带有文本输入的 PowerShell 电子邮件

我正在尝试编写一个脚本,它将抛出四个文本输入框并将其输入的值保存到四个变量中,每个变量代表用户名、电话 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

相关内容