C# Programming

 
Image

アクティブディレクトリ (ADSI)

開発環境: Visual Studio 2003 

1.目次

2.目的

ADSI とは、 Active Directory Services Interfaces で、アクティブディレクトリサービスへアクセスするためのインターフェースです。
.NET Framework には、DirectoryEntry と DirectorySearcher という 2 つの Active Directory コンポーネント クラスが用意されています。
ADSI を使用すると、ネットワーク上のリソースを探したり管理したりする作業を比較的簡単に行うことができます。

Image

3.参考書

(1) MSDN チュートリアル : アクティブ ディレクトリ オブジェクトの追加

4.作り方

注意
DirectorySearcher は、LDAP プロバイダで使用します。
LDAP を使える環境が無いのでここではDirectoryEntry だけの説明です。

次のような、パスを指定して ADSI から情報を取得するアプリケーションを作ります。
ここでは、ユーザ、グループ、サービス、プリントキューの情報をリストしています。

Image

MSDN チュートリアル : アクティブ ディレクトリ オブジェクトの追加 に説明が載っているので、細かい説明はそちらを見てください。

コード的にはかっちょ悪いけど、MSDNと同じつくりにしています。

中身はほとんど同じですが、DirectoryEntry の Path を TextBoxから指定して、Getボタンで情報を取得するようにしています。
このパスは、ディレクトリサービスの種類、あるいはドメイン構成によって違ってくるので注意が必要です。
DirectoryEntry の Path の例
ドメインに参加している場合WinNT://MyDomain/YourComputerName
WinNT://MyDomain/Group
WinNT://MyDomain/MyComputer/aPrinter/
ワークグループの場合 WinNT://YourComputerName
LDAPの場合LDAP://MyDomain.microsoft.com/CN=TopH,DC=DEV,DC=MSFT,DC=COM,O=Internet LDAP://CN=TopHat,DC=DEV,DC=MSFT,DC=COM,O=Internet
NDSの場合NDS://ndsServer/O=Internet/DC=COM/DC=MSFT/DC=DEV/CN=TopHat NWCOMPAT://binderyServer/TopHat

自分の環境は、ワークグループなので、WinNT://UCHUKAMEN となります。

5.必要条件

動作環境

DirectoryEntry、 DirectorySearcherを使用するためには、ADSI SDK または ADSI ランタイムがコンピュータにインストールされている必要があります。
Windows 2000, XP では、ADSI 2.5 が既定でインストールされています。
旧バージョンの Windows を使用している場合は、Microsoft の Web サイトから SDK をインストールする必要があります。

DirectoryEntry を使って、Active Directory オブジェクトのプロパティ値に変更を加えるには、目的のオブジェクトに対する管理者の権限が必要です。

DirectorySearcher では、LDAP プロバイダが必要です。

6.ソースコード

変更履歴
2003/7/21   初版作成

Form1.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.DirectoryServices;

namespace ADSI1
{
        /// <summary>
        /// Form1 の概要の説明です。
        /// </summary>
        public class Form1 : System.Windows.Forms.Form
        {
        private System.DirectoryServices.DirectoryEntry directoryEntry1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.TextBox tbPath;
        private System.Windows.Forms.TreeView treeView1;
                /// <summary>
                /// 必要なデザイナ変数です。
                /// </summary>
                private System.ComponentModel.Container components = null;

                public Form1()
                {
                        //
                        // Windows フォーム デザイナ サポートに必要です。
                        //
                        InitializeComponent();

                        //
                        // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
                        //
                }

                /// <summary>
                /// 使用されているリソースに後処理を実行します。
                /// </summary>
                protected override void Dispose( bool disposing )
                {
                        if( disposing )
                        {
                                if (components != null) 
                                {
                                        components.Dispose();
                                }
                        }
                        base.Dispose( disposing );
                }

                #region Windows Form Designer generated code
                /// <summary>
                /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
                /// コード エディタで変更しないでください。
                /// </summary>
                private void InitializeComponent()
                {
            this.directoryEntry1 = new System.DirectoryServices.DirectoryEntry();
            this.button1 = new System.Windows.Forms.Button();
            this.tbPath = new System.Windows.Forms.TextBox();
            this.treeView1 = new System.Windows.Forms.TreeView();
            this.SuspendLayout();
            // 
            // directoryEntry1
            // 
            this.directoryEntry1.Path = "WinNT://uchukamen";
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(328, 8);
            this.button1.Name = "button1";
            this.button1.TabIndex = 0;
            this.button1.Text = "Get";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // tbPath
            // 
            this.tbPath.Location = new System.Drawing.Point(16, 8);
            this.tbPath.Name = "tbPath";
            this.tbPath.Size = new System.Drawing.Size(264, 19);
            this.tbPath.TabIndex = 1;
            this.tbPath.Text = "WinNT://UCHUKAMEN";
            // 
            // treeView1
            // 
            this.treeView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right)));
            this.treeView1.ImageIndex = -1;
            this.treeView1.Location = new System.Drawing.Point(0, 40);
            this.treeView1.Name = "treeView1";
            this.treeView1.SelectedImageIndex = -1;
            this.treeView1.Size = new System.Drawing.Size(416, 144);
            this.treeView1.TabIndex = 2;
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(416, 190);
            this.Controls.Add(this.treeView1);
            this.Controls.Add(this.tbPath);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Active Directory";
            this.ResumeLayout(false);

        }
                #endregion

                /// <summary>
                /// アプリケーションのメイン エントリ ポイントです。
                /// </summary>
                [STAThread]
                static void Main() 
                {
                        Application.Run(new Form1());
                }


        private void button1_Click(object sender, System.EventArgs e)
        {
            // カーソルを砂時計にする。
            this.Cursor = Cursors.WaitCursor;
            // ツリーノードをクリアする。
            this.treeView1.Nodes.Clear();
            // ツリーノードの操作を開始
            this.treeView1.BeginUpdate();
            this.directoryEntry1.Path = this.tbPath.Text;

            TreeNode users = new TreeNode("Users");
            TreeNode groups = new TreeNode("Groups");
            TreeNode services = new TreeNode("Services");
            TreeNode printQueue = new TreeNode("PrintQueue");
            treeView1.Nodes.AddRange(new TreeNode[] { users, groups, services, printQueue });

            foreach(DirectoryEntry child in this.directoryEntry1.Children) 
            {
                TreeNode newNode = new TreeNode(child.Name);
                switch (child.SchemaClassName) 
                {
                    case "User" :
                        users.Nodes.Add(newNode);  
                        AddPathAndProperties(newNode, child);
                        break;
                    case "Group" :
                        groups.Nodes.Add(newNode);   
                        AddPathAndProperties(newNode, child);
                        break;
                    case "Service" :
                        services.Nodes.Add(newNode);   
                        AddPathAndProperties(newNode, child);
                        break;
                    case "PrintQueue" :
                        printQueue.Nodes.Add(newNode);   
                        AddPathAndProperties(newNode, child);
                        break;
                    default:
                        Console.WriteLine("Unhandled SchemaClassName:" +  child.SchemaClassName);
                        break;
                }
            }
            // ツリーノードの操作を終了
            this.treeView1.EndUpdate();
            // カーソルを元に戻す。
            this.Cursor = Cursors.Default;
        }

        // プロパティを取得する
        private void AddPathAndProperties(TreeNode node, DirectoryEntry entry)
        {
            TreeNode propertyNode = new TreeNode("Properties");
            try
            {
                node.Nodes.Add(propertyNode);
                foreach (string propertyName in entry.Properties.PropertyNames) 
                {
                    string oneNode = propertyName + ": " + 
                        entry.Properties[propertyName][0].ToString();
                    propertyNode.Nodes.Add(new TreeNode(oneNode));
                }
            }
            catch (Exception exc)
            {
                propertyNode.Nodes.Add(exc.Message);
            }
        }
        }
}