sbagnato
sbagnato

Reputation: 496

Powershell - Using If with multiple checkboxes

I have a long script that provides a user with prompts: enter a ticket number (commented out for now), enter an email address (also commented) and select from a series of 4 checkboxes. The idea is that a new person can get access to any combo of 4 different locations. 2 locations are handled by 1 admin, and the other 2 by a single admin (IE, A & B are handled by admin A, C is handled by admin B, and D by C). Therefore, I wrote a long script that includes a snippet of code for each location combination without duplication. So, you could select A, AB, AC, AD, ABC, ABD, ect.

If I include code to just send an email when A, B, C OR D is chosen, everything works great. When I include code to, say, select A & B, the script does not work right.

An example: I select to include access to building A. The email gets sent saying user needs access to A. Another example: I select to include access to building B. The emails gets sent saying user needs access to B. Final example with the issue: I select to include access to buildings A and B. I get a prompt to include access to A and a prompt to include access to A and B, but I get 2 emails to include access to A. I should get 1 prompt and 1 email both stating access to A and B.

For brevity, I have clipped a lot of the code to remove all combinations besides the code for A, and A & B. If you need me to include more, please let me know.

# initialize the script
    if ($startupvariables) { try {Remove-Variable -Name startupvariables  -Scope Global -ErrorAction SilentlyContinue } catch { } }
    New-Variable -force -name startupVariables -value ( Get-Variable | ForEach-Object { $_.Name } )

# make sure the cmd window is not closed
    Write-Output "Don't close this window!"

    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
    $Separator = ".", "@"

# advise what the script does
    Add-Type -AssemblyName PresentationCore,PresentationFramework
    $ButtonType = [System.Windows.MessageBoxButton]::OKCancel
    $MessageIcon = [System.Windows.MessageBoxImage]::Warning
    $MessageTitle = "Building Access - US Corp Locations"
    $MessageBody = "This script sends the building admins for the US corporate locations an email advising them that a user needs access to their location.`n`nTo use it, enter the below information:`n`n`n`tSCTask Ticket Number`n`n`tUser's Email Address`n`n`tBuilding Access Requested`n`n`nIf this is the script you want to use, click OK.`nIf not, click Cancel."
    $Result = [System.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon)

    if ($Result -eq "Cancel")
    {
        Exit-PSSession
    }
    else
    {

# get the ticket number
###################
#    $Ticket = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the SCTask ticket number" , "Ticket Number")
$Ticket = 1234567890
###################
# get the user id via the email address
###################
#    $UserID = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the user's email address" , "User Email Address")
$UserID = "xxxxxxxxxxx.com"
###################
    $User = $UserID.split($Separator)
    $Firstname = $User[0].substring(0,1).toupper()+$User[0].substring(1).tolower()
    $Lastname = $User[1].substring(0,1).toupper()+$User[1].substring(1).tolower()
    $User = $Firstname, $Lastname

# get the local username
    $Username = [System.Environment]::UserName

# provide checkboxes for locations requested
    function Location_Access{
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 

    $Form = New-Object System.Windows.Forms.Form
    $Form.width = 415
    $Form.height = 235
    $Form.Text = ”Select Building Locations"
    $Font = New-Object System.Drawing.Font("Verdana",11)
    $Form.Font = $Font

    $MyGroupBox = New-Object System.Windows.Forms.GroupBox
    $MyGroupBox.Location = '5,5'
    $MyGroupBox.size = '385,135'

    $Checkbox1 = New-Object System.Windows.Forms.Checkbox
    $Checkbox1.Location = '20,20'
    $Checkbox1.size = '360,25'
    $Checkbox1.Checked = $false 
    $Checkbox1.Text = "World Headquarters (Maumee, OH)"
    $CB1 = "World Headquarters"

    $Checkbox2 = New-Object System.Windows.Forms.Checkbox
    $Checkbox2.Location = '20,45'
    $Checkbox2.size = '360,25'
    $Checkbox2.Checked = $false 
    $Checkbox2.Text = "Maumee Technology Center (Maumee, OH)"
    $CB2 = "Maumee Technology Center"

    $Checkbox3 = New-Object System.Windows.Forms.Checkbox
    $Checkbox3.Location = '20,70'
    $Checkbox3.size = '360,25'
    $Checkbox3.Checked = $false 
    $Checkbox3.Text = "Global IT Center/Longbow (Maumee, OH)"
    $CB3 = "Global IT Center/Longbow"

    $Checkbox4 = New-Object System.Windows.Forms.Checkbox
    $Checkbox4.Location = '20,95'
    $Checkbox4.size = '360,25'
    $Checkbox4.Checked = $false 
    $Checkbox4.Text = "Novi (Novi, MI)"
    $CB4 = "Novi"

    $OKButton = new-object System.Windows.Forms.Button
    $OKButton.Location = '10,150'
    $OKButton.Size = '90,35' 
    $OKButton.Text = 'OK'
    $OKButton.DialogResult=[System.Windows.Forms.DialogResult]::OK
    $CancelButton = new-object System.Windows.Forms.Button
    $CancelButton.Location = '110,150'
    $CancelButton.Size = '90,35'
    $CancelButton.Text = "Cancel"
    $CancelButton.Add_Click({$objForm.Close()})
    $CancelButton.DialogResult=[System.Windows.Forms.DialogResult]::Cancel

    $form.Controls.AddRange(@($MyGroupBox,$OKButton,$CancelButton))
    $MyGroupBox.Controls.AddRange(@($Checkbox1,$Checkbox2,$Checkbox3,$Checkbox4))
    $form.AcceptButton = $OKButton
    $form.CancelButton = $CancelButton
    $form.Add_Shown({$form.Activate()})    
    $dialogResult = $form.ShowDialog()

    if ($DialogResult -eq "OK")
    {
    # if WHQ is selected
        if ($Checkbox1.Checked)
        {
            $subject = "Ticket $Ticket - $User's Building Access Request"
            $body = @"
            <html>
            <body style="font-family:calibri"> 
            Team,<br>
            <br>
            <br>
            Per ticket $Ticket, $User is requesting building access to:<br>
            <br>
            <br>
            <b><u>$CB1</b></u><br>
            <br>
            <br>
            <br>
            Thank You,<br>
            <br>
            IT Service Desk<br>
            <br>
            ------------------------------------------------------------------ <br>
            IT Service Desk Operation Information <br>
            ------------------------------------------------------------------ <br>
            Hours of Operation       :    24 hours a day<br>
            xxxxxxxxxxxxxxxx
            </body>
            </html>
"@
        }
        # create confirmation message
            $ButtonType = [System.Windows.MessageBoxButton]::YesNo
            $MessageIcon = [System.Windows.MessageBoxImage]::Warning
            $MessageTitle = "Corporate Building Access Request"
            $MessageBody = "The information you have entered is show below:`n`n`nTicket Number: $Ticket`n`nUser's Email Address: $UserID`n`nAccess To: $CB1`n`n`nIf you would like to send the email, click Yes.`nOtherwise, click No."
            $Result = [System.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon)
            if ($Result -eq "No")
            {
                Exit-PSSession
            }
            else
        # send email
            {
                Send-MailMessage -To "<[email protected]>" -from "<[email protected]>" -Subject $subject -SmtpServer "mailrelay.xxxx.com" -BodyAsHtml -body $body
            }
    # if WHQ & MTC is selected
        elseif ($Checkbox1.Checked -And $Checkbox2.Checked)
        {
            $subject = "Ticket $Ticket - $User's Building Access Request"
            $body = @"
            <html>
            <body style="font-family:calibri"> 
            Team,<br>
            <br>
            <br>
            Per ticket $Ticket, $User is requesting building access to:<br>
            <br>
            <br>
            <b><u>$CB1 & $CB2</b></u><br>
            <br>
            <br>
            <br>
            Thank You,<br>
            <br>
            IT Service Desk<br>
            <br>
            ------------------------------------------------------------------ <br>
            IT Service Desk Operation Information <br>
            ------------------------------------------------------------------ <br>
            Hours of Operation       :    24 hours a day<br>
            xxxxxxxxx
            </body>
            </html>
"@
        }
        # create confirmation message
            $ButtonType = [System.Windows.MessageBoxButton]::YesNo
            $MessageIcon = [System.Windows.MessageBoxImage]::Warning
            $MessageTitle = "Corporate Building Access Request"
            $MessageBody = "The information you have entered is show below:`n`n`nTicket Number: $Ticket`n`nUser's Email Address: $UserID`n`nAccess To: $CB1 & $CB2`n`n`nIf you would like to send the email, click Yes.`nOtherwise, click No."
            $Result = [System.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon)
            if ($Result -eq "No")
            {
                Exit-PSSession
            }
            else
        # send email
            {
                Send-MailMessage -To "<[email protected]>" -from "<[email protected]>" -Subject $subject -SmtpServer "mailrelay.xxxx.com" -BodyAsHtml -body $body
            }

    }
    elseif ($DialogResult -eq "Cancel")
    {
        break
    }
}
Location_Access
}

Function Clean-Memory {
    Get-Variable |
        Where-Object { $startupVariables -notcontains $_.Name } |
            ForEach-Object {
            try { Remove-Variable -Name "$($_.Name)" -Force -Scope "global" -ErrorAction SilentlyContinue -WarningAction SilentlyContinue}
                catch { }
 }
 }

enter image description here

enter image description here

enter image description here

I should not get that middle prompt, only the second one where it prompts for both locations selected. Included with each prompt is an email for the building access. However, I get 2 emails both for access to the first building, and neither mentioning the second building.

I know this is odd, and probably seems convoluted. Please let me know what other info you might need. I can include the full code if needed; just wanted to cut out as much extras as possible.


Update: error when running script

You cannot call a method on a null-valued expression.
At line:109 char:42
+ $MyGroupBox.Controls | % {if($_.Checked){[Void]$TextTotal.AppendLine($_.Text);[V ...
+                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At line:142 char:154
+ ... `nAccess To: $($TextTotal.ToString())`n`n`nIf you would like to send the email,  ...
+                    ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Upvotes: 0

Views: 2499

Answers (1)

Kirill Pashkov
Kirill Pashkov

Reputation: 3236

I think you need to build up final message according to elements checked. Add this piece of code right after form showdialog call ($dialogResult = $form.ShowDialog())

$CheckedBoxes = New-Object System.Text.StringBuilder
$CheckedBoxesForEmail = New-Object System.Text.StringBuilder
$MyGroupBox.Controls | % {if($_.Checked){[Void]$TextTotal.AppendLine($_.Text);[Void]$CheckedBoxesForEmail.AppendLine('<b><u>{0}</b></u><br>' -f $_.Text)}}

Then just throw away all those needless IF statements for every checkbox. I have changed variable $CB1 to this $($CheckedBoxesForEmail.ToString()) and this $($TextTotal.ToString()). Those will carry all the text you want.

$CheckedBoxes = New-Object System.Text.StringBuilder
$CheckedBoxesForEmail = New-Object System.Text.StringBuilder
$MyGroupBox.Controls | % {if($_.Checked){[Void]$TextTotal.AppendLine($_.Text);[Void]$CheckedBoxesForEmail.AppendLine('<b><u>{0}</b></u><br>' -f $_.Text)}}

if ($DialogResult -eq "OK")
    {
            $subject = "Ticket $Ticket - $User's Building Access Request"
            $body = @"
            <html>
            <body style="font-family:calibri"> 
            Team,<br>
            <br>
            <br>
            Per ticket $Ticket, $User is requesting building access to:<br>
            <br>
            <br>$($CheckedBoxesForEmail.ToString())<br>
            <br>
            <br>
            Thank You,<br>
            <br>
            IT Service Desk<br>
            <br>
            ------------------------------------------------------------------ <br>
            IT Service Desk Operation Information <br>
            ------------------------------------------------------------------ <br>
            Hours of Operation       :    24 hours a day<br>
            xxxxxxxxxxxxxxxx
            </body>
            </html>
"@
        }
        # create confirmation message
            $ButtonType = [System.Windows.MessageBoxButton]::YesNo
            $MessageIcon = [System.Windows.MessageBoxImage]::Warning
            $MessageTitle = "Corporate Building Access Request"
            $MessageBody = "The information you have entered is show below:`n`n`nTicket Number: $Ticket`n`nUser's Email Address: $UserID`n`nAccess To: $($TextTotal.ToString())`n`n`nIf you would like to send the email, click Yes.`nOtherwise, click No."
            $Result = [System.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon)

Upvotes: 1

Related Questions