Exclude OU's from being found

The script pulls a list of users from certain OU"s . It works great but we have some OU’s under the main OU that I need to exclued

Main OU will always be the $ou in the script.

The OU"s that I will need to exclude are

$ou Service Accounts
$ou Super Accounts
Disabled Users

This is all under the main OU

Main OU <~ this name changes based on main OU in our enviroment

Example

Azure
Azure Users
Azure Seasonal Accounts
Azure Service Accounts <~ dont want this OU to be searched
Azure Super Accounts <~ dont want this OU to be searched
Disabled Users


 
 
# OUs to Exclude from list - based on OU Name
  $excludeOUs = @(
   "Domain Controllers",
   "Computers - Unsorted",
   "Non-Syncing OU",
   "PDX",
   "Trackside",
   "Z_MigrationTest",
   "Arlington",
   "Nemacolin",
   "Azure"
 
  # Assuming you have OUs with this exact name for exclusion at the OU level
 )
 
 # Finds all OUs
 $ouQuery = Get-ADOrganizationalUnit -Filter * -SearchBase "DC=ad,DC=chdn,DC=com" -SearchScope OneLevel
 
 # Filtering based on OU Name, not DistinguishedName here
 $ouList = $ouQuery | Where-Object { $excludeOUs -notcontains $_.Name }
 
 # Specify output CSV path
 $csvPath = "C:\Users\Public\Okta_AD_Company\testmattUsers.csv"
 
 # Check and remove existing CSV to start fresh
 If (Test-Path $csvPath) { Remove-Item $csvPath }
 
 # Loop through each OU and gather user info while excluding certain DistinguishedName patterns
 foreach ($ou in $ouList) {
     Write-Host "`nFinding Users for $ou" -ForegroundColor Cyan
 
     Get-ADUser -Filter * -SearchBase $ou.DistinguishedName -Properties DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged |
         Where-Object {
             $_.DistinguishedName -notlike "*OU=Disabled Users,*" -and
             $_.DistinguishedName -notlike "*OU= $ou Service Accounts,*" -and
             $_.DistinguishedName -notlike "*OU= $ou Super Accounts,*"
         } |
         Select-Object DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged |
         Export-Csv -Path $csvPath -NoTypeInformation -Append
 }

The code you posted is quite messed up. And apart from that you didn’t even format it as code. So I will ignore it and give some general tips.

For a -contains or -notcontains or -in or -notin filter to work as expected it needs a perfect match. So in case of OUs you would need a list of the DistinguishedNames of the OUs.

You can either …

  • Use a -match or -notmatch filter if the names of the OUs you want to exclude are specific enough.
  • Add a calculated property to the user list with the OU of the user and use the DistinguishedName of the OUs you want to exclude to actually exclude them with a -contains or -notcontains filter.

Please … Next time when you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.

Thanks in advance

How to format code in PowerShell.org 1 <---- Click :point_up_2:t4: :wink:

( !! Sometimes the preformatted text button hides behind the settings gear symbol. :wink: )

I have tried with this code and it still does not work. We have tons of OU’s and just trying to figure out how to dynamically do this work.

# OUs to Exclude from list - based on OU Name
$excludeOUs = @(
    "Domain Controllers",
    "Computers - Unsorted",
    "Non-Syncing OU",
    "PDX",
    "Trackside",
    "Z_MigrationTest",
    "Arlington",
    "Nemacolin",
    "Azure"

     # Assuming you have OUs with this exact name for exclusion at the OU level
)

# Finds all OUs
$ouQuery = Get-ADOrganizationalUnit -Filter * -SearchBase "DC=ad,DC=chdn,DC=com" -SearchScope OneLevel

# Filtering based on OU Name, not DistinguishedName here
$ouList = $ouQuery | Where-Object { $excludeOUs -notcontains $_.Name }

# Specify output CSV path
$csvPath = "C:\Users\Public\Okta_AD_Company\testmattUsers.csv"

# Check and remove existing CSV to start fresh
If (Test-Path $csvPath) { Remove-Item $csvPath }

# Loop through each OU and gather user info while excluding certain DistinguishedName patterns
foreach ($ou in $ouList) {
    Write-Host "`nFinding Users for $ou" -ForegroundColor Cyan

    Get-ADUser -Filter * -SearchBase $ou.DistinguishedName -Properties DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged |
            Where-Object {
        $_.DistinguishedName -notlike "*OU=Disabled Users,*" -and
        $_.DistinguishedName -notmatch  "CN = *,OU=${ou.Name} Service Accounts,OU=${ou.Name} Users,OU=${ou.Name},DC=ad,DC=chdn,DC=com"

        #CN=Bris Scan,OU=Bris Service Accounts,OU=Bris Users,OU=Bris,DC=ad,DC=chdn,DC=com <~ example of one OU that we have ..the bris part can be named . 


        #$_.DistinguishedName -notlike "*OU=${ou.Name} Super Accounts,*"
    } |
        Select-Object DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged |
        Export-Csv -Path $csvPath -NoTypeInformation -Append
}

That’s an unsufficient explanation. What exactly does not work?

What does “dynamically” means in this case?

it still does not fiilter out users that are in the service account OU’s or any other OU’s that I want to exclude.

When i say dynamically that the beginning of the script loops through the OU"s that we have. I just can not figure out why it is not filtering out . I even tried below. It still shows users

CN=Special Service,OU=1CC Service Accounts,OU=1CC Users,OU=1CC,DC=ad,DC=chdn,DC=com

# OUs to Exclude from list - based on OU Name
$excludeOUs = @(
    "Domain Controllers",
    "Computers - Unsorted",
    "Non-Syncing OU",
    "PDX",
    "Trackside",
    "Z_MigrationTest",
    "Arlington",
    "Nemacolin",
    "Azure"

     # Assuming you have OUs with this exact name for exclusion at the OU level
)

# Finds all OUs
$ouQuery = Get-ADOrganizationalUnit -Filter * -SearchBase "DC=ad,DC=chdn,DC=com" -SearchScope OneLevel

# Filtering based on OU Name, not DistinguishedName here
$ouList = $ouQuery | Where-Object { $excludeOUs -notcontains $_.Name }

# Specify output CSV path
$csvPath = "C:\Users\Public\Okta_AD_Company\testmattUsers.csv"

# Check and remove existing CSV to start fresh
If (Test-Path $csvPath) { Remove-Item $csvPath }

# Loop through each OU and gather user info while excluding certain DistinguishedName patterns
foreach ($ou in $ouList) {
    Write-Host "`nFinding Users for $ou" -ForegroundColor Cyan

    Get-ADUser -Filter * -SearchBase $ou.DistinguishedName -Properties DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged |
            Where-Object {
        $_.DistinguishedName -notlike "*OU=Disabled Users,*" -and
        $_.DistinguishedName -notcontains  "*OU=${ou.Name} Service Accounts,OU=${ou.Name} Users,OU=${ou.Name},DC=ad,DC=chdn,DC=com"

        #CN=Bris Scan,OU=Bris Service Accounts,OU=Bris Users,OU=Bris,DC=ad,DC=chdn,DC=com <~ example of one OU that we have ..the bris part can be named . 


        #$_.DistinguishedName -notlike "*OU=${ou.Name} Super Accounts,*"
    } |
        Select-Object DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged |
        Export-Csv -Path $csvPath -NoTypeInformation -Append
}

Based on the code provided, you are not filtering out “Service Account” OU as it is not in the array you created for the exclusion. Am I missing something? FYI, I tried your code and it worked fine for me to filter as long as the OU’s I wanted to exclude were in the $excludeOUs array.

I’d recommend focussing on one issue at a time. You are filtering twice. Once with your exclude list before the loop and once inside the loop with a filter with two conditions.

Which one does not work?

Good catch Olaf, I completely missed that :slight_smile:

I am sorry the one in the middle . We have alot of OU’s and they get added daily and then some are removed. That is why the first loop. It works great as it gets the names of the top level OU’s that is where I get the names to use in the second loop. As all OU’s will have

CN=Special Service,OU=1CC Service Accounts,OU=1CC Users,OU=1CC,DC=ad,DC=chdn,DC=com
CN=Special Service,OU=ABC Service Accounts,OU=ABCUsers,OU=ABC,DC=ad,DC=chdn,DC=com
CN=Special Service,OU=DLC Service Accounts,OU=DLC Users,OU=DLC,DC=ad,DC=chdn,DC=com

the first loop grabs the three letters above .

The second loop is there I can not figure out how to filter right . I would want to remove the above from the loop.

I have a couple other OU"s that i will want to add too be filtered out too in this second loop. Thank you for looking at this . The top loop works great.

Get-ADUser -Filter * -SearchBase $ou.DistinguishedName -Properties DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged |
            Where-Object {
        $_.DistinguishedName -notlike "*OU=Disabled Users,*" -and
        $_.DistinguishedName -notmatch  "CN = *,OU=${ou.Name} Service Accounts,OU=${ou.Name} Users,OU=${ou.Name},DC=ad,DC=chdn,DC=com"

        #CN=Bris Scan,OU=Bris Service Accounts,OU=Bris Users,OU=Bris,DC=ad,DC=chdn,DC=com <~ example of one OU that we have ..the bris part can be named . 


        #$_.DistinguishedName -notlike "*OU=${ou.Name} Super Accounts,*"
    } |
        Select-Object DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged |
        Export-Csv -Path $csvPath -NoTypeInformation -Append
}

The operators -match or -notmatch use regex to filter. In regex the asterisk ( * ) has another meaning than in -like or -notlike for example. The same goes for $ and curly braces. So your pattern does not make sense actually.
Did you actually want to use -notlike?

Why is that? :thinking: :man_shrugging:t3:

I would love to use the notlike. I would actually like to use anything that works. For some reason I can not wrap my head around what to do. I know I will have to use ou.name as it will loop through all the OU’s .

I was able to break it down to 1 ou and able to get filter out the groups I do not want by using this command

$adgroup = Get-ADUser -Filter * -SearchBase $ou.DistinguishedName -Properties DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged |Where-Object { $_.DistinguishedName -notmatch 'Service Accounts| Super Accounts|Disabled Users' } | Select-Object DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged


$adgroup |Export-Csv c:\users\public\testmattnew.csv -NoTypeInformation

I just do not know how to put it in the loop correctly and get the results for all the OU’s . This comes up with a csv error

 # Loop through each OU and gather user info while excluding certain DistinguishedName patterns
 foreach ($ou in $ouList) {
     Write-Host "`nFinding Users for $ou" -ForegroundColor Cyan
 
 Get-ADUser -Filter * -SearchBase $ou.DistinguishedName -Properties DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged `
            |Where-Object { $_.DistinguishedName -notmatch 'Service Accounts| Super Accounts|Disabled Users' } `
            | Select-Object DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged`
                Export-Csv -Path $csvPath -NoTypeInformation -Append
 }
 
 #$adgroup |Export-Csv c:\users\public\okta\testmattnew.csv -NoTypeInformation

Finally resolved it. Here is the final code
Thank you everyone for the assist. I have written odd scripts and not sure why this was throwning me off.

# OUs to Exclude from list - based on OU Name
  $excludeOUs = @(
   "Domain Controllers",
   "Computers - Unsorted",
   "Non-Syncing OU",
   "PDX",
   "Trackside",
   "Z_MigrationTest",
   "Arlington",
   "Nemacolin",
   "Azure"
 
  # Assuming you have OUs with this exact name for exclusion at the OU level
 )
 
 # Finds all OUs
 $ouQuery = Get-ADOrganizationalUnit -Filter * -SearchBase "DC=ad,DC=chdn,DC=com" -SearchScope OneLevel
 
 # Filtering based on OU Name, not DistinguishedName here
 $ouList = $ouQuery | Where-Object { $excludeOUs -notcontains $_.Name }
 
 # Specify output CSV path
 $csvPath = "C:\Users\Public\okta\testmattUsers.csv"
 
 # Check and remove existing CSV to start fresh
 If (Test-Path $csvPath) { Remove-Item $csvPath }
 
 # Loop through each OU and gather user info while excluding certain DistinguishedName patterns
 foreach ($ou in $ouList) {
     Write-Host "`nFinding Users for $ou" -ForegroundColor Cyan
 
 Get-ADUser -Filter * -SearchBase $ou.DistinguishedName -Properties DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged `
            |Where-Object { $_.DistinguishedName -notmatch 'Service Accounts|Super Accounts|Disabled Users'}  `
            | Select-Object DisplayName, samAccountName, company, DistinguishedName, whenCreated, whenChanged `
            | Export-Csv -Path $csvPath -NoTypeInformation -Append   
 
 }
 

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.