コンピュータを表すクラス Computer クラスは DomainObject クラスを継承します。
Webアプリでデータソースとして使えるようにします。
<DataObject()>
Public NotInheritable Class Computer
Inherits DomainObject
#Region " プライベートフィールド "
Private ReadOnly _fullName, _role, _os, _osVer, _osSP, _site As String
#End Region
#Region " フレンドコンストラクタ "
'DirectoryEntry を指定して Computer クラスの新しいインスタンスを初期化します。
Friend Sub New(entry As DirectoryEntry)
MyBase.New(entry)
entry.Invoke("GetInfoEx", New Object() {"msDS-isGC", "msDS-SiteName"}, 0)
With entry.Properties
_fullName = DirectCast(.Item("dNSHostName").Value, String)
_role = GetRole() '役割を取得
_os = DirectCast(.Item("operatingSystem").Value, String)
_osVer = DirectCast(.Item("operatingSystemVersion").Value, String)
_osSP = DirectCast(.Item("operatingSystemServicePack").Value, String)
_site = DirectCast(.Item("msDS-SiteName").Value, String)
End With
End Sub
#End Region
#Region " パブリックプロパティ "
'DNS 名を取得します。
Public ReadOnly Property FullName As String
Get
Return _fullName
End Get
End Property
'OS を取得します。
Public ReadOnly Property OperatingSystem As String
Get
Return _os
End Get
End Property
'OS のサービスパックを取得します。
Public ReadOnly Property OperatingSystemServicePack As String
Get
Return _osSP
End Get
End Property
'OS のバージョンを取得します。
Public ReadOnly Property OperatingSystemVersion As String
Get
Return _osVer
End Get
End Property
'プライマリグループ ID を取得します。
Public ReadOnly Property PrimaryGroupId As Integer
Get
If MyBase.IsDisposed Then
Throw New ObjectDisposedException(Me.GetType().Name)
End If
Return Convert.ToInt32(MyBase.Entry.Properties.Item("primaryGroupID").Value)
End Get
End Property
'役割を取得します。
Public ReadOnly Property Role As String
Get
Return _role
End Get
End Property
'サイトを取得します。
Public ReadOnly Property Site As String
Get
Return _site
End Get
End Property
#End Region
#Region " パブリックメソッド "
'指定した名前のコンピュータを検索します。このメソッドはデータバインド用です。
<DataObjectMethod(DataObjectMethodType.Select)>
Public Shared Function FindByName(name As String) As Computer
Return DirectCast(DirectoryAccess.FindDirectoryObject(name, CategoryType.Computer), Computer)
End Function
'所属するグループを取得します。
Public Function GetBelongGroups(groups As IEnumerable(Of DomainGroup)) As ReadOnlyCollection(Of String)
If groups Is Nothing Then
Throw New ArgumentNullException("groups", "groups が Nothing です。")
End If
Dim belongGroups = groups.Where(
Function(group) group.Native.IsMember(MyBase.Entry.Path)).Select(Function(group) group.Name).ToList()
belongGroups.Add(DirectoryAccess.GroupTokens.Item(Me.PrimaryGroupId))
belongGroups.Sort()
Return belongGroups.AsReadOnly()
End Function
'指定した名前のコンピュータの所属するグループを取得します。このメソッドはデータバインド用です。
<DataObjectMethod(DataObjectMethodType.Select)>
Public Shared Function GetBelongGroups(name As String) As ReadOnlyCollection(Of String)
Dim pc = FindByName(name) 'コンピュータを検索
Dim groups = DirectoryAccess.GetGroups(Of DomainGroup)() 'グループを取得
Return pc.GetBelongGroups(groups) '所属するグループを取得
End Function
'コンピュータの一覧を取得します。このメソッドはデータバインド用です。
<DataObjectMethod(DataObjectMethodType.Select)>
Public Shared Function GetComputers() As IList(Of Computer)
Return DirectoryAccess.GetComputers() 'コンピュータを取得
End Function
#End Region
#Region " プライベートメソッド "
'役割を取得します。
Private Function GetRole() As String
Dim gc = MyBase.Entry.Properties.Item("msDS-isGC").Value
If gc Is Nothing Then
Return "ワークステーションまたはサーバー"
End If
Return If(Convert.ToBoolean(gc), "グローバル カタログ", "ドメイン コントローラー")
End Function
#End Region
一覧を取得する GetComputers メソッドは内部で DirectoryAccess クラスの GetComputers メソッドを呼んでますが、これについては別途書きます。
コンピュータはユーザと同じく所属するグループがあり、プライマリ グループがあります。
プライマリ グループはユーザと同じ方法で取得しますが所属するグループは内部実装が異なります。
ユーザの場合は IADsUser.Groups メソッドで所属するグループ(プライマリ グループ以外)を取得できるんですが、コンピュータの場合はそれに相当するメソッドがありません。
また、残念なことに LDAP で取得したコンピュータは IADsComputer オブジェクトとして扱えない(DirectoryEntry.NativeObject からキャストできない)んです。なのでユーザやグループのように Native プロパティを実装してません。
仕方ないのですべてのグループを取得して、個々のグループに対してメンバであれば(IADsGroup.IsMember メソッドが True を返せば)そのグループに所属してると判断してます。