Imports LzmTW.DirectoryServices ''' <summary> ''' ldapPath专为简化AD域组织单元、用户、计算机、网络打印机的节点管理而设计。 ''' 对于一个确定的域,ldapPath仅仅关心关键标识部分,即(CN|OU=...)集合。 ''' 在容器中管理各个节点以及在导入导出节点集合时,ldapPath简洁明了。 ''' 此为示例。示例后贴出主要代码,全部代码计划以资源下载提供。 ''' ''' 仅供参考。水如烟(http://www.cnblogs.com/LzmTW,http://blog.csdn.net/lzmtw) ''' 20090309 ''' </summary> Public Class LdapPathDemo Public Sub Test1() Dim ldap As New ldapPath("www.csdn.net",True) '包含主机 Console.WriteLine(ldap.ShortDomainController) '域csdn.net的主机 'www '或 ldap = New ldapPath("csdn.net",False) '不含主机 ldap.ShortDomainController = "www" '置主机 ldap.Path = "CN=水如烟,OU=VB,OU=NET,OU=CSDN用户" Console.WriteLine(ldap.Path) '当前节点路径 'LDAP://www.csdn.net/CN=水如烟,OU=CSDN用户,DC=csdn,DC=net ldap.Name = "lzmtw" '更改当前节点名 Console.WriteLine(ldap.Path(ldapType.IncludeDomainName)) '不含主机的节点路径 'LDAP://csdn.net/CN=lzmtw,DC=net ldap.ParentDistinguishedName = "OU=C#,OU=CSDN用户" '更改容器路径 Console.WriteLine(ldap.Path(ldapType.OnlyLocation)) '只含关键标识部分的节点路径 'LDAP://CN=lzmtw,OU=C#,DC=net ldap = ldap.Parent.Parent.Parent '第三级容器实例 Console.WriteLine(ldap.Path) 'LDAP://www.csdn.net/OU=CSDN用户,DC=net Console.WriteLine(ldap.IsRoot) '是否为根 'False ldap = ldap.Parent '再上一级 Console.WriteLine(ldap.Path) 'LDAP://www.csdn.net/DC=csdn,DC=net Console.WriteLine(ldap.IsRoot) '是否为根 'True End Sub Public Sub Test2() '节点关键标识在不同域中的传递 Dim ldapForDomain1 As New ldapPath("www.csdn.net") ldapForDomain1.Path = "CN=水如烟,OU=CSDN用户" 'ldapForDomain1 .Path 为LDAP://www.csdn.net/CN=水如烟,DC=net Dim ldapForOther As New ldapPath("www.cnblogs.com") ldapForOther.Path = ldapForDomain1.Path Console.WriteLine(ldapForOther.Path) 'LDAP://www.cnblogs.com/CN=水如烟,DC=cnblogs,DC=com '或 ldapForOther.Path = ldapForDomain1.ShortDistinguishedName Console.WriteLine(ldapForOther.Path) '同上 '只用关心关键标识 Console.WriteLine(ldapForOther.ShortDistinguishedName) 'CN=水如烟,OU=CSDN用户 '最后更改主机 ldapForOther.ShortDomainController = "mmm" Console.WriteLine(ldapForOther.Path) 'LDAP://mmm.cnblogs.com/CN=水如烟,DC=com End Sub End Class
主要代码:
''' <summary> ''' Path表示方式 ''' </summary> ''' <remarks></remarks> Public Enum ldapType ''' <summary> ''' 仅路径,如LDAP://CN=水如烟,DC=domain,DC=local ''' </summary> OnlyLocation ''' <summary> ''' 含域,如LDAP://domain.local/CN=水如烟,DC=local ''' </summary> ''' <remarks></remarks> IncludeDomainName ''' <summary> ''' 全部(含域主机),如LDAP://server.domain.local/CN=水如烟,DC=local ''' </summary> All End Enum
Public Class ldapPath Implements IDisposable ''' <summary> ''' 当前实例路径更改事件。 ''' </summary> Public Event PathChanged() Private gShortDomainController As String = Nothing Private DC As New UnitsForDC Private CNOU As New UnitsForCNOU ''' <param name="domainName">域名或域主机全名,如domain.local或server.domain.local。</param> ''' <param name="hasServer">domainName中是否包含主机。</param> ''' <remarks></remarks> Public Sub New(ByVal domainName As String,Optional ByVal hasServer As Boolean = True) If hasServer Then Dim express As String = Me.GetDomainServerAddress(domainName) If Not String.IsNullOrEmpty(express) Then Me.DC.DomainName = express.Substring(express.IndexOf(".") + 1) Me.ShortDomainController = express End If Else DC.DomainName = domainName End If Me.OnPathChanged() End Sub ''' <summary> ''' 获取当前实例的域名。 ''' </summary> Public ReadOnly Property DomainName() As String Get Return Me.DC.DomainName End Get End Property ''' <summary> ''' 获取或设置当前实例的域控制器(主机)简称,若全称为server.domain.local则此值为server。 ''' </summary> ''' <remarks>若当前域名为空,则设置无效。</remarks> Public Property ShortDomainController() As String Get Return gShortDomainController End Get Set(ByVal value As String) If String.IsNullOrEmpty(Me.DomainName) Then gShortDomainController = Nothing Return End If If value Is Nothing Then gShortDomainController = Nothing Else value = value.Trim If value.IndexOf(".") = -1 Then gShortDomainController = value Else gShortDomainController = value.Substring(0,value.IndexOf(".")) End If End If End Set End Property ''' <summary> ''' 获取或设置当前节点名称。若节点路径为"LDAP://CN=水如烟,DC=local",则此值为"水如烟"。 ''' </summary> ''' <remarks>若当前节点为空,则设置无效,因为无法预知是CN还是OU。</remarks> Public Property Name() As String Get Return Me.CNOU.Name End Get Set(ByVal value As String) Me.CNOU.Name = value End Set End Property ''' <summary> ''' 获取当前节点全称。若节点路径为"LDAP://CN=水如烟,DC=local",则此值为"CN=水如烟"。 ''' </summary> ''' <remarks>在容器中新增节点时,需以此形式表示节点名。</remarks> Public ReadOnly Property NameForLdap() As String Get Return Me.CNOU.NameForLdap End Get End Property ''' <summary> ''' 获取当前节点路径关键识别名。若节点路径为"LDAP://CN=水如烟,DC=local",则此值为"CN=水如烟,OU=CSDN用户"。 ''' </summary> Public ReadOnly Property ShortDistinguishedName() As String Get Return Me.CNOU.Express End Get End Property ''' <summary> ''' 获取或设置当前节点所在容器路径识别名。若节点路径为"LDAP://CN=水如烟,DC=local",则此值为"OU=VB,DC=local"。 ''' </summary> ''' <remarks>若当前节点为空,则设置无效。</remarks> Public Property ParentDistinguishedName() As String Get Return Me.GetDistinguishedName(1) End Get Set(ByVal value As String) Me.CNOU.Parent = value End Set End Property ''' <summary> ''' 获取当前节点所在容器路径的ldapPath实例。 ''' </summary> Public ReadOnly Property Parent() As ldapPath Get Dim ldpa As ldapPath = Me.Clone ldpa.Path = Me.ParentDistinguishedName Return ldpa End Get End Property ''' <summary> ''' 获取一个值,表示当前节点是否为根节点。若节点路径为"LDAP://DC=domain,DC=local",则此值为True,否则为False。 ''' </summary> Public ReadOnly Property IsRoot() As Boolean Get Return Me.CNOU.Count = 0 End Get End Property ''' <summary> ''' 获取或设置当前节点路径,如"LDAP://server.domain.local/CN=水如烟,DC=local"。若当前域名为空,仅返回"LDAP://"。 ''' </summary> Public Property Path() As String Get Return Me.Path(ldapType.All) End Get Set(ByVal value As String) Me.CNOU.Load(value) Me.OnPathChanged() End Set End Property ''' <summary> ''' 获取当前节点与指定级次容器相符的路径。若当前域名为空,仅返回"LDAP://"。 ''' </summary> ''' <param name="ldapType">Path表示方式</param> ''' <param name="index">容器级次。0表示自称,1表示父级,2表示父级的父级,以此类推。</param> ''' <remarks ></remarks> Public ReadOnly Property Path(ByVal ldapType As ldapType,Optional ByVal index As Integer = 0) As String Get Return Me.GetPath(ldapType,index) End Get End Property ''' <summary> ''' 获取当前节点与指定级次容器相符的路径识别名。 ''' </summary> ''' <param name="index">容器级次。0表示自称,1表示父级,2表示父级的父级,以此类推。</param> ''' <remarks>若节点路径为"LDAP://CN=水如烟,DC=local",如index为2,则返回"OU=NET,DC=local"</remarks> Public Function GetDistinguishedName(ByVal index As Integer) As String Dim b As New StringBuilder Dim location As String = CNOU.Express(index) If Not String.IsNullOrEmpty(location) Then b.Append(location).Append(",") b.Append(DC.Express) Return b.ToString End Function ''' <summary> ''' 创建与当前实例相同的实例。 ''' </summary> Public Function Clone() As ldapPath Dim ldap As New ldapPath(Me.DomainName,False) ldap.ShortDomainController = Me.ShortDomainController ldap.Path = Me.Path Return ldap End Function Private Function GetDomainServerAddress(ByVal address As String) As String If address Is Nothing Then Return Nothing Dim m As Match = Regex.Match(address,"/b/w+(/.+/w+){2,}") If m.Success Then Return m.Value Else Return Nothing End If End Function Private Sub OnPathChanged() RaiseEvent PathChanged() End Sub Private Function GetPath(ByVal ldapType As ldapType,Optional ByVal index As Integer = 0) As String Dim b As New StringBuilder If Me.DC.Count = 0 Then GoTo Finish b.Append(Me.GetDistinguishedName(index)) If ldapType = DirectoryServices.ldapType.OnlyLocation Then GoTo Finish b.Insert(0,Me.DomainName & "/") If ldapType = DirectoryServices.ldapType.IncludeDomainName Then GoTo Finish If Me.ShortDomainController IsNot Nothing Then b.Insert(0,Me.ShortDomainController & ".") End If Finish: b.Insert(0,"LDAP://") Return b.ToString End Function Private disposedValue As Boolean = False ' 检测冗余的调用 ' IDisposable Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposedValue Then If disposing Then ' TODO: 释放其他状态(托管对象)。 Me.CNOU.Dispose() Me.DC.Dispose() End If ' TODO: 释放您自己的状态(非托管对象)。 ' TODO: 将大型字段设置为 null。 End If Me.disposedValue = True End Sub #Region " IDisposable Support " ' Visual Basic 添加此代码是为了正确实现可处置模式。 Public Sub Dispose() Implements IDisposable.Dispose ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean) 中。 Dispose(True) GC.SuppressFinalize(Me) End Sub #End Region End Class
类图: