powershellvariableshashtableou

Possible to compress variable substitution in powershell?


I'm trying to create a script with GUI that will allow me to create user accounts for my organization and to assign the user accounts to various OUs. My problem is that I want to display a simple name in a listbox and have the selection map to the proper distinguished name for the OU, but to do that I'm having to manually reassign the variables as shown below:

$OU = WPFOU_List.SelectedItems

$WPFHR_Staff.Add_Click({
   $WPFOU_List.Items.Clear()
   $WPFOU_List.Items.Add("Oregon")
   $WPFOU_List.Items.Add("Colorado")
   $WPFOU_List.Items.Add("California")
})

$WPFSales_Staff.Add_Click({
   $WPFOU_List.Items.Clear()
   $WPFOU_List.Items.Add("Portland")
   $WPFOU_List.Items.Add("Denver")
   $WPFOU_List.Items.Add("Los Angeles")
})


if ($OU = "Oregon")
{$OU = "ou=oregon,ou=hr,dc=my,dc=org,dc=com"}
elseif ($OU = "Colorado")
{$OU = "ou=colorado,ou=hr,dc=my,dc=org,dc=com"}
elseif ($OU = "California")
{$OU = "ou=california,ou=hr,dc=my,dc=org,dc=com"}
elseif ($OU = "Portland")
{$OU = "ou=portland,ou=sales,dc=my,dc=org,dc=com"}
elseif ($OU = "Denver")
{$OU = "ou=denver,ou=sales,dc=my,dc=org,dc=com"}
elseif ($OU = "Los Angeles")
{$OU = "ou=la,ou=sales,dc=my,dc=org,dc=com"}

Clicking either of the buttons populates a listbox with the friendly names, but is there an easier way to map those friendly names to the distinguished paths?


Solution

  • Use an ordered hashtable (PSv3+) to define your friendly names and their associated OUs:

    $ous = [ordered] @{
      Oregon        = "ou=oregon,ou=hr,dc=my,dc=org,dc=com"
      Colorado      = "ou=colorado,ou=hr,dc=my,dc=org,dc=com"
      # ...
      'Los Angeles' = "ou=la,ou=sales,dc=my,dc=org,dc=com"
    }
    

    You can then enumerate and filter it by department (hr and sales, in your case) and use each entry's .Key property - which contains the friendly name - to populate the list; requires PSv4+, due to use of .Where().

    Using hr as an example:

    $WPFHR_Staff.Add_Click({
       $WPFOU_List.Items.Clear()
       # Note that in order to enumerate hashtables you must use .GetEnumerator()
       foreach ($ouEntry in $ous.GetEnumerator().Where({ $_.Value -match ',ou=hr,' })) {
         $WPFOU_List.Items.Add($ouEntry.Key) # .Key is the friendly name
       }
    })
    

    Note: For performance reasons, the above is only feasible for smallish hashtables; with a large number of OUs a more sophisticated approach is needed.


    To obtain the full OU name based on the selected list item (assuming that .SelectedItems returns a single friendly name added to the list earlier):

    $ou = $ous[$WPFOU_List.SelectedItems]