#****************************************************************************************
#*
Packages:
*
#*--------------------------------------------------------------------------------------*
#*
None
required
*
#****************************************************************************************
#****************************************************************************************
#*
Definitions:
*
#*--------------------------------------------------------------------------------------*
#*
None
required
*
#****************************************************************************************
#
# Display header
#
print "\nObjSum
V01.00.00pl Joe Richards ([EMAIL PROTECTED]) January
2004\n\n";
#
#
Get args
# ex: Arg1: dc=test,dc=local
# Arg2:
"&(objectcategory=person)(objectclass=user)(useraccountcontrol:AND:=2)"
#
my
$base=shift;
my $filter=shift;
#
#
Process args
# Set defaults if nothing specified -
default NC and all objects
#
if ($base!~/\w/) {$base="-default"} else
{$base="-b $base"};
if ($filter!~/\w/) {$filter="*"};
#
# Build container/OU query and
execute
# We want all OUs and any containers that are
"default",
# i.e. shown in
basic views, this skips adminsdholder et alii.
#
my $cmd="adfind $base
-f \"&(|(objectcategory=organizationalunit)"
.
"(objectcategory=container))(!showInAdvancedViewOnly=TRUE)\" name
"
. "msDS-Approx-Immed-Subordinates -csv -csvdelim %%SPLIT%%
-csvq \"\"";
my @containers=`$cmd`;
shift @containers; # lose the header
line
chomp @containers; # lose crlf
#
#
Print header for CSV
#
print "\"dn\",\"name\",\"Aprox Child Obj
Count\",\"$filter count\"\n";
#
# Quote filter in case it needs to be
#
if
($filter!~/\"/) {$filter="\"$filter\""};
#
# Loop through the containers and
OUs
# break out attribs for
container
# if the object has any objects, then get exact
count for filter
# pull off
number
# output CSV line
#
foreach my
$thiscontainer (@containers)
{
my
($container,$containername,$approxobjs)=split(/%%SPLIT%%/,$thiscontainer);
my $objcount=0;
if ($approxobjs)
{
my $cmd="adfind -bit -b \"$container\" -f $filter -c
2>&1";
($objcount)=((grep(/Objects
returned/,`$cmd`))[0]=~/(\d+)/);
}
print
"\"$container\",\"$containername\",\"$approxobjs\",\"$objcount\"\n";
}
Here are some sample runs so
you can get an understand of the output
All computers in
domain
F:\DEV\Perl\objsum>objsum.pl -default
(objectcategory=computer)
"dn","name","Aprox Child Obj Count","(objectcategory=computer)
count"
"CN=Users,DC=test,DC=loc","Users","23","0"
"CN=Computers,DC=test,DC=loc","Computers","9","9"
"CN=ForeignSecurityPrincipals,DC=test,DC=loc","ForeignSecurityPrincipals","4","0"
"OU=Domain
Controllers,DC=test,DC=loc","Domain
Controllers","2","2"
"OU=Users,OU=My,DC=test,DC=loc","Users","2","0"
"OU=My,DC=test,DC=loc","My","3","0"
"OU=Groups,OU=My,DC=test,DC=loc","Groups","0","0"
"OU=TestOU,DC=test,DC=loc","TestOU","3","0"
"OU=Groups,OU=TestOU,DC=test,DC=loc","Groups","6","0"
"OU=Email,OU=My,DC=test,DC=loc","Email","1","0"
"OU=Users,OU=TestOU,DC=test,DC=loc","Users","10","0"
"OU=Outlook,OU=TestOU,DC=test,DC=loc","Outlook","0","0"
All disabled users in
domain
F:\DEV\Perl\objsum>objsum.pl -default
"&(objectcategory=person)(objectclass=user)(useraccountcontrol:AND:=2)"
"dn","name","Aprox Child Obj
Count","&(objectcategory=person)(objectclass=user)(useraccountcontrol:AND:=2)
count"
"CN=Users,DC=test,DC=loc","Users","23","2"
"CN=Computers,DC=test,DC=loc","Computers","9","0"
"CN=ForeignSecurityPrincipals,DC=test,DC=loc","ForeignSecurityPrincipals","4","0"
"OU=Domain
Controllers,DC=test,DC=loc","Domain
Controllers","2","0"
"OU=Users,OU=My,DC=test,DC=loc","Users","2","0"
"OU=My,DC=test,DC=loc","My","3","0"
"OU=Groups,OU=My,DC=test,DC=loc","Groups","0","0"
"OU=TestOU,DC=test,DC=loc","TestOU","3","1"
"OU=Groups,OU=TestOU,DC=test,DC=loc","Groups","6","0"
"OU=Email,OU=My,DC=test,DC=loc","Email","1","0"
"OU=Users,OU=TestOU,DC=test,DC=loc","Users","10","1"
"OU=Outlook,OU=TestOU,DC=test,DC=loc","Outlook","0","0"
All disabled computers in the computers container (and
any sub containers)
F:\DEV\Perl\objsum>objsum.pl
cn=computers,dc=test,dc=loc
"&(objectcategory=computer)(useraccountcontrol:AND:=2)"
"dn","name","Aprox Child Obj
Count","&(objectcategory=computer)(useraccountcontrol:AND:=2)
count"
"CN=Computers,DC=test,DC=loc","Computers","9","1"
All enabled computers in the computers container (and any
sub containers)
F:\DEV\Perl\objsum>objsum.pl cn=computers,dc=test,dc=loc
"&(objectcategory=computer)(!useraccountcontrol:AND:=2)"
"dn","name","Aprox Child
Obj Count","&(objectcategory=computer)(!useraccountcontrol:AND:=2)
count"
"CN=Computers,DC=test,DC=loc","Computers","9","8"
One
thing I need to specifically point out is the Approx Child Obj Count. This
leverages an attribute that is in Windows Server 2003 AD and ADAM that not
many people are aware of called msDS-Approx-Immed-Subordinates. That is a
constructed attribute that gives you exactly what is says... an
APPROXIMATE number of child objects in the container. This number WILL be off
at times from the actual count. It is to give you rough estimates of how many
objects will be in a container to help clue you in for other queries or when
populating a GUI for instance. If you know you have ~45,000 objects in a
container, there is a good chance you will handle it differently than one with
10 objects. I use it here because I find it to be interesting info and it is
good for not chasing into empty containers. I have never seen it wrong when it
says there are 0 objects.
joe
Joe,
What about adding a "-summary" flag to "oldcmp" so you can
see how many (disabled) PCs you have in any part of the OU tree? Might also be
nice to have an "-onlyactive" rather than "all" or "disabled"... "Managers"
often want "numbers"....
Dave.
What features, etc are you looking for that you would
consider better?
Folks,
I am struggling
with a fairly simple request. We would like a simple report that lists how
many PC's there are in each OU into an Excel Spreadsheet. Well I have managed
to do this with CSVDE and the summary report in Excel. Is there a better (low
cost) solution?
Dave
Wade
E-Services
0161 474
5456
**********************************************************************
This
email and any files transmitted with it are confidential and
intended
solely for the use of the individual or entity to whom they
are addressed.
As a public body, the Council may be required to disclose this email, or any
response to it, under the Freedom of Information Act 2000, unless the
information in it is covered by one of the exemptions in the Act.
If
you receive this email in error please notify Stockport e-Services via
[EMAIL PROTECTED] and then permanently remove it from your system.
Thank
you.
http://www.stockport.gov.uk
**********************************************************************