今回は「標準コマンドで楽をしよう」ということでcsvdeコマンドを取り上げます。大量のオブジェクトを属性付きでテキストに出力し一括で比較したい、あるいは大量のオブジェクトを一括で作成したい。しかし、スクリプトをかくスキルあるいは時間がない・・・。そんなときにcsvdeを知っていると非常に楽をすることができます。

csvdeとは

csvdeはcsv data exportの略・・・だと思います(きっと)。ActiveDirectoryに対してcsv形式でデータを出力したり、入力したりできるコマンドラインツールです。CSV形式なので、Excelなどで簡単にデータを閲覧したり、作成したりできるので、非常に使い勝手がよいです。Windows 2000 Server以降のサーバーOSであれば基本的に使用できますが、バージョンによって微妙にコマンドラインオプションが異なったりしますので、つどヘルプを読むようにするのがいいと思います。ヘルプの読み方に関しては「コマンドラインヘルプの読み方」(※次に書く予定です。書いたらリンクを張ります。)を参考にしてください。

コマンドラインヘルプ

以下はWindows Server 2008 R2に標準で搭載されているcsvdeのヘルプです。

CSV Directory Exchange

汎用パラメーター

-i              インポート モードにします (既定ではエクスポート モードです) -f ファイル名   入力ファイル名または出力ファイル名 -s サーバー名   結合先のサーバー (既定ではコンピューターのドメインの DC) -v              詳細モードをオンにします -c FromDN ToDN  FromDN を ToDN で置き換えます -j パス         ログ ファイルの場所 -t ポート       ポート番号 (既定値 = 389) -u              Unicode 形式を使います -?              ヘルプ

エクスポート固有

-d RootDN       LDAP search のルートです (既定では名前付けコンテキスト) -r Filter       LDAP search のフィルターです (既定では “(objectClass=*)”) -p SearchScope  検索範囲 (Base/OneLevel/Subtree) -l list         LDAP search で検索する属性の一覧 (コンマ区切り) -o list         入力から省略する属性の一覧 (コンマ区切り) -g              ページされた検索を無効にします。 -m              エクスポートで SAM ロジックを有効にします。 -n              バイナリ値をエクスポートしません。

インポート

-k              ‘Constraint Violation’ エラーと ‘Object Already Exists’ エラー を無視してインポートを続けます

資格情報の確立

資格情報が指定されなかった場合は、CSVDE は現在ログオンしているユーザーとして SSPI を使って結合します。

-a UserDN [Password | *]            簡易認証 -b UserName Domain [Password | *]   SSPI 結合方法

例: 現在のドメインのインポート csvde -i -f INPUT.CSV

例: 現在のドメインのエクスポート csvde -f OUTPUT.CSV

例: 特定のドメインと資格情報のエクスポート csvde -m -f OUTPUT.CSV -b USERNAME DOMAINNAME * -s SERVERNAME -d “cn=users,DC=DOMAINNAME,DC=Microsoft,DC=Com” -r “(objectClass=user)” ログはファイルに書き込まれませんでした。ログ ファイルを生成するには、 -j オプションを使ってログ ファイルへのパスを指定してください。 大きくわけてエクスポートモードとインポートモードに分かれていることがわかると思います。

エクスポート

まず、エクスポートの方法です。規定でエクスポートモードですので、あとは、エクスポートするファイル名を指定してあげるだけでエクスポートすることができます。たとえば以下のような感じです。

C:>csvde -f c:\domain.csv “(null)” に接続しています SSPI を使って現在のユーザーとしてログインしています ディレクトリをファイル c:\domain.csv にエクスポートしています エントリを検索しています… エントリを書き出しています …………………………………………………………………….. …………………………………………………………………….. …………………………………………………………………….. . エクスポートが完了しました。後処理を実行しています… 241 個のエントリがエクスポートされました

コマンドが正しく完了しました 出力結果を見ると、以下のようにドメインパーティションが出力されていることがわかります。(「パーティション」については「Active Directoryのパーティションとレプリケーションスコープ」を参照してください。)

1行目に属性の名前(ヘッダ)が、2行目以降に実際のデータが記録されていることがわかります。excelで読み込んだりすると、この状態でもそれなりに読むことができます。

ちなみに、説明などに日本語を入力している場合、上記のやり方でエクスポートすると文字化けしてしまって読めません。これを避けるには-uオプションをつけて、Unicode形式を使用する必要があります。というか、エクスポートの時には常に-uをつけておくべき、とおぼえてしまってよいと思います。

さて、エクスポートされた結果を読むことができるでしょうか?これを読み解くにはActiveDirectoryのオブジェクトの成り立ちや主要な属性の名前、意味を理解しておく必要があります。そのうちこのブログでも解説しようとおもいますが、ぜひ、自身でActiveDirectoryユーザーとコンピューターからユーザーなどの属性を変更し、エクスポートすることを繰り返して、対応や意味を考えてみてください。きっと力になりますよ。

インポートTips

さて、とりあえずこれでドメインパーティションのエクスポートはできるようになったのですが、これだけではなんだかよくわからないオブジェクトも出力されているし、もっと目的のオブジェクトを絞りたい、というようなことがあると思います。私がよく使うやり方を紹介しておきます。

特定のOU、コンテナ、オブジェクトのみの出力

domain.localドメインのUsersコンテナのみを出力するには以下のようにします。

- csvde -u -f users.csv -d "cn=Users,dc=domain,dc=local"

domain.localドメインのounameというOUのみを出力するには以下のようにします。

- 

csvde -u -f ouname.csv -d “ou=OUName,dc=domain,dc=local”

domain.localドメインのounameに存在しているuser1というオブジェクトのみを出力するには以下のようにします。

- csvde -u -f ouname.csv -d "cn=user1,ou=OUName,dc=domain,dc=local"

特定のオブジェクトの種類のみの出力

ドメインパーティション内のすべてのユーザーのみを出力するには以下のようにします。

- csvde -u -f useronly.csv -r "(objectClass=user)"

ドメインパーティション内のすべてのグループのみを出力するには以下のようにします。

- csvde -u -f grouponly.csv -r "(objectClass=group)"

コンフィグレーションパーティション、スキーマパーティションの出力

コンフィグレーションパーティションの情報を出力するには以下のようにします。

- csvde -u -f configration.csv -d "cn=configuration,dc=test,dc=local"

スキーマパーティションの情報を出力するには以下のようにします。

- csvde -u -f schema.csv -d "cn=schema,cn=configuration,dc=test,dc=local"

ディレクトリ情報の参照専用情報エクスポート

ここまで見てきたようにドメインパーティション、コンフィグレーションパーティション、スキーマパーティションの情報を簡単にコマンド一発でエクスポートできます。ですので、毎日夜にでも情報を日時つきでエクスポートしておけば、後で「あれ、なんでこのオブジェクトのこの属性にこんな値が入ってるんだ?」なんていうようなときに、いつ値が変更されたのか、なんていうことを追跡することが簡単にできます。たとえばExchange Serverの設定などはコンフィグレーションパーティションに入っている・・・というように特定のアプリケーションの設定変更を追うことも結構容易にできます。

もちろん、最近ではADのオブジェクトの属性の変更を監査して、追跡できるようにもなりましたので、csvdeでやらなくてもいいのですが、やはりテキストで出力しておける安心感と、diffツールでdiffしてしまえば一目瞭然な点は魅力的かなと思います。(もっとも、csvdeでエクスポートしても値の意味がわからないような属性は追えないんですけどね。)

インポート

エクスポートの次はインポートです。大量のアカウントを作成するような時に特に便利です。ですが、いったいどういうフォーマットでCSVを作成すればいいのか、必ず指定すべき属性は何なのか?など、結構謎が多いのがこのコマンドのちょっと困ったところです。

で、私がいろいろ悩んだ結果、以下のような流れでCSVフォーマットを決めるのが良いように思います。

- まず、作成したいオブジェクト、設定したい属性を「ADユーザーとコンピューター」で手動で作成する。この際、入力した項目がわかるように値を入れておく。
- 作成したオブジェクトをエクスポートする。
- 作成されたcsvファイルを編集し、目的の属性以外は削る(このとき必須属性は残しておくここに経験が必要)
- 上記csvファイルをフォーマットとして、テストインポートしてみる
- できたオブジェクトを見ながら微調整する

かなりまどろっこしいですが、ある程度は仕方ないですね。

このときの注意点として、そもそも設定できない属性があることは覚えておくべきです。たとえばobjectSidなんていうような属性には値を指定して入力することはできません。

たとえばユーザーオブジェクト例にやって見ましょう。

作成したいオブジェクト、設定したい属性を「ADユーザーとコンピューター」で手動で作成する

こんな感じにしておくと後でやりやすいです。

作成したオブジェクトをエクスポートする

作成したオブジェクトをエクスポートします。

C:>csvde -u -f test.csv -d “CN=フルネーム,CN=Users,DC=ex2010,DC=local” “(null)” に接続しています SSPI を使って現在のユーザーとしてログインしています ディレクトリをファイル test.csv にエクスポートしています エントリを検索しています… エントリを書き出しています . エクスポートが完了しました。後処理を実行しています… 1 個のエントリがエクスポートされました

コマンドが正しく完了しました 以下のようにエクスポートされました。(見づらくてすいません。) DN,objectClass,cn,sn,givenName,initials,distinguishedName,instanceType,whenCreated,whenChanged,displayName,uSNCreated,uSNChanged,name,objectGUID,userAccountControl,badPwdCount,codePage,countryCode,badPasswordTime,lastLogoff,lastLogon,pwdLastSet,primaryGroupID,objectSid,accountExpires,logonCount,sAMAccountName,sAMAccountType,userPrincipalName,objectCategory,dSCorePropagationData “CN=フルネーム,CN=Users,DC=ex2010,DC=local”,user,フルネーム,姓,名,イニシャル,“CN=フルネーム,CN=Users,DC=ex2010,DC=local”,4,20100608140808.0Z,20100608140809.0Z,フルネーム,49444,49450,フルネーム,X’f64cca53791bcc49a1e59a4a6815ad16’,512,0,0,0,0,0,0,0,513,X'010500000000000515000000866e2e7a77bed49aac0afd2167040000’,9223372036854775807,0,logonname2000,805306368,logonname@ex2010.local,“CN=Person,CN=Schema,CN=Configuration,DC=ex2010,DC=local”,16010101000000.0Z

作成されたcsvファイルを編集し、目的の属性以外は削る

上記のcsvファイルをExcelで開いて目印としてつけた属性のみを抜き出すと以下のようになります。

と、言いながら、objectClassだけは消さずに残してしまいました。すいません。この属性は見てのとおり、objectのクラスを指定するもので、これはユーザーオブジェクトを作る際には必須なので、残しました。こういったことはやっているうちにわかってくるようになります。

これをcsv形式で保存しましょう。名前をつけて保存でcsvを選んでください。

さて、これでフォーマット的なものが出来上がりつつあります。ためしにテストインポートしてみましょう。

csvファイルをフォーマットとして、テストインポートしてみる

ここまででできたcsvファイルはそのままにして、先ほど作成したオブジェクトをディレクトリから消します。その上でインポートしてみます。

C:>csvde -i -f c:\test.csv “(null)” に接続しています SSPI を使って現在のユーザーとしてログインしています ファイル “c:\test.csv” からディレクトリをインポートしています エントリを読み込んでいます.. 1 個のエントリを正しく修正しました。

コマンドが正しく完了しました 正常にインポートできました。出来上がったオブジェクトを見てみます。

正常にインポートされましたが、「アカウントは無効」になってしまっているようです。ちょっと残念ですね。

できたオブジェクトを見ながら微調整する

これをどうにかしようと思ったら・・・・。2つ大きくアプローチがあります。

- アカウントのインポートまではうまくできているので、後から別の方法でアカウントを有効にする
- アカウントの有効、無効をコントロールしている属性を突き止めて、その属性をcsvdeで読み込む元のCSVに反映させる

たとえば1の方法でいってしまうのなら、2003以降のOSであれば、ADユーザーとコンピューターで複数アカウントを選択して、プロパティから一括してオブジェクトを有効にすることができます。これで問題は解決ですね。

個人的にはあまり1つの方法にこだわらず、ほかの回避策がみつかるなら、それを採用するのがいいと思います。

もしも、2の方法で「csvdeで全部やってやる!」と意気込むと、その先には茨の道が待っていることが多いです・・・。今回のことに限れば以下のURLに説明と回避策が書いてあります。

- [csvdeコマンドで複数のユーザー・アカウントを一括登録する - 管理者必見! ネットワーク・コマンド集:ITpro](http://itpro.nikkeibp.co.jp/article/COLUMN/20071127/288113/)

なお,csvdeコマンドでアカウントをインポートした場合,特に設定をしていない場合は登録したアカウントは無効な状態になっています。また,csvdeではパスワードのインポートはできないため,後から他の方法(net userやdsmod userコマンド,ADSIスクリプト)でパスワード登録とアカウントの有効化を設定し直す必要があります。例えば,簡単な例としてdsquery *コマンドからdsmod userコマンドへのパイプラインで設定する方法を示すと図4のようになります。

このような設定をしたくない場合には,一時的にActive Directoryの「ドメイン・セキュリティ・ポリシー」から設定できる「パスワードのポリシー」の「パスワードの長さ」を0文字,「パスワードは,複雑さの要件を満たす必要がある」を「無効」に設定し(図5),userAccountControl属性値を「512」としてCSVファイルに加えておくことで,「パスワードなし」で「ユーザーは次回ログオン時にパスワードの変更が必要」という状況でアカウントを登録することもできます。 はい。パスワードポリシーを変更したうえで、userAccountControl属性に「512」と入力する必要がある、ということが書かれています。パスワードポリシーに関してはそれを気がつくのはなかなかセンスが要求されるでしょうし、userAccountControlに関しては「512って何?」という状態になってしまう人が多いと思います。(ビット演算です。←わかる人向けです)

このように、ActiveDirectoryの属性には、単純でないものがありますので、あまり深追いしないことをお勧めします。回避策があれば回避策を使いましょう。(心配しなくても逃げられないことにすぐに出会いますからそのときにがんばればいいでしょう・・・)

何はともあれ、これで一応インポートすることができました。おおよそこのような流れになります。

まとめ

最後はちょっとグダグダになってしまった感もありますが、標準ツールで結構簡単にエクスポート、インポートできることを実感してもらえたのではないでしょうか。そして、難しいことは回避策を取ってしまう、と。

ただ、これだけのことでも、きちんと使えば何十時間もの時間の節約になったりします。ぜひ活用してみてください。