Inventory computers by OS

Hi -

I’m using PowerShell v. 4.0 to try to inventory computers in some child OU’s by the Operating system and I’m getting inconsistent results. Here’s the code I’m using:

$ous = Get-ADOrganizationalUnit -Filter {name -like "*"} -SearchBase "" -SearchScope OneLevel
Foreach($ou in $ous){
$ouname = $
$dn = $ou.DistinguishedName
$windows2000 = (Get-ADComputer -LDAPFilter '(&(objectCAtegory=computer)(operatingsystem="*2000*"))' -SearchBase $dn -SearchScope Subtree).count
$Windows2003 = (Get-ADComputer -LDAPFilter '(&(objectCAtegory=computer)(operatingsystem="*2003*"))' -SearchBase $dn -SearchScope Subtree).count
$windows2008 = (Get-ADComputer -LDAPFilter '(&(objectCAtegory=computer)(operatingsystem="*2008*"))' -SearchBase $dn -SearchScope Subtree).count
$windows2012 = (Get-ADComputer -LDAPFilter '(&(objectCAtegory=computer)(operatingsystem="*2012*"))' -SearchBase $dn -SearchScope Subtree).count
$windows2016 = (Get-ADComputer -LDAPFilter '(&(objectCAtegory=computer)(operatingsystem="*2016*"))' -SearchBase $dn -SearchScope Subtree).count

The problem, for example, is that I get “0” Windows 2008 machines for a given OU in the csv file, but I use an LDAP browser with the same LDAP filter and it finds several machines. I’ve tried modifying the filter by putting in the EXACT operating system name (like “Windows Server 2012 R2 Standard”), but it still doesn’t work.

In other cases, I get a strange output message in the .csv: “Microsoft.ActiveDirectory.Management.ADPropertyValueCollection”. Research indicates that is an indication of a multi-valued attribute. Is that because there are multiple flavors of a given OS (Standard vs. Enterprise vs. DataCenter)? I would think putting in “**” in the filter would resolve that.

I don’t really want to use WMI for this, since I don’t need to get that far down in the weeds. I just want to pull the OS attribute from the computer object in AD and have it work consistently.

Any advice or assistance would be appreciated.

Thank you


get-adcomputer -filter * -Properties OperatingSystem | where operatingsystem -like "*2012*"

eta: if you want count, pipe the output to “measure”

get-adcomputer -filter * -Properties OperatingSystem | where operatingsystem -like "*2012*" | measure

Wouldn’t this be a better option?

Get-AdComputer -Filter {OperatingSystem -like "*2012*"}

This will only pull back the required computers, whereas using Filter * will pull back and pipe all computers to Where-Object.

Yes it is!

John/Ian - Thanks for the input. I tried it again, using the following code, per your suggestions:

$windows2012 = (Get-AdComputer -Filter {OperatingSystem -like "*2012*"} -SearchBase $dn -SearchScope Subtree).count

I found that it works, except in cases when only 1 object is found that meets the search filter. If it finds 0 or 2 or more objects it works, but not if it finds 1. If it finds 1, then I get the “Microsoft.ActiveDirectory.Management.ADPropertyValueCollection” output.

Any ideas?

When you find only one object, you get the object and not an array of objects. Try $windows2012.gettype() and you´ll see that the object types are different. I suggest you use Measure-Object to get the count.

$windows2012 = (Get-AdComputer -Filter {OperatingSystem -like "*2012*"} -SearchBase $dn -SearchScope Subtree | Measure-Object).count

Thanks, Erik. That seems to have done the trick. Strange though, that it wouldn’t treat a single result as an array with one element.

It is supposed to work that way. :slight_smile: If you do a query to get a single object, you want the object, not an array.

If you really want an array you could do this instead:

$windows2012 = @() #create empty array
$windows2012 += Get-AdComputer -Filter {OperatingSystem -like "*2012*"} -SearchBase $dn -SearchScope Subtree #adding to array

Always hate to miss some information when you are trying to do something like this.
Try this:

get-adcomputer -filter * -Properties OperatingSystem|Group-Object -Property OperatingSystem