Combine multiple arrays down to one

AintGotNoTime 161 Reputation points
2021-09-01T19:50:17.237+00:00

In my script I am pulling accounts from many OU structures, and so I have an array for each. how can I eliminate all these different arrays I am trying to combine down to one for the whole things. Sometimes no accounts are returned in the array and I have issues in past that would blank out the main array I was sticking accounts into.
`#Get a domain controller for the dva domain.
$dc = Get-ADDomainController -DomainName dva -Discover -NextClosestSite

Add the Domains via the following

Create and Array and then add the array to the filter with the domain name and then add the filter to main array collections if it finds information

$dvamailboxes = Get-ADOrganizationalUnit -LDAPFilter "(Name=Shared Mailboxes)" -Server dva | Select-Object -Expand DistinguishedName

After getting the mailbox OU then Create andother array for the accounts and select accounts per the date.

roll through dva looking for accounts

$dvamailboxAccounts = foreach ($box in $($dvamailboxes))
{
Get-ADUser -Server $dc -SearchBase $box -filter * -Property whenCreated | Where {$_.whenCreated -gt $dte}
}

Select the objects from the Get-ADuser and put in an array for use later

$dvaacctArray = $dvamailboxAccounts | select @{Name="userName";Expression={$_.SamAccountName.Trim()}}, @{Name="address";Expression={"dva"}}, @{Name="safeName";Expression={'VA-WIN-MAILBOX-ACCTS'}},
@{Name="platformId";Expression={'VA-WinLocalDisableAcct-Prod-Admin-26-1yr'}}, @{Name="secret";Expression={'12345678'}}

Append the array with the DVA accounts

if($dvaacctArray -gt $null)
{
$mainemailaccounts += $dvaacctArray
}
`
Then I do the same with the next domain
#Get the DC for the AAC domain
$dc = Get-ADDomainController -DomainName aac -Discover -NextClosestSite

#Add the Domains via the following
#Create and Array and then add the array to the filter with the domain name and then add the filter to main array collections if it finds information
$aacmailboxes = Get-ADOrganizationalUnit -LDAPFilter "(Name=Shared Mailbox)" -Server aac |  Select-Object -Expand DistinguishedName


#After getting the mailbox OU then Create andother array for the accounts and select accounts per the date.
#roll through dva looking for accounts
$aacmailboxAccounts = foreach ($box in $($aacmailboxes)) 
    {
        Get-ADUser -Server $dc -SearchBase $box -filter * -Property whenCreated | Where {$_.whenCreated -gt $dte}
    }

#Select the objects from the Get-ADuser and put in an array for use later
$aacacctArray = $aacmailboxAccounts | select @{Name="userName";Expression={$_.SamAccountName.Trim()}}, @{Name="address";Expression={"aac"}}, @{Name="safeName";Expression={'VA-WIN-MAILBOX-ACCTS'}},
@{Name="platformId";Expression={'VA-WinLocalDisableAcct-Prod-Admin-26-1yr'}}, @{Name="secret";Expression={'12345678'}}




***But this is where the code will start getting large when trying the meld all the arrays into one as I keep adding more.  How can I reduce this to one arrya otherwise I will end up with about 30 statements like below adding up the arrays.

#Append the array with the AAC accounts
if($aacacctArray -gt $null -and $mainemailaccounts -gt $null)
    {
       $mainemailaccounts += $aacacctArray
    }
        elseif ($aacacctArray -gt $null -and $mainemailaccounts -eq $null)
            {
                $mainemailaccounts += $aacacctArray
            }
            else
                {
                 Write-Output "No accounts exist to onboard"
                 exit 1001
                }
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,364 questions
{count} votes

Accepted answer
  1. Rich Matheisen 44,776 Reputation points
    2021-09-02T21:20:15.947+00:00

    I think, based on the code you provided, that almost all of the arrays are unnecessary. You can probably wrap up all that your code does in something like this:

    [datetime]$dte = 0      # to be provided
    
    $domains = 'acc','dav'
    [array]$mainemailaccounts = @()
    $domains |
        ForEach-Object{
            #Get the DC for the domain
            $dc = Get-ADDomainController -DomainName $_ -Discover -NextClosestSite |
                Select-Object -Expand distinguishedName -First 1st
            # get the OUs for this domain
            Get-ADOrganizationalUnit -LDAPFilter "(Name=Shared Mailbox)" -Server $dc |  
                Select-Object -Expand DistinguishedName |
                    ForEach-Object{
                        $mainemailaccounts += Get-ADUser -filter * -Server $dc -SearchBase $_ -SearchScope OneLevel -Property whenCreated | 
                                                Where-Object {$_.whenCreated -gt $dte} |
                                                    Select-Object   @{Name="userName";Expression={$_.SamAccountName.Trim()}}, 
                                                                    @{Name="address";Expression={"aac"}}, 
                                                                    @{Name="safeName";Expression={'VA-WIN-MAILBOX-ACCTS'}},
                                                                    @{Name="platformId";Expression={'VA-WinLocalDisableAcct-Prod-Admin-26-1yr'}}, 
                                                                    @{Name="secret";Expression={'12345678'}}
                    }
        }
        if ($mainemailaccounts.count -eq 0){
            Write-Output "No accounts exist to onboard"
            exit 1001
        }
    

6 additional answers

Sort by: Newest
  1. AintGotNoTime 161 Reputation points
    2021-09-13T20:51:58.01+00:00

    Ok, this code works with one issue, it only ever gets the accounts in the array of the last domain in the list of $33Domains, the purpose was to consolidate into one array, but it get no other accounts but the last domain.

    [datetime]$dte = '06/15/2021'
     $ALLmailboxes = @()
     $ALLmailboxAccounts = @()
     $ALLacctArray = @()
     $33Domains = @('dva', 'aac', 'cem')
    
     Foreach ($Domain in $33Domains) {
         $Domainmailboxes = @()
         $DomainmailboxAccounts = @()
         $DomainacctArray = @()
    
         $dc = Get-ADDomainController -DomainName $Domain -Discover -NextClosestSite
         [string]$dchost = $dc.HostName
    
         $Domainmailboxes = Get-ADOrganizationalUnit -LDAPFilter "(Name=Shared Mailboxes)" -Server $dchost |  Select-Object -Expand DistinguishedName
    
         #Write-Host $Domainmailboxes | Format-Table -force
    
    
             $DomainmailboxAccounts = foreach ($box in $($Domainmailboxes)) 
              {
                  Get-ADUser -Server $dchost -SearchBase $box -filter * -Property whenCreated | Where {$_.whenCreated -gt $dte}
              }
    
    
                 # rest of domain level processing goes here
                $DomainacctArray += $DomainmailboxAccounts | select @{Name="userName";Expression={$_.SamAccountName.Trim()}}, 
                                                                    @{Name="address";Expression={$Domain}}, 
                                                                    @{Name="safeName";Expression={'VA-WIN-MAILBOX-ACCTS-4'}},
                                                                    @{Name="platformId";Expression={'VA-WinLocalDisableAcct-Prod-Admin-26-1yr'}}, 
                                                                    @{Name="secret";Expression={'12345678'}}
    
    
          }  
    
         write-host = $DomainacctArray | Format-table -Force
    

  2. Limitless Technology 39,356 Reputation points
    2021-09-09T09:32:58.483+00:00

    Hi there,

    Account organizational units (OUs) contain user, group, and computer objects. Resource OUs contain resources and the accounts that are responsible for managing those resources. The forest owner is responsible for creating an OU structure to manage these objects and resources and for delegating control of that structure to the OU owner. You can get more info from here

    https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/delegating-administration-of-account-ous-and-resource-ous

    Hope this Answers all your queries , if not please do repost back .
    If an Answer is helpful, please click "Accept Answer" and upvote it : )

    0 comments No comments

  3. AintGotNoTime 161 Reputation points
    2021-09-03T21:53:37.12+00:00

    Ok, I got this working to filter through so far but 2 things, one it does not pull the samAccountName and I need the address to be the same as the domain I am searching through. I tried the variable but that was a no go.

    [datetime]$dte = '08/15/2021'
    $ALLmailboxes = @()
    $ALLmailboxAccounts = @()
    $ALLacctArray = @()
    $33Domains = @('dva', 'cem')
    
    Foreach ($Domain in $33Domains) {
        $Domainmailboxes = @()
        $DomainmailboxAccounts = @()
        $DomainacctArray = @()
    
        $dc = Get-ADDomainController -DomainName $Domain -Discover -NextClosestSite
        $Domainmailboxes = Get-ADOrganizationalUnit -LDAPFilter "(Name=Shared Mailboxes)" -Server $Domain |  Select-Object -Expand DistinguishedName
    
        Write-Host $Domainmailboxes | Format-Table -force
    
    
        $DomainmailboxAccounts = foreach ($box in $($Domainmailboxes)) 
         {
             Get-ADUser -Server $dc -SearchBase $box -filter * -Property whenCreated | Where {$_.whenCreated -gt $dte}
    
         }
    
        # rest of domain level processing goes here
        $DomainacctArray = $DomainmailboxAccounts | Select
                                                         @{Name="userName";Expression={$_.SamAccountName.Trim()}}, 
                                                         @{Name="address";Expression={'$Domain'}}, 
                                                         @{Name="safeName";Expression={'VA-WIN-MAILBOX-ACCTS'}},
                                                         @{Name="platformId";Expression={'VA-WinLocalDisableAcct-Prod-Admin-26-1yr'}}, 
                                                         @{Name="secret";Expression={'12345678'}}
    
        write-host = $DomainacctArray | Format-table -Force
        # All done, Now append the domain that we processed to the overall arrays.  
    
        #$ALLmailboxes += $Domainmailboxes 
        #$ALLmailboxAccounts += $DomainmailboxAccounts 
        #$ALLacctArray += $DomainacctArray
    

  4. MotoX80 31,571 Reputation points
    2021-09-02T19:36:13.11+00:00

    So don't build 33 (or more) arrays, make the "loop" generic so that it can process any domain.

     $ALLmailboxes = @()
     $ALLmailboxAccounts = @()
     $ALLacctArray = @()
     $33Domains = @('aac','dva','abc','xyz','etc')
     Foreach ($Domain in $33Domains) {
         "Processing domain $Domain"
         $Domainmailboxes = @()
         $DomainmailboxAccounts = @()
         $DomainacctArray = @()
    
         $Domainmailboxes = Get-ADOrganizationalUnit -LDAPFilter "(Name=Shared Mailboxes)" -Server $Domain |  Select-Object -Expand DistinguishedName
    
    
         # rest of domain level processing goes here
    
    
         # All done, Now append the domain that we processed to the overall arrays.  
    
         $ALLmailboxes += $Domainmailboxes 
         $ALLmailboxAccounts += $DomainmailboxAccounts 
         $ALLacctArray += $DomainacctArray
    
    
     }
    
    0 comments No comments