0

I've been working on this script that seemed simple enough in concept but is really boggling me with some things that just don't seem to work like I'd expect. The basic idea is the script is going to read a set of usernames and provide a user with a checkbox they can check for each account they want the system to create. With help from this site I was able to get a function that is able to dynamically create the variables and checkbox objects, but now I am having issues accessing their values. I just need to pull a boolean value for each name whether the box was checked or not. Here is the full code:

$form = New-Object System.Windows.Forms.Form
$flowlayoutpanel = New-Object System.Windows.Forms.FlowLayoutPanel
$buttonOK = New-Object System.Windows.Forms.Button


$usernames = "andrew", "beth", "charlie", "dave", "james", "george"
$totalvalues = ($usernames.count)

$formsize = 85 + (30 * $totalvalues)
$flowlayoutsize = 10 + (30 * $totalvalues)
$buttonplacement = 40 + (30 * $totalvalues)

$form_Load = {
    foreach($user in $usernames){
        $DynamicCheckBox = New-Variable -Name ("checkbox" + $user)
        $DynamicCheckBox = New-object System.Windows.Forms.CheckBox

        $DynamicCheckBox.Margin = '10, 8, 0, 0'
        $DynamicCheckBox.Name = 'checkbox' + $_
        $DynamicCheckBox.Size = '200, 22'
        $DynamicCheckBox.Text = "" + $user
        $DynamicCheckBox.TextAlign = 'MiddleLeft'
        $flowlayoutpanel.Controls.Add($DynamicCheckBox)
    }       
}

$form.Controls.Add($flowlayoutpanel)
$form.Controls.Add($buttonOK)
$form.AcceptButton = $buttonOK
$form.AutoScaleDimensions = '8, 17'
$form.AutoScaleMode = 'Font'
$form.ClientSize = "500 , $formsize"
$form.FormBorderStyle = 'FixedDialog'
$form.Margin = '5, 5, 5, 5'
$form.MaximizeBox = $False
$form.MinimizeBox = $False
$form.Name = 'form1'
$form.StartPosition = 'CenterScreen'
$form.Text = 'Form'
$form.add_Load($form_Load)

$flowlayoutpanel.BorderStyle = 'FixedSingle'
$flowlayoutpanel.Location = '48, 13'
$flowlayoutpanel.Margin = '4, 4, 4, 4'
$flowlayoutpanel.Name = 'flowlayoutpanel1'
$flowlayoutpanel.Size = "400, $flowlayoutsize"
$flowlayoutpanel.TabIndex = 1

$buttonOK.Anchor = 'Bottom, Right'
$buttonOK.DialogResult = 'OK'
$buttonOK.Location = "383, $buttonplacement"
$buttonOK.Margin = '4, 4, 4, 4'
$buttonOK.Name = 'buttonOK'
$buttonOK.Size = '100, 30'
$buttonOK.TabIndex = 0
$buttonOK.Text = '&OK'


$form.ShowDialog()

    foreach($user in $usernames){
        $DynamicCheckBoxValue = Get-Variable -Name ('$checkbox' + $user) -Scope Script
        write-host $DynamicCheckBoxValue

    }  

write-host $checkbox.Checked

I've tried playing with the scope settings for the variable being created in line 15, but if I change the scope to Script as I think it should be, I get a strange series of errors. Powershell tells me that the variable already exists (though this may be because they are still in my ISE session?). If I tell it to forcibly overwrite any that might be there that fixes that error, but either way I get errors that tell me that the variable does not exist, even when just right before powershell was complaining that the variables already did exist.

Get-Variable : Cannot find a variable with the name '$checkboxgeorge'.
At C:\Users\sheep\Untitled1.ps1:62 char:33
+ ...      $DynamicCheckBoxValue = Get-Variable -Name ('$checkbox' + $user)
+                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: ($checkboxgeorge:String) [Get-Variable], ItemNotFoundException
    + FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.GetVariableCommand

I'm not sure what is happening here and I'm fiddling with scopes as that seems like the culprit. If anyone here knows what the fix is could you also tell me why this is happening?

Sheep
  • 5
  • 3
  • did you mean: `$DynamicCheckBoxValue = Get-Variable -Name ('checkbox' + $user)` without the `$` sign? – Kory Gill Sep 19 '17 at 21:57
  • 1
    "*With help from this site I was able to get a function that is able to dynamically create the variables*" - that wasn't a help, that was a hinderance. See previous rant/answer on this topic: https://stackoverflow.com/a/40477933/478656 – TessellatingHeckler Sep 19 '17 at 22:05

3 Answers3

1

Even though i submitted this answer, I strongly recommend you to read this answer from TesselatingHeckler here that he kindly provided in the comments section to you.

Furthermore, although dynamic variables are a thing, in your case, that's a layer which proves to be useless and add complicated logic when this can be much more simple.

One better solution than dynamic variables for your scenario.

For instance, instead of creating a username array, use a hashtable which will still store your username but will have a "value" field which you can use to store your bolean and soon enough, when you have something more complex, you can store complete object inside the value field.

$usernames = 
            @{
            'andrew'='';
            'beth'='';
            'charlie'='';
            'dave'='';
            'james'=''
            'george'=''
            }

Now that you have your hashtable, you can set your values using

#Settings some value - in your case, that would be done through the form
$usernames.andrew = 0 
$usernames.dave = 1

You can even do it "dynamically"

$User = Read-Host  # Asking which user here
$usernames.Item($User) = 1 # setting user "checkbox value" to 1 here

For instance, in that last example, the username is stored into $User and the value of that user is then set to '1' .

It gives you everything you wanted without the overhead of setting dynamic variables.

A simple statement to display who checked their checkbox. Since everything is in the $Usernames hashtable, it is easy to manipulate, store into a csv file, etc... without any additional work.

# Display users checked status their checkboxes
$usernames | ft Name, @{n='IsChecked';e={$_.Value -eq 1}}
Sage Pourpre
  • 9,932
  • 3
  • 27
  • 39
0

Below line is not making any change to variable $DynamicCheckBox.

$DynamicCheckBox = New-Variable -Name ("checkbox" + $user)

I have modified the script to find out which users were checked. Hope this will help.

Code:-

    $form = New-Object System.Windows.Forms.Form
    $flowlayoutpanel = New-Object System.Windows.Forms.FlowLayoutPanel
    $buttonOK = New-Object System.Windows.Forms.Button


    $usernames = "andrew", "beth", "charlie", "dave", "james", "george"
    $totalvalues = ($usernames.count)

    $formsize = 85 + (30 * $totalvalues)
    $flowlayoutsize = 10 + (30 * $totalvalues)
    $buttonplacement = 40 + (30 * $totalvalues)

    $script:CheckBoxArray = @()

    $form_Load = {

       foreach($user in $usernames){

            $DynamicCheckBox = New-object System.Windows.Forms.CheckBox

            $DynamicCheckBox.Margin = '10, 8, 0, 0'
            $DynamicCheckBox.Name = $user
            $DynamicCheckBox.Size = '200, 22'
            $DynamicCheckBox.Text = "" + $user
            $DynamicCheckBox.TextAlign = 'MiddleLeft'
            $flowlayoutpanel.Controls.Add($DynamicCheckBox)
            $script:CheckBoxArray += $DynamicCheckBox
        }       
    }

    $form.Controls.Add($flowlayoutpanel)
    $form.Controls.Add($buttonOK)
    $form.AcceptButton = $buttonOK
    $form.AutoScaleDimensions = '8, 17'
    $form.AutoScaleMode = 'Font'
    $form.ClientSize = "500 , $formsize"
    $form.FormBorderStyle = 'FixedDialog'
    $form.Margin = '5, 5, 5, 5'
    $form.MaximizeBox = $False
    $form.MinimizeBox = $False
    $form.Name = 'form1'
    $form.StartPosition = 'CenterScreen'
    $form.Text = 'Form'
    $form.add_Load($($form_Load))

    $flowlayoutpanel.BorderStyle = 'FixedSingle'
    $flowlayoutpanel.Location = '48, 13'
    $flowlayoutpanel.Margin = '4, 4, 4, 4'
    $flowlayoutpanel.Name = 'flowlayoutpanel1'
    $flowlayoutpanel.AccessibleName = 'flowlayoutpanel1'
    $flowlayoutpanel.Size = "400, $flowlayoutsize"
    $flowlayoutpanel.TabIndex = 1

    $buttonOK.Anchor = 'Bottom, Right'
    $buttonOK.DialogResult = 'OK'
    $buttonOK.Location = "383, $buttonplacement"
    $buttonOK.Margin = '4, 4, 4, 4'
    $buttonOK.Name = 'buttonOK'
    $buttonOK.Size = '100, 30'
    $buttonOK.TabIndex = 0
    $buttonOK.Text = '&OK'


    $form.ShowDialog()

        foreach($cbox in $CheckBoxArray){
            $cbox.Name + " is " + $cbox.CheckState

        }  

    Remove-Variable checkbox*

Input:-

enter image description here

Output:-

enter image description here

Juan Serrats
  • 1,358
  • 5
  • 24
  • 30
Vaibhav
  • 185
  • 2
  • 11
-1

This might push you in the right direction.

When you use Get-Variable you have to exclude the $. So use: Get-Variable -Name ("checkbox" + $user) -Scope Script

Alex
  • 498
  • 2
  • 8