Per the subject line ... hope it proves as useful to some of you as it has been to me this week.  As always, please verify its successful execution in a lab before use in a production environment.
 
Thanks to Laura Hunter for guinea-pigging it for me!
 
Kindest regards.
 
Dean

--
Dean Wells
MSEtechnology
* Email: [EMAIL PROTECTED]

http://msetechnology.com

 
:: Active Directory Object Counter - Dean Wells / MSEtechnology / Sept. 2005

:: Provides count and breakdown of objects and their class type within the 
supplied partition
:: - additional LDIFDE command line arguments [such as providing credentials] 
can be supplied by 
::   pre-populating the environment variable "LDIFargs" with the desired syntax.

:: See script help for further details

@echo off

:: Define initial environment
set STDOUT=nul
set STDERR=nul
set TITLESTRING=Active Directory Object Counter
set TOGGLE=0
set FQDN=
set LOGDIR=%TEMP%\
set PARTCLASS=?
set PARTTYPE=?

if "%1"=="" goto :HELP
if "%1"=="/?" goto :HELP

setlocal ENABLEDELAYEDEXPANSION

:: Locate critical executables
for %%e in (ldifde.exe find.exe) do (
        set where="%%~$PATH:e"
        if "!where!"=="""" (
                echo ERROR - Required executable, "%%e", not located within the 
path
                goto :END
        )
)

:: Prepare display and window title
echo/
echo STATUS - Working ...
echo/

title %TITLESTRING%

:: Determine verbosity requirements and if a DN or FQDN was supplied
set DNSorDN=%*
set VERBOSE=%*
set DNSorDN=%DNSorDN: -V=%
set DNSorDN=%DNSorDN: /v=%
set DNSorDN=%DNSorDN: -V=%
set DNSorDN=%DNSorDN: -v=%

if not "%VERBOSE%"=="%DNSorDN%" set VERBOSE=1

set ROOT=%DNSorDN:,=%

if not "%ROOT%"=="%DNSorDN%" (
        set ROOT=%DNSorDN%
        call :STRIPDN %DNSorDN%
        if "!TOGGLE!"=="-1" (
                echo ERROR - Unknown syntax supplied
                goto :HELP
        )
) else (
        set ROOT=dc=%DNSorDN:.=,dc=%
        set FQDN=%DNSorDN%
        set LOGDIR=%LOGDIR%!FQDN!
)

:: Define or modify remaining environment
set CNT=0
set ICTMP=
set LOGFILE="%LOGDIR%\objcount.log"
set TMPFILE="%LOGDIR%\objcount.$$$"
set SERVER=
set TMPSYNTAX=

:: Create %LOGDIR% directory
if not exist "%LOGDIR%" (
        md "%LOGDIR%" 2>%STDERR%
        if errorlevel 1 (
                echo ERROR - Log directory could NOT be created
                echo/
                echo         "%LOGDIR%"
                goto :END
        )
)

:: Construct human-readable time
set DTIME=%TIME% & set DTIME=!DTIME:~0,8!

:: Display operational data
echo   * Running on computer  : %COMPUTERNAME%

:: Determine if -s [server to query against] was supplied by LDIFargs, if so, 
don't use %FQDN%
if not "%LDIFargs%"=="" (
        set TMPSYNTAX=%LDIFargs:-s=%
        set TMPSYNTAX=!TMPSYNTAX:-S=!
)

if "%TMPSYNTAX%"=="%LDIFargs%" (
        echo   * DSAs resolved using  : %FQDN%
        set SERVER=-s %FQDN%
) else (
        echo   * DSAs resolved using  : see optional LDIF args. below
)

:: Continue displaying operational data
echo   * Base DN of query is  : %ROOT%
echo   * Command submitted at : %DTIME% on %DATE%
if not "%LDIFargs%"=="" (
        echo   * Optional LDIF args.  : %LDIFargs%
)
echo/

:: Construct LDAP query for all objects
echo     - submitting LDAP query
set LDIFSYNTAX=ldifde -j "%LOGDIR%" %SERVER% -d %ROOT% -r objectclass=* -l 
objectclass -f %LOGFILE% %LDIFargs%

:: Submit LDAP query for all objects
%LDIFSYNTAX% >%STDOUT%

:: If LDFIDE returned an error, delete %LOGFILE% such that the following error 
check is triggered
if errorlevel 1 (
        del %LOGFILE% 2>%STDERR%
)

if not exist %LOGFILE% (
        echo/
        echo ERROR - LDAP query failed enumerating objects
        echo/
        echo   %LDIFSYNTAX%
        goto :HELP
)

:: Construct and submit LDAP query to determine partition type
set /p =    - partition type: <nul
ldifde -j "%LOGDIR%" %SERVER% -d %ROOT% -r objectclass=* -l 
objectclass,instanceType,fSMORoleOwner -p base -f %TMPFILE% %LDIFargs% >%STDOUT%

:: Parse query result
for /f "tokens=1,2 usebackq" %%t in (%TMPFILE%) do (
        if /i "%%t"=="objectclass:" (
                set PARTCLASS=%%u
        ) else (
                if /i "%%t"=="instanceType:" (
                        set PARTTYPE=%%u
                )
        )
)

:: Display partition detail
if "%PARTTYPE%"=="13" (
        if /i "%PARTCLASS%"=="dmd" (
                echo Schema
        ) else (
                if /i "%PARTCLASS%"=="configuration" (
                        echo Configuration
                ) else (
                        if /i "%PARTCLASS%"=="domainDNS" (
                                echo Application [NDNC]
                        ) else (
                                echo UNKNOWN 
[class=%PARTCLASS%/instanceType=%PARTTYPE%]
                        )
                )
        )
) else (
        if "%PARTTYPE%"=="5" (
                if /i "%PARTCLASS%"=="domainDNS" (
                                echo Domain or ADAM NDNC
                ) else (
                        echo UNKNOWN [class=%PARTCLASS%/instanceType=%PARTTYPE%]
                )
        ) else (
                echo UNKNOWN [class=%PARTCLASS%/instanceType=%PARTTYPE%]
        )
)

:: Count total objects
for /f %%c in ('type %LOGFILE% ^| find /i /c "dn:"') do (
        set /p =    - total number of objects: <nul
        set OBJTOT=%%c
)

:: Determine if LDIFDE failed to locate the supplied partition
echo %OBJTOT%
        
if "%OBJTOT%"=="0" (
        echo/
        echo ERROR - LDAP query incomplete; object count too low
        goto :END
)

:: If high verbosity was not requested [/v], skip to summary
if not "%VERBOSE%"=="1" goto :SKIPINSTCNT

:: Append footer to %LOGFILE% in order to ensure instance count function below 
includes the last object
echo dn: 
This_line_was_appended_to_ensure_last_object_found_is_included_by_the_instance_count_function>>%LOGFILE%

:: Count the number of instances of each class [filter LDIF changetype: entries 
from log file]
echo     - calculating number of instances per class [-V]
for /f "tokens=1,2 usebackq" %%n in (%LOGFILE%) do (
        if /i not "%%n"=="changetype:" (
                if /i not "%%n"=="dn:" (
                        set ICTMP=%%o
                ) else (
                        if not "!ICTMP!"=="" (
                                set /a CNT+=1
                                title %TITLESTRING% - !CNT! of %OBJTOT% ...
                                call set /a [$IC$]!ICTMP!+=1 2>%STDERR%
                                if errorlevel 1 (
                                        set ICFIX=!ICTMP!
                                        set ICFIX=!ICFIX:-=#$#!
                                        call set /a [$IC$]!!ICFIX!!+=1
                                )
                        )
                )
        )
)

:: Ensure temporary file used below is empty
del %TMPFILE% 2>%STDERR%

:: Construct instance count temporary file
for /f "tokens=1,2 delims==" %%e in ('set [$IC$] 2^>%STDOUT%') do (
        if "!INSTSTR!"=="" (
                echo/
                echo STATUS - The following classes were found -
                echo/
        )
        set INSTSTR=%%e
        set INSTSTR=!INSTSTR:#$#=-!
        set INSTSTR=!INSTSTR:[$IC$]=!
        set INSTCNT=         %%f
        set INSTCNT=!INSTCNT:~-10!
        echo !INSTCNT! !INSTSTR!>>%TMPFILE%
)

:: Display sorted instance count
for /f "tokens=1,2" %%s in ('sort /r %TMPFILE%') do (
        set INSTSTR=%%t
        set INSTSTR=!INSTSTR! ....................................
        set INSTSTR=!INSTSTR:~0,37! %%s
        echo     !INSTSTR!
)

:: Display total object count
echo/
echo   TOTAL ................................. %CNT% objects

:SKIPINSTCNT

echo/

:: Construct human-readable time
set DTIME=%TIME% & set DTIME=!DTIME:~0,8!

:: Script body ends
echo Completed successfully at %DTIME% on %DATE%
goto :END

:: Define functions/subroutines

:: Convert DN to FQDN
:STRIPDN
if not "%1"=="" (
        if "!TOGGLE!"=="0" (
                set TYPE=%1
                set TOGGLE=1
        ) else (
                if /i "!type!"=="cn" (
                        set LOGDIR=!LOGDIR!%1.
                        set TOGGLE=0
                ) else (
                        if /i "!type!"=="dc" (
                                set LOGDIR=!LOGDIR!%1.
                                set FQDN=!FQDN!%1.
                                set TOGGLE=0
                        ) else (
                                set TOGGLE=-1
                                goto :EOF
                        )
                )
        )
        shift
        goto :STRIPDN
)
set FQDN=%FQDN:~0,-1%
set LOGDIR=%LOGDIR:~0,-1%
goto :EOF

:HELP
echo/
echo SYNTAX - %0 ^<Partition FQDN or DN^> [-V]
echo/
echo          [-V] optional, displays per-class object count
echo/
echo          Additional LDIFDE command line arguments [such as providing 
echo          alternate credentials] can be supplied by pre-populating the 
echo          environment variable "LDIFargs" with the desired syntax.
echo/
echo          e.g. set LDIFargs=-b Administrator MSET MyPassw0rd
echo               set LDIFargs=-s cubelet.msetechnology.com

goto :END

:END
title Command Prompt
if not "%FQDN%"=="" if exist "%LOGDIR%" (
        del "%TMPFILE%" "%LOGFILE%" "%LOGDIR%\ldif.err" "%LOGDIR%\ldif.log" /f 
/q 2>%STDERR%
        rd "%LOGDIR%" 2>%STDERR%
)

Reply via email to