26.7 Querying AD with WMI
Up to now, we've shown how
WMI can be a powerful resource to aid in
managing components of individual computers. You may be wondering
what impact WMI will have on Active Directory? It can, in fact, play
as big a role in automating the management of Active Directory as you
want. Also, over time, WMI's importance with respect
to monitoring Active Directory will continue to grow as Microsoft
develops new providers.
First we are going to review how you can use WMI and the Active
Directory provider to access and query objects in Active Directory.
We will then cover some specific WMI providers that Microsoft has
made available in Windows Server 2003; these providers help you
monitor certain aspects of Active Directory, such as trusts and
replication. In the next chapter, we will cover the WMI DNS provider
and how you can manage Microsoft DNS servers with it. To start with,
let's look at the Active Directory provider.
The Active Directory provider uses the root\directory\ldap namespace.
Within that namespace, every Active Directory schema class and
attribute is mapped to corresponding WMI classes or properties. Each
abstract class (e.g., top) is mapped to a WMI
class with "ds_" prefixed on the
name. Each nonabstract class (e.g., structural and auxiliary) is
mapped to two classes. One has
"ads_" prefixed, and the other has
"ds_" prefixed. The
"ads_" classes conform to the class
hierarchy defined by the subClassOf attribute for
each class. The "ds_" classes for
nonabstract (e.g., structural) classes are descendants of their
cooresponding "ads_" class. Perhaps
an example would help illustrate this hierarchy:
ds_top
ads_person
ads_organizationalperson
ads_user
ads_computer
ds_computer
In this example, we showed the class hierarchy for the Active
Directory "computer" object class
as it is mapped to WMI. The attribute mappings are more
straightforward. Each Active Directory attribute has a corresponding
property in WMI with "ds_"
prefixed. So the description attribute would map
to the ds_description property in WMI. An
additional property was added called ADSIPath,
which is the ADsPath, and is the key for each
Active Directory object in WMI. We highly recommend installing and
using the WMI CIM Studio to browse the root\directory\ldap namespace.
The organization of classes and objects will become apparent.
We can use the techniques shown so far to query and manipulate Active
Directory objects. We can retrieve all the instances of a particular
Active Directory class (via InstancesOf) or
perform WQL query based on certain criteria. In the following
example, we search for all user objects that have a last name equal
to "Allen".
strComputer = "."
Set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\directory\LDAP")
Set objUsers = objWMI.ExecQuery("SELECT * FROM ds_user where ds_sn = 'Allen' ")
if objUsers.Count = 0 then
Wscript.Echo "No matching objects found"
else
for each objUser in objUsers
WScript.Echo "First Name: " & objUser.ds_givenName
WScript.Echo "Last Name: " & objUser.ds_sn
WScript.Echo ""
next
end if
Since WMI is typically used to manage computers, we can leverage
Active Directory as a repository of computer objects and perform
certain functions on a set of computers that match our criteria. In
the next code sample, we do a WQL query for all computers that are
running "Windows Server 2003",
connect to each one, and print the date each machine was last
rebooted.
on error resume next
strComputer = "."
Set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\directory\LDAP")
Set objComps = objWMI.ExecQuery("SELECT * FROM ds_computer " & _
"where ds_OperatingSystem = 'Windows Server 2003' ")
if objComps.Count = 0 then
Wscript.Echo "No matching objects found"
else
for each objComp in objComps
WScript.Echo objComp.ds_name
Set objRemoteWMI = GetObject("winmgmts:\\" & objComp.ds_name & "\root\cimv2")
if Err <> 0 then
WScript.Echo " Could not connect"
Err.Clear
else
' Perform whatever functions necessary on objRemoteWMI
Set objOSes = objRemoteWMI.InstancesOf("Win32_OperatingSystem")
for each objOS in objOSes
strTime = objOS.LastBootUpTime
strYear = Left(strTime, 4)
strMon = Mid(strTime, 5, 2)
strDay = Mid(strTime, 7, 2)
WScript.Echo " Last Reboot: " & strYear & "/" & strMon & "/" & strDay
next
end if
WScript.Echo ""
Set objRemoteWMI = Nothing
next
end if
In the code, we retrieve each matching computer object and then
construct a WMI moniker to connect to that machine. From there, we
enumerate the Win32_OperatingSystem object and
print out the LastBootUpTime property. Note that
we could perform essentially any function we want, including querying
disks and the event log, modifying the registry, and so on. Also, we
could instantiate a
WbemScripting.SWbemLocator
object if we need to log on to the computers with alternate
credentials other than those the script is running under.
|