Powershell: Filtering flat arrays

2020-04-30 02:01发布

问题:

I'm working on a PS script for making some of our processes easier and more automated and I've quickly found myself well outside my (limited) PowerShell knowledge.

Context: I'm building a UI that has two ComboBox controls and a handful of text boxes for creating resource calendars. The first ComboBox has a static list of 3 sub-divisions in my organization. The second ComboBox has a list of the offices in that division which should automatically update when a selection is made in the first box.

The end goal is to generate the Exchange Management Shell code necessary to create mailboxes with the necessary uniform naming convention:

New-Mailbox -Name 'Acme Inc $division $office $subdivision Resource Name' -Alias 'resourcename'-OrganizationalUnit '<path/to/OU>' -UserPrincipalName 'resourcename@acmeinc.lcl' -SamAccountName 'resourcename' 

Right now I'm thinking I'll build these off of a single array which has three fields that correspond to division, sub-division, and office:

Note: Division 1 has no subdivisions, while division 2 has two subdivisions. Combobox 1 should list division 1, subdivision 1, subdivision 2.

$arr_AgencyOffices = @(
     'division 1','division 1','Aberdeen'
     'division 1','division 1','Perth'
     'division 1','division 1','Sacramento'
     'division 1','division 1','Long Beach'
     'division 1','division 1','New York'
     'division 1','division 1','Dallas'
     'division 1','division 1','Miami'
     'division 1','division 1','Vancouver'
     'division 2','subdivision 1','Sacramento'
     'division 2','subdivision 1','Tumwater'
     'division 2','subdivision 1','Vancouver'
     'division 2','subdivision 2','Aberdeen'
     'division 2','subdivision 2','Centralia'
     'division 2','subdivision 2','Sacramento'
     'division 2','subdivision 2','Long Beach'
     'division 2','subdivision 2','Shelton'
     'division 2','subdivision 2','Dallas'
     'division 2','subdivision 2','Stevenson'
     'division 2','subdivision 2','Miami'
     'division 2','subdivision 2','Vancouver'
)

Specific Question: How do I return only the matching office location values into $arr_Offices given any specific cbo1.SelectedItem?

回答1:

What you show in your example is not a multi-dimensional array, it's just a regular flat array.

To get a multi-dimensional (or rather, a jagged) array, do:

$arr_AgencyOffices = @(
    @('division 1','division 1','Aberdeen'),
    @('division 1','division 1','Perth'),
    @('division 1','division 1','Sacramento'),
    @('division 1','division 1','Long Beach'),
    @('division 1','division 1','New York'),
    @('division 1','division 1','Dallas'),
    @('division 1','division 1','Miami'),
    @('division 1','division 1','Vancouver'),
    @('division 2','subdivision 1','Sacramento'),
    @('division 2','subdivision 1','Tumwater'),
    @('division 2','subdivision 1','Vancouver'),
    @('division 2','subdivision 2','Aberdeen'),
    @('division 2','subdivision 2','Centralia'),
    @('division 2','subdivision 2','Sacramento'),
    @('division 2','subdivision 2','Long Beach'),
    @('division 2','subdivision 2','Shelton'),
    @('division 2','subdivision 2','Dallas'),
    @('division 2','subdivision 2','Stevenson'),
    @('division 2','subdivision 2','Miami'),
    @('division 2','subdivision 2','Vancouver')
)

Now you can index into the value on two dimensions:

$arr_AgencyOffices[4][2] # New York

That being said, I would probably arrange the offices into a set of nested hashtables, like so:

$AgencyOffices = @{
    'division 1' = @{
        'division 1' = @(
            'Aberdeen'
            'Perth'
            'Sacramento'
            'Long Beach'
            'New York'
            'Dallas'
            'Miami'
            'Vancouver'
        )
    }
    'division 2' = @{
        'subdivision 1' = @(
            'Sacramento'
            'Tumwater'
            'Vancouver'
        )
        'subdivision 2' = @(
            'Aberdeen'
            'Centralia'
            'Sacramento'
            'Long Beach'
            'Shelton'
            'Dallas'
            'Stevenson'
            'Miami'
            'Vancouver'
        )
    }
}

Now you can index into the subdivision arrays using their actual names:

PS C:\> $AgencyOffices['division 2']['subdivision 1']
Sacramento
Tumwater
Vancouver

This makes it trivial to retrieve the correct lists for the comboboxes given that you can just take the selected text of the preceding choice to find the next list:

$combobox2List = $AgencyOffices[$combobox1.SelectedText].Keys

and so on