Powershell - Filtering OUs while using get-adcomputer
Asked Answered
W

2

6

I am trying to create a script that generates a list of computers based on specific properties which a computer may have. For example, I am trying to make a list of Windows XP computers and Windows 7 computers, throw their names in a .csv file and outputting the final count of each.

Here is my code so far

import-module ActiveDirectory
$computers = get-adcomputer -Filter 'ObjectClass -eq "Computer"' -properties "OperatingSystem"
$i = 0
$j = 0
Foreach ($computer in $computers) {
    if ($computer.operatingSystem -like "Windows 7*") {
        $i++
        '"{0}","{1}","{2}"' -f $computer.Name, $computer.OperatingSystem, "$computer.DistinguishedName" | Out-file -append C:\users\admin\desktop\test.txt
        }
    elseif ($computer.OperatingSystem -like "Windows XP*") {
        $j++
        '"{0}","{1}","{2}"' -f $computer.Name, $computer.OperatingSystem, "$computer.DistinguishedName" | Out-file -append C:\users\admin\desktop\test.txt
        }
    else {
        $_
        }

}
write-host "$i Win 7"
write-host "$j Win xp"
$k = $i+$j
write-host "$k Total"

Sample Output:

104 Win 7
86 Win xp
190 Total

This script works however I would like to make it a bit better by being able to say which OU's not to look into, but I can't quite figure it out.

If anyone has any insight into how to do this, or even just to make the above code any better I would love to hear it.

Thank you!

Windowshop answered 17/7, 2012 at 22:23 Comment(0)
S
10

The -like operator doesn't seem to work with wildcards for DistinguishedName. So the obvious operation Get-ADComputer -Filter {(DistinguishedName -notlike "*OU=evil,*")} doesn't work.

The easiest workaround is to get all the computers in a colleciton and filter it afterwards to suit your needs. Like so,

# All the computers from the evil OU:
$evilOU = $computers| ? {$_.DistinguishedName -like "*ou=evil,*"}
# All the computers but the ones from the evil OU:
$goodOU = $computers| ? {$_.DistinguishedName -notlike "*ou=evil,*"}

Addendum

To combine matching rules, use -and -or and -like. Remember to use * wildcard with ? (where-object)

# All the computers save the ones from evil and wicked OU:
$goodOU = $computers| ? {
  $_.DistinguishedName -notlike "*ou=evil,*" -and $_.DistinguishedName -notlike "*ou=wicked,*"

}

Semen answered 18/7, 2012 at 7:25 Comment(2)
Can I add more than one string using the -or operator? $goodOU = $computers| ? {$_.DistinguishedName -notlike ("ou=evil," -or "CN=BadCN,")}. this isn't the correct syntax thoughWindowshop
looking at examples, and trying this doesn't work either. $filteredComputers = $computers | where-object {($_.DistinguishedName -notlike "OU=Laptops,") -or ($_.DistinguishedName -notlike "*CN=Resources,*") -or ($_.DistinguishedName -notlike "CN=Computers,")}Windowshop
L
2

while there's nothing wrong with filtering after you've collected all the computers, a more efficient manner of restricting your data to one OU would be to use the -searchbase switch in your GET-ADCOMPUTER cmdlt. I also noticed you're filtering your object type to specify computer, which is a little redundant as the get-adcomputer cmdlt already filters out other object types.

i've taken your code and fixed it up a bit.

import-module ActiveDirectory
$computers = get-adcomputer -Filter * -properties "OperatingSystem" -SearchBase "OU=evil,OU=workstations,DC=cs,DC=domain,DC=net"
$i = 0
$j = 0
Foreach ($computer in $computers) {
    if ($computer.operatingSystem -like "Windows 7*") {
        $i++
        '"{0}","{1}","{2}"' -f $computer.Name, $computer.OperatingSystem, "$($computer.DistinguishedName)" | Out-file -append C:\users\admin\desktop\test.txt
        }
    elseif ($computer.OperatingSystem -like "Windows XP*") {
        $j++
        '"{0}","{1}","{2}"' -f $computer.Name, $computer.OperatingSystem, "$($computer.DistinguishedName)" | Out-file -append C:\users\admin\desktop\test.txt
        }
    else {
        $_
        }

}
write-host "$i Win 7"
write-host "$j Win xp"
$k = $i+$j
write-host "$k Total"

The above above example should function the same as your previous scrip save that it will enumerate all the computers with either windows 7 or xp that are within the evil OU. which is located within the workstations OU on the ds.Domain.Net domain.

You've probably also noticed that your distinguished name is getting ".DistinguishedName" appended to the end of each column, this is because your $computer.DistinguishedName expression isn't being fully evaluated while it's in quotations, easily resolved with the following change:

"$computer.DistinguishedName"

to

"$($computer.DistinguishedName)"

the "$(<...>)" syntax tells powershell to evaluate the full expression within brackets before converting the output to string.

Licking answered 9/1, 2014 at 21:15 Comment(1)
Some good points here. However, unfortunately, the original question wants to omit one or a few OUs and include a majority. I believe searchbase would generally not help unless, as you say, your scenario allows you to focus in on just one OU subtree.Push

© 2022 - 2024 — McMap. All rights reserved.