Search code examples
powershellactive-directoryselect-object

Using Select-Object and Where-Object in same sentence with PowerShell


I'm new using PowerShell, and I'm trying to select some fields from Active Directory that are like some strings, let me explain:

This is my code so far:

$csv = Import-Csv C:\Users\barreola\Desktop\test_AD.csv

$IS = @(
'*601*',
'*609*',
'*602*',
'*608*',
'*610*',
'*611*',
'*1212*',
'*603*',
'*604*'
)


$csv.Username | ForEach-Object {
    Get-ADUser $_ -Properties Department | Select-Object SamAccountName,Department
}

So far, this retrieves the expected data, as shown below

SamAccountName Department                              
-------------- ----------                              
user1          First floor department (0601)
user2          Second floor department (0609)                   
user3          Second floor department (0609)                   
user4          Second floor department (0609)                   
user5          Third floor department (0604)              
user6          Fourth floor department (0707)      
user7          Fifth floor department (0500)                  
user8          Sixth floor department (1306)   
user9          First floor department (0601)

But I want PowerShell to show me only those contained in $IS, something like

Get-ADUser $_ -Properties Department | Select-Object SamAccountName,Department Where-Object {Department -like $IS}

And the expected output would be

SamAccountName Department                              
-------------- ----------                              
user1          First floor department (0601)
user2          Second floor department (0609)                   
user3          Second floor department (0609)                   
user4          Second floor department (0609)                   
user5          Third floor department (0604)   
user9          First floor department (0601)

NOTE: .csv file contains 700,000+ rows.


Solution

  • Where-Object can do this, but it isn't the best way. The way you're using Get-ADUser will retrieve every user in your domain. That's the part that will take the longest. So you don't want to retrieve any more users than you have to, since that will just waste your time.

    Instead, use the -Filter parameter of Get-ADUser so you only ask AD for the users you want. In your case, you'd need a string like this:

    Department -like *601*' -or Department -like '*609*' -or etc.
    

    You can get a string like that from your array by doing this:

    "Department -like '$($IS -Join "' -or Department -like '")'"
    

    You can read about -Join in the documentation.

    But then you also can't use the -Identity parameter (which is what $_ is being mapped to) at the same time you're using -Filter. So you'll have to include the username (or SamAccountName) in the filter.

    Putting it together, this is what it would look like:

    $csv.Username | ForEach-Object {
        Get-ADUser -Filter "SamAccountName -eq '$_' -and (Department -like '$($IS -Join "' -or Department -like '")')" -Properties Department | Select-Object SamAccountName,Department
    }