All references and code samples in this article are based on the Beta version of the .NET Framework released with Visual Studio 2005 Beta 1, and could be changed when the final version is released.
Introduction
In previous versions of the .NET framework, the interaction with Active Directory has been limited to functionality found in the System.DirectoryServices namespace. System.DirectoryServices made it possible to bind to objects in Active Directory and retrieve or change attribute values for the object.In the beta version of the .NET framework 2.0, an additional namespace has been added called ActiveDirectory, that includes all functionality required to manage Active Directory infrastructure components such as:
- Forests
- Domains
- Domain Controllers
- Sites
- Replication
Class mapping
The key classes in the ActiveDirectory namespace are directly related to the hierarchy that an Active Directory infrastructure is made of. Figure 1 shows how classes in the namespace are mapped to components in the Active Directory hierarchy starting at the forest level.
Figure 1: The important classes in the ActiveDirectory namespace
Enumerating Active Directory Information
To retrieve information about your Active Directory infrastructure, you can start from the top and retrieve a Forest object to determine the Active Directory forest in which the domain that the executing computer is located.This function returns a Forest object that can in turn be used to retrieve further information about Domains in the Active Directory Forest.
Private Function _ Getforest() _ As Forest Dim myForest _ As Forest myForest = _ Forest.Current Return myForest End FunctionUsing the forest object, a collection of domains can be retrieved using the function below.
Private Function GetDomains() _ As DomainCollection Dim myDomains As DomainCollection myDomains = Getforest.Domains Return myDomains End FunctionTo continue the enumeration, each domain object in the DomainCollection is used to enumerate domain controllers in the domain. The full code below will list each domain in the forest, and all domain controllers in each enumerated domain.
Imports System.DirectoryServices.ActiveDirectory Module ADmod Public Sub Main() Dim myDomain As Domain Dim myDC As DomainController For Each myDomain In _ GetDomains() Console.WriteLine( _ “=====================”) Console.WriteLine( _ “Domain Controllers in “ & _ myDomain.Name) Console.WriteLine(“”) For Each myDC In _ myDomain.DomainControllers Console.WriteLine( _ myDC.Name) Next Next End Sub Private Function Getforest() _ As Forest Dim myForest As Forest myForest = Forest.Current Return myForest End Function Private Function GetDomains() _ As DomainCollection Dim myDomains As _ DomainCollection myDomains = Getforest.Domains Return myDomains End Function End Module
Managing FSMO Roles
There are two different ways to discover information about FSMO roles in your Forest and Domains. You can bind to a specific domain controller and query it for a collection of roles currently held (if any), or you can query a Domain or Forest object specifically about which Domain Controller each role is hosted on.This snippet will bind to a domain controller and enumerate roles in the ActiveDirectoryRoles collection. Notice the DirectoryContext.Open method is used to instantiate the DomainController object when it is not retrieved from a Domain object.
Private Sub EnumDCRoles(DCName _ As String) Dim myDC As DomainController Dim myRole As ActiveDirectoryRole myDC =DomainController.GetObject( _ DirectoryContext.Open(DCName) For Each myRole In myDC.Roles Console.WriteLine( _ myRole.ToString) Next End SubTo retrieve FSMO information from a Domain or Forest, you need to specifically query for each role individually. This snippet binds to a domain and lists the server names that hold each domain wide FSMO role.
Private Sub EnumDomainRoles( _ DomainName as String) Dim myDomain As Domain myDomain Domain.GetObject( _ DirectoryContext.open( _ DomainName)) Console.WriteLine( _ “Operation master roles in “ &_ DomainName) Console.WriteLine(“”) Console.WriteLine( _ “PDC Emulator: “ & _ myDomain.PdcRoleOwner.Name) Console.WriteLine( _ “Infrastructure Manager: “ & _ myDomain.InfrastructureRoleOwner.Name) Console.WriteLine(“Rid Master: “ &_ myDomain.RidRoleOwner.Name) End Sub
Transferring FSMO Roles
FSMO roles can be either seized or relocated to another server. The difference between seizing a role and transferring it is that when transferring a role, the domain controller that currently holds the role is still online. The methods of the DomainController object available for these operations are SeizeRoleOwnership and TransferRoleOwnership. Both methods require Integers as an input parameter that are defined in the ActiveDirectoryRole enumeration, as detailed in Table 1.Table 1System.DirectoryServices.ActiveDirectory.ActiveDirectoryRole |
|
SchemaRole | 0 |
NamingRole | 1 |
PdcRole | 2 |
RidRole | 3 |
InfrastructureRole | 4 |
Consider the following snippet to transfer roles to an alternative Domain Controller:
Private Sub TransferRole( ByVal RoleToTransfer As _ ActiveDirectoryRole, _ ByVal DCTargetName As String) Dim myDC As DomainController myDC = DomainController.GetObject(_ DirectoryContext.Open( _ DCTargetName)) myDC.TransferRoleOwnership( _ RoleToTransfer) End Sub
Managing Active Directory Sites and Subnets – Retrieving Site and Subnet information
The namespace contains a full set of classes that can be used to manage forest-wide components such as Sites, Subnets and Site Links that are used to define replication boundaries. Since Sites are Fforest-wide, all sites can be enumerated by retrieving a collection of site objects from the Forest.Sites property. Each Site object in turn has a Subnets property that contains a collection of subnets that are assigned to a site. This code snippet will list all sites in a Forest and display what subnets are assigned to each site.Private Sub ListSites() Dim myForest As Forest Dim mySites As _ ReadOnlySiteCollection Dim mySubnets As _ ActiveDirectorySubnetCollection Dim iEnumSites, iEnumSubnets _ As Integer myForest = Forest.Current mySites = myForest.Sites For iEnumSites = 0 To _ mySites.Count -1 Console.WriteLine(mySites( _ iEnumSites).Name) Console.WriteLine( _ “***Assigned Subnets***”) mySubnets = _ mySites(iEnumSites).Subnets For iEnumSubnets = 0 To_ mySubnets.Count – 1 Console.WriteLine( _ mySubnets( _ iEnumSubnets).Name) Next Next End Sub
Creating new Sites and Subnets
A new Site is created by instantiating a new ActiveDirectorySite object. The constructor requires the DirectoryContext as a parameter to determine the Forest in which to create the site and the credentials to use to access Active Directory. By default the current domain and the logged-on user’s credentials are used. A string value is also required for the name of the new site. After the object has been instantiated, options can be configured and Subnets assigned to the Site. To complete the operation the save method must be called to commit the changes.Private Sub CreateSite( _ ByVal Sitename as String) Dim mySite As ActiveDirectorySite mySite = New ActiveDirectorySite( _ DirectoryContext.Open(), _ “MyNewSite”) mySite.Options = _ ActiveDirectorySiteOptions. _ TopologyCleanupDisabled mySite.Save() End subSubnets are created in a similar way to sites. One difference is that the Subnet constructor contains an overloaded method which gives an option to assign the subnet to a site upon creation.
Dim mySubnet = _ New ActiveDirectorySubnet( _ DirectoryContext.Open(), _ “192.168.1.0/24”, “MyNewSite”)
Managing Replication
Extensive possibilities are available to manage replication of Active Directory partitions, such as:- Retrieving information about pending operations
- Initiate replication from a replication neighbor, any specific Domain Controller, or all Domain Controllers
- Retrieving information about the replication topology
This example shows how replication of the configuration partition is initiated:
Private Sub replicate(_ ByVal SourceDC As String, _ ByVal DestDC As String) Dim myDC As DomainController myDC = DomainController.GetObject(_ DirectoryContext.Open(SourceDC)) myDC.SyncReplicaFromServer( _ “CN=Configuration,DC=Fabrikam,DC=Com”,_ DestDC) End Sub
Comments