Search for partial match in array

@ksl28 - if I understood your posts correctly, you were matching DNs by criteria. Regular Expressions are an efficient way to parse strings for this purpose.

In the demo code below:

  • I create an array of DNs with included noise for testing the regex.
  • Store the match criteria in variable matchOUs.
  • Instantiate an ArrayList object to hold the results in memory.
  • Used a single foreach to iterate over the array and execute an if statement.

I do not have AD on my laptop. Therefore, I did not include the DN check in the code.

Demo Code

using namespace System.Collections;

$WinServers = @(“CN=Server1,OU=Navision,OU=salary,OU=country4,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server2,OU=2017,OU=Navision,OU=salary,OU=country4,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server3,OU=2019,OU=Navision,OU=salary,OU=country4,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server4,OU=salary,OU=country4,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server5,OU=yada1,OU=yada2,OU=yada3,OU=saladShooter,OU=salary,OU=country4,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Bob\, Billy,OU=Compliance,OU=country4,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Doe\, Jane,OU=Compliance,OU=country4,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server33,OU=HR,OU=country3,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server44,OU=HR,OU=country4,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server202,OU=HR,OU=country3,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server22,OU=HR,OU=country3,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server30019,OU=Extra,OU=HR,OU=country3,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Server313,OU=HR,OU=country3,OU=ExtraStuff2,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Smith\, John,OU=salary,OU=country4,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=Smith\, John,OU=salary,OU=country5,OU=Servers,OU=Administration,DC=domain,DC=com”,
“CN=BigWig\, BigWig,OU=Gold,OU=Partners,OU=Vendors,DC=domain,DC=com”);

$matchOUs = "^CN=Server(\d)+(?:`.+)?,OU=(\bsalary\b|\bHR\b|\bCompliance\b),OU=country[1-4],OU=Servers,OU=Administration,DC=domain,DC=com";

$results = [ArrayList]::new();

foreach ($i in $WinServers)
{
    if($i -match $matchOUs)
    {
        [void]$results.Add($i);
    }
}
cls
$results;

Results

If my eyes aren’t tricking me, then there should be 10 matches. Careful with CN=Server313~. That one threw me at first.

Remarks

Regex can reduce the amount of code and processing because of its compact nature. I can break down the match criteria if you’d like.

I also tested a for loop that used array indexing, but saw no gain in performance over foreach—both repeatedly measured at 2 milliseconds with Measure-Command on my laptop. There could be a greater time difference looping over larger sets.

Using a for loop

$results1 = [ArrayList]::new();
for ($i = 0; $i -lt $WinServers.Count; $i++)
{
    if($WinServers[$i] -match $matchOUs)
    {
        [void]$results1.Add($WinServers[$i]);
    }
}

See also

Regular expression syntax cheatsheet.