netからactive directoryデータにアクセス ~コンピュータ情報の取得と表示~

20
.NET かか Active Directory かかかかかかかか かかかかかかかかかかかかか かか かかか mitchin

Upload: michio-koyama

Post on 18-Dec-2014

410 views

Category:

Technology


1 download

DESCRIPTION

Get computer objects from Active Directory and display on a windows/web form.

TRANSCRIPT

Page 1: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

.NET から Active Directory データにアクセス

コンピュータ情報を表示する

小山 三智男mitchin

Page 2: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

2

サンプルアプリケーション

開発環境• OS : Windows 8 Enterprise(x64)• IDE : Visual Studio Professional 2013• アプリ: Windows フォーム (.NET 4.5.1)

Web フォーム (.NET 4.5.1) IE10クラスライブラリ (.NET 4.5.1)※ ソースコード自体は .NET 4 相当

実行環境• 単一ドメイン、単一サイト、単一サブネット• サーバ: Windows Server 2008 Standard SP2(.NET 4.5.1)• IIS : Windows 認証• クライアント: Windows 7 、 IE10

Page 3: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

3

参照設定

• .NET から Active Directory の色々な情報にアクセスするために System.DirectoryServices アセンブリを参照する必要があります。•ドメインやサイト関連は System.DirectoryServices. ActiveDirectory 名前空間にそれらを表すクラスがあり、 Active Directory の管理タスクを自動化するために使用されます。•Active Directory 内のデータにアクセスするために使用されるのは System.DirectoryServices 名前空間で、オブジェクトをカプセル化する DirectoryEntry クラスやクエリを実行するDirectorySearcher クラスなどがあります。•ADSI(Active Directory Services Interfaces) を使用してネイティブなオブジェクトを扱う場合は Active DS Type Libraryを参照する必要があります。

Page 4: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

4

主にどんなデータがあるの?

管理ツール「 Active Directory ユーザとコンピュータ」で管理する以下のオブジェクト• ユーザ• グループ• コンピュータ• 組織単位( OU)• プリンタ• 共有フォルダ

Page 5: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

5

サンプルアプリケーションの初期画面

ドメインを取得して画面下部に接続先を表示しています。

Page 6: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

6

コンピュータリスト画面( Windows アプリ)

Page 7: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

7

コンピュータリスト画面( Web アプリ)

Page 8: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

8

どうやって接続するの?

ドメインに接続するには LDAP を使います。プロバイダ: LDAP(Lightweight Directory Access Protocol)書式例: LDAP://DC=virtual,DC=proceed,DC=local

この LDAP の接続文字列を引数にして DirectoryEntry のインスタンスを作成します。この DirectoryEntry がドメインを表し、検索のルートになります。( DirectorySearcher の引数になります。)この場合、検索範囲はドメイン全体ということになります。

Page 9: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

9

検索してコンピュータのリストを取得する

• 接続するドメインや取得したコンピュータは DirectoryEntry オブジェクト

• ユーザやコンピュータを検索するのは DirectorySearcher オブジェクト• 複数の検索結果は SearchResultCollection として返される• SearchResult.GetDirectoryEntry メソッドで DirectoryEntry を取得• LDAP 書式のフィルター文字列( DirectorySearcher.Filter プロパティ)

は次のように指定(属性 = 値 をカッコで括る)• "(objectCategory=Computer)" -- コンピュータ• "(&(objectCategory=Computer)(!operatingSystem=Windows

8*))" -- Windows 8 以外のコンピュータ• "(&(objectCategory=Computer)(|(operatingSystem=Windows

Server*)(operatingSystem=Windows 8*)))" -- Windows Server か Windows 8 のコンピュータ• "(&(objectCategory=Computer)(logonCount>=100))" -- 100 回以

上ログオンしているコンピュータ

Page 10: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

10

ADSI のインターフェイス

基本インターフェイスは IADs インターフェイスで、各オブジェクトはこのインターフェイスを継承しています。

オブジェクトとそれに対応するインターフェイス

DirectoryEntry.NativeObject プロパティの値を上記インターフェイスにキャストできます。が・・・

ユーザ IADsUser

グループ IADsGroup

コンピュータ IADsComputer

組織単位( OU) IADsOU

プリンタ IADsPrintQueue

共有フォルダ

Page 11: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

11

IADsComputer の残念なお知らせ

IADsComputer インターフェイスは LDAP をサポートしていません。なのでキャストしようとすると InvalidCastException がスローされます。IADs インターフェイスにはキャストできますが、サンプルアプリケーションでは積極的に使用する理由がないので、今回追加したコンピュータを表すクラス(後述)にはユーザやグループを表すクラスのように ADSI オブジェクトを取得する Native プロパティを実装していません。

ユーザやグループについてはこちらのスライドを参照http://www.slideshare.net/mitchin227/display-userhttp://www.slideshare.net/mitchin227/display-group

Page 12: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

12

クラスライブラリ側に追加したクラス

Computer ( コンピュータを表すクラス )プロパティ• FullName (DNS 名を取得 )• OperatingSystem (OS を取得 )• OperatingSystemServicePack (OS の Service Pack を取得 )• OperatingSystemVersion (OS のバージョンを取得 )• PrimaryGroupId ( プライマリ グループ ID を取得 )• Role ( 役割を取得 )• Site ( サイトを取得 )

メソッド• FindByName ( コンピュータを検索 )• GetBelongGroups ( 所属するグループを取得 )• GetComputers ( コンピュータの一覧を取得 )

Page 13: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

13

クラスライブラリ側

DirectoryAccess クラスに追加したパブリックなメンバ• GetComputers メソッド ( コンピュータの一覧を取得 )

Page 14: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

14

フォーム側( Windows アプリ)

• BindingSource のデータソースに Computer クラスを指定• BindingSource を一覧 ListBox のデータソースに設定•詳細の各コントロールは BindingSource (クラス)のプロパティにバインド•グループの一覧を取得し、内部に保持•コンピュータの一覧を取得し BindingSource のデータソースに設定•取得したコンピュータの数を表示•選択されたコンピュータの所属するグループを取得し、所属するグループ ListBox のデータソースに設定

Page 15: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

15

フォーム側( Web アプリ)

• Computer クラスをビジネスオブジェクトとする ObjectDataSource を 3 つ用意• GetComputers メソッドを指定したものを一覧 ListBox のデータソースに指定• FindByName メソッドを指定したものを詳細 FormView のデータソースに指定(パラメーター ソースは一覧 ListBox )• GetBelongGroups メソッドを指定したものを所属するグループ ListBox のデータソースに設定•一覧 ListBox 用 ObjectDataSource の Selected イベントで取得したコンピュータの数を表示

Page 16: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

16

コンピュータ取得サンプルコード( VB )Public Shared Function GetComputers() As IList(Of Computer) Dim computers As New List(Of Computer)() Using root = GetRootEntry() ' ルートの DirectoryEntry を取得 Dim filter = String.Format("(objectCategory={0})",

CategoryType.Computer) Using searcher As New DirectorySearcher(root, filter) Using results = searcher.FindAll() For Each res As SearchResult In results computers.Add(DirectCast( CreateInstance(res.GetDirectoryEntry()), Computer)) Next End Using End Using End Using Return computersEnd Function※root は一般的には New DirectoryEntry(LDAP のルートパス ) をセット※CreateInstance メソッドは DirectoryEntry から DirectoryObject を作

Page 17: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

17

コンピュータ取得サンプルコード( C# )public static IList<Computer> GetComputers() { var computers = new List<Computer>(); using (var root = GetRootEntry()) { // ルートの DirectoryEntry を取得 var filter = String.Format("(objectCategory={0})",

CategoryType.Computer); using (var searcher = new DirectorySearcher(root, filter)) { using (var results = searcher.FindAll()) { foreach (SearchResult res in results) { groups.Add( (Computer)CreateInstance(res.GetDirectoryEntry())); } } } } return computers;}※root は一般的には new DirectoryEntry(LDAP のルートパス ) をセット※CreateInstance メソッドは DirectoryEntry から DirectoryObject を作

Page 18: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

18

所属するグループの取得( VB )

Public Function GetBelongGroups(groups As IEnumerable(Of DomainGroup)) As ReadOnlyCollection(Of String)

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

ユーザの場合は IADsUser.Groups メソッドで所属するグループを取得できますが、コンピュータの場合はできないのでグループのコレクションが必要です。個々のグループに対してメンバであれば( IADsGroup.IsMember メソッドが True を返せば)そのグループに所属していると判断しています。プライマリ グループの追加についてはユーザの場合と同じです。

Page 19: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

19

所属するグループの取得( C# )

Public ReadOnlyCollection<string> GetBelongGroups(IEnumerable<DomainGroup> groups){

var belongGroups = groups.Where( group => group.Native.IsMember(base.Entry.Path)).Select group => group.Name).ToList();

belongGroups.Add( DirectoryAccess.GroupTokens[this.PrimaryGroupId]); belongGroups.Sort(); return belongGroups.AsReadOnly();}

Page 20: NETからActive Directoryデータにアクセス ~コンピュータ情報の取得と表示~

20

詳細や関連情報はブログ等で

.NET から Active Directory にアクセスhttp://www.slideshare.net/mitchin227/active-directory-24695891

ユーザやグループの検索http://blogs.wankuma.com/mitchin/archive/2013/06/26/327958.aspx

SearchResultCollection クラスhttp://blogs.wankuma.com/mitchin/archive/2013/06/30/327977.aspx

ネイティブ ADSI オブジェクトhttp://blogs.wankuma.com/mitchin/archive/2013/07/01/327981.aspx

ユーザの所属するグループの取得http://blogs.wankuma.com/mitchin/archive/2013/07/11/327999.aspx

コンピュータ用のクラスhttp://blogs.wankuma.com/mitchin/archive/2013/11/09/328208.aspxhttp://blogs.wankuma.com/mitchin/archive/2013/11/10/328210.aspx

コンピュータリスト画面http://blogs.wankuma.com/mitchin/archive/2013/11/13/328220.aspx