.NETからActive Directoryデータにアクセス
プリンタ情報を表示する

小山 三智男
mitchin
サンプルアプリケーション
開発環境
• OS:Windows 8.1 Pro、Windows 7 Professional SP1
• IDE:Visual Studio Professional 2013
• アプリ:Windows フォーム(.NET 4.5.1)
Web フォーム(.NET 4.5.1) IE11、IE10
クラスライブラリ(.NET 4.5.1)
※ソースコード自体は .NET 4 相当
実行環境
• 単一ドメイン、単一サイト、単一サブネット
• サーバ:Windows Server 2008 Standard SP2(.NET 4.5.1)
• IIS:Windows 認証
• クライアント:Windows 7 Professional SP1、IE10
2
参照設定
• .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を
参照する必要があります。
3
主にどんなデータがあるの?
管理ツール「Active Directory ユーザとコンピュータ」で管理
する以下のオブジェクト
• ユーザ
• グループ
• コンピュータ
• 組織単位(OU)
• プリンタ
• 共有フォルダ

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

IADsUser
IADsGroup

コンピュータ
組織単位(OU)
プリンタ

IADsComputer
IADsOU
IADsPrintQueue

共有フォルダ
DirectoryEntry.NativeObject プロパティの値を上記インター
フェイスにキャストできます。但し IADsComputer は LDAP をサ
ポートしていないので 実質キャストできません。
5
どうやって接続するの?
ドメインに接続するには LDAP を使います。
プロバイダ:LDAP(Lightweight Directory Access Protocol)
書式例:LDAP://DC=virtual,DC=proceed,DC=local

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

6
検索してプリンタのリストを取得する
•
•
•
•
•

接続するドメインや取得したプリンタは DirectoryEntry オブジェクト
ユーザやプリンタを検索するのは DirectorySearcher オブジェクト
複数の検索結果は SearchResultCollection として返される
SearchResult.GetDirectoryEntry メソッドで DirectoryEntry を取得
LDAP書式のフィルター文字列(DirectorySearcher.Filter プロパティ)は
次のように指定(属性=値 をカッコで括る)
• "(objectCategory=PrintQueue)" -- プリンタ
• "(&(objectCategory=PrintQueue)(!location=*本社))" -- 本社以外のプ
リンタ
• "(&(objectCategory=PrintQueue)(|(printColor=False)(printDuplexSupp
orted=False)))" -- モノクロか片面印刷のプリンタ
• "(&(objectCategory=PrintQueue)(printPagesPerMinute>=30))" -- 1分
間に30枚以上印刷できるプリンタ

7
プリンタのプロパティ
左:コントロールパネル、右:管理ツール

8
プリンタリスト画面(Windowsアプリ)

9
プリンタリスト画面(Webアプリ)

10
クラスライブラリ側に追加したクラス
PrintQueue (プリンタを表すクラス)
プロパティ
• Color, Duplex (カラー/両面 かどうかを取得または設定)
• FullName (名前を取得)
• Location (場所を取得または設定)
• MaxResolution (最高解像度を取得または設定)
• Model (モデルを取得または設定)
• Name, ServerName (プリンタ名/サーバ名 を取得)
• Speed (印刷速度を取得または設定)
• Stapling (ホチキス止めかどうかを取得または設定)
メソッド
• FindByName (データバインド用:プリンタを検索)
• GetPrintQueues (データバインド用:プリンタの一覧を取得)
11
プロパティと属性の対応
プロパティ画面の「全般」タブの項目に対応する属性です。

12
参考:プリンタの属性
プリンタにはサンプルアプリで使用する属性以外にも次のような
属性があります。
•portName:ポート - ポート
•printCollate:詳細設定 - 詳細な印刷機能を有効にする
•printKeepPrintedJobs:詳細設定 - 印刷後ドキュメントを残す
•printMediaReady:全般 - 利用可能な用紙
•printShareName:共有 - 共有名
•printSpooling :詳細設定 - スプール/直接 の選択
•Priority:詳細設定 - 優先順位
•shortServerName:serverNameのコンピュータ名部分
•uNCName:UNCパス(serverNameprinterName)
13
クラスライブラリ側
DirectoryAccess クラスに追加したパブリックなメンバ
• GetPrintQueues メソッド (プリンタを取得)

14
フォーム側(Windowsアプリ)
• BindingSource のデータソースに PrintQueue クラスを指定
• BindingSource を一覧 ListBox のデータソースに設定
• 詳細の各コントロールは BindingSource(クラス)のプロパ
ティにバインド
• プリンタの一覧を取得し BindingSource のデータソースに設定
• 取得したプリンタの数を表示

15
フォーム側(Webアプリ)
• PrintQueue クラスをビジネスオブジェクトとする
ObjectDataSource を2つ用意
• GetPrintQueues メソッドを指定したものを 一覧 ListBox の
データソースに指定
• FindByName メソッドを指定したものを 詳細 FormView のデー
タソースに指定(パラメータ ソースは一覧 ListBox)
• 一覧 ListBox 用 ObjectDataSource の Selected イベントで取
得したプリンタの数を表示
• 詳細 FormView 用 ObjectDataSource の Selecting イベントで
プリンタが未選択ならイベントをキャンセルし、Selected イベ
ントで 選択したプリンタの印刷速度、最高解像度の値を
ViewState に保持
• 印刷速度、最高解像度の値変更時に値をチェック、実数なら小
数部を切捨て、数値に変換できなければ変更前の値に戻す
16
プリンタ取得サンプルコード(VB)
Public Shared Function GetPrintQueues() As IList(Of PrintQueue)
Dim printers As New List(Of PrintQueue)()
Using root = GetRootEntry()
'ルートのDirectoryEntryを取得
Dim filter = "(objectCategory= PrintQueue)"
Using searcher As New DirectorySearcher(root, filter)
Using results = searcher.FindAll()
For Each res As SearchResult In results
printers.Add(DirectCast(
CreateInstance(res.GetDirectoryEntry()), PrintQueue))
Next
End Using
End Using
End Using
Return printers
End Function
※root は一般的には New DirectoryEntry(LDAPのルートパス) をセット
※CreateInstance メソッドは DirectoryEntry から DirectoryObject を作成
17
プリンタ取得サンプルコード(C#)
public static IList<PrintQueue> GetPrintQueues() {
var printers = new List<PrintQueue>();
using (var root = GetRootEntry()) {
//ルートのDirectoryEntryを取得
var filter = "(objectCategory=PrintQueue)";
using (var searcher = new DirectorySearcher(root, filter)) {
using (var results = searcher.FindAll()) {
foreach (SearchResult res in results) {
printers.Add(
(PrintQueue)CreateInstance(res.GetDirectoryEntry()));
}
}
}
}
return printers;
}
※root は一般的には new DirectoryEntry(LDAPのルートパス) をセット
※CreateInstance メソッドは DirectoryEntry から DirectoryObject を作成
18
詳細や関連情報はブログ等で
.NETからActive Directoryデータにアクセス ~ユーザ情報の取得と表示~
http://www.slideshare.net/mitchin227/display-user
ユーザやグループの検索
http://blogs.wankuma.com/mitchin/archive/2013/06/26/327958.aspx
Active Directory 内のオブジェクトの検索指定
http://blogs.wankuma.com/mitchin/archive/2013/06/28/327969.aspx
プリンタのプロパティ画面の項目と属性の対応(全般タブ)
http://blogs.wankuma.com/mitchin/archive/2013/12/29/328318.aspx
プリンタ用のクラス
http://blogs.wankuma.com/mitchin/archive/2014/01/04/328325.aspx
http://blogs.wankuma.com/mitchin/archive/2014/01/05/328326.aspx
プリンタリスト画面
http://blogs.wankuma.com/mitchin/archive/2014/01/07/328332.aspx
追加したプリンタを特定の組織単位(OU)に配置する
http://blogs.wankuma.com/mitchin/archive/2014/01/09/328337.aspx
19

.NETからActive Directoryデータにアクセス ~プリンタ情報の取得と表示~