知られざるActive Directory技術の「舞台裏」

第5回 DS*コマンドを使ってLDAPを操作する

この記事を読むのに必要な時間:およそ 4 分

パイプラインによる複雑なDSコマンドを使う

先に記載したとおり,パイプラインを使って複数のコマンドを連続して利用することで,複雑な動作が可能になります。いくつかの例を示します。

dsquery user "OU=営業部,DC=marubatsucorp,DC=local" -stalepwd 21|dsmod user -mustchpwd yes

実行結果

実行結果

実行結果

"OU=営業部,DC=marubatsucorp,DC=local"ディレクトリ内で,21日間パスワードの変更がなかったユーザアカウントについて,次回ログオン時にパスワードを変更することを強制します。dsquery userコマンドでパスワードの変更状況をチェックし,該当するアカウントにdsmod userコマンドでパスワードの変更を強制する設定を行ないます。パスワードポリシーとは関係なく強制的にパスワードを変更させたい場合に,便利です。

dsquery computer "CN=Computers,DC=marubatsucorp,DC=local" -inactive 12|dsrm -noprompt

"CN=Computers,DC=marubatsucorp,DC=local"ディレクトリ内で,12週間ログオンがなかったコンピュータオブジェクトを検索し,そのオブジェクトを削除します。利用されないアカウントオブジェクトをそのままにしておくのはセキュリティ上問題があるので,無効化したり削除したい場合に便利です。

dsquery server|dsget server -dnsname -site -isgc

実行結果

実行結果

フォレスト内のすべてのドメインコントローラについて,所属するサイトとグローバルカタログかどうかを表示します。このコマンドを使うことで[Active Directoryサイトとサービス]スナップインの情報を簡単にテキスト化することができます。

dsadd group "CN=課長グループ,OU=営業部,DC=marubatsucorp,DC=local" -desc 営業部課長グループ && dsquery * -filter "&(objectCategory=Person)(objectClass=User)(department=営業部*)(title=課長*)"|dsmod group "CN=課長グループ,OU=営業部,DC=marubatsucorp,DC=local" -addmbr

実行結果

実行結果

実行結果

少し長いですが,まずdsadd groupコマンドで新しいセキュリティグループ(課長グループ)を"OU=営業部,DC=marubatsucorp,DC=local"に作成し,dsquery *コマンドで,部署名(department)に"営業部"が,役職名(title)に"課長"が含まれるユーザオブジェクトを検索して,dsmod groupコマンドで"CN=課長グループ,OU=営業部,DC=marubatsucorp,DC=local"グループのメンバとして,これらのユーザを追加します。ユーザオブジェクトはobjectCategory属性に"Person"文字列とobjectClass属性に"User"文字列を含んでいますので,このような検索条件で抽出することができます。

dsquery * -filterコマンドを使うと,任意の属性を使って検索条件を指定できるため,非常に便利です。検索条件を指定する演算子には,つぎのようなものがあります。なお,特殊文字をリテラル文字(表記上の文字)として扱う場合,エスケープシーケンスによる符号化が必要です。あわせて記載します(表5,表6)⁠

表5 LDAP検索時の演算子

=Equal等しい
&Andかつ
|Orまたは
!Not~でない
>Less thanより小さい
<Greater thanより大きい
>=And Above以上
<=Or Below以下

表6 特殊文字のエスケープシーケンス

*アスタリスク\2a
(開き括弧\28
)閉じ括弧\29
\バックスラッシュ\5c
NULNull文字\00
/スラッシュ\2f
dsadd ou "OU=利用していないアカウント,DC=marubatsucorp,DC=local" && For /F "usebackq delims=" %i in (`dsquery * -filter "&(|(&(objectCategory=Person)(objectClass=User)(company=○×株式会社))(objectClass=computer))(lastLogon<=129249216000000000)"`) Do @dsmove %i -newparent "OU=利用していないアカウント,DC=marubatsucorp,DC=local"

実行結果

実行結果

実行結果

このコマンドは,まずdsadd ouコマンドで新しいOU(利用していないアカウント)を"DC=marubatsucorp,DC=local"に作成し,dsquery *コマンドで,会社名(company)に"○×株式会社"が含まれるユーザオブジェクトとすべてのコンピュータオブジェクトについて,最終ログオン時間(lastLogon)が"2010年7月30日9:00:00"以前のオブジェクトを検索して,dsmoveコマンドで該当するオブジェクトを移動します。

通常DS*コマンドはパイプラインによる引数の引き渡しができますが,コマンドによってうまくいかないことがあります。このようなときには,For /Fコマンドを利用することで,引数を適切に引き渡すことができます。ここでは,dsquery *コマンドの結果(複数行のDN)をひとつずつ%iに代入し,Do [dsmoveコマンド]の適切な位置で変数を利用することで,コマンドを実現させています(くわしくはFor /?コマンドヘルプをご覧ください)⁠

明示的なログオン時間をしきい値としたい場合,lastLogonまたはlastLogonTimestamp属性を検索条件に加える必要があります。lastLogon属性の時刻は,1601年1月1日を起点に100ナノ秒単位の累積時間で表現されますので,しきい値の設定には計算が必要です(簡単なチェックにはw32tm /ntteコマンドが便利です)⁠またlastLogon属性はドメインコントローラ間で複製を行なわない(ドメインコントローラごとに異なる)ので,どのドメインコントローラでも同じ値が必要な場合lastLogonTimestamp属性を使います。ただしlastLogonTimestamp属性にはいくつかの制限がある(Windows Server 2003ドメイン機能レベルで動作する,必ずしも最新のログオン時間を表していない等)ので,注意してください。

dsquery * "OU=利用していないアカウント,DC=marubatsucorp,DC=local" -filter "&(!objectClass=organizationalUnit)(whenChanged<=20100730000000.0Z)"|dsrm -noprompt

dsquery *コマンドで"OU=利用していないアカウント,DC=marubatsucorp,DC=local"ディレクトリ内の,オブジェクトクラスがOU以外でwhenChanged属性が"2010年7月30日00:00:00(GMT時間)"以前のものを検索し,dsrmコマンドで削除します。

whenChanged属性は,オブジェクトに直接紐付いた任意の属性が変更されたときにその時刻が記録されます。ログオンやパスワードの変更も含め,オブジェクトに何か変更が加えられた時刻を確認するときに利用します。なお,whenChanged属性は国際標準時で時刻が設定されますので,OSのタイムゾーン設定に添った調整が必要です。うえのコマンドの場合,日本のタイムゾーン(GMT+9:00)であれば"2010年7月30日09:00:00"がしきい値になります。

Column:PowerShell 2.0を使ったオブジェクトの管理

Windows Server 2008 R2では,DS*コマンドのほかPowerShell 2.0を使ったActive Directoryの管理を行なうことができます。PowerShellではコマンドレットと呼ばれる専用コマンドを使って,Actice Directoryの各種オブジェクトの新規作成/変更/削除やActive Directoryの自身の設定を行なうことができます。

多くの種類のコマンドレットがあるのでくわしい紹介はできませんが,PowerShellでしか設定できないコマンドレット(細かい設定が可能なパスワードポリシーを設定するSet-ADFineGrainedPasswordPolicyや,Active Directoryごみ箱機能(Recycle Bin)を設定するEnable-ADOptionalFeature等)があること,マイクロソフトの戦略として今後はPowerShellスクリプト技術を中心に展開していくことを考えれば,PowerShellを使ったスクリプト技術を習得しておくことは,非常に重要です。

Active Directoryのコマンドレットにどのようなものがあるのか,から知りたいのであれば,Windows Server 2008 R2ドメインコントローラで[PowerShell]のシェルを起動して,次のコマンドレットを実行すれば,最初の疑問は解決するでしょう。

Import-Module ActiveDirectory
Get-Command -Module ActiveDirectory|Foreach-Object {Get-Help $_.Name|Select-Object Name,Synopsis}

実行結果

実行結果

著者プロフィール

小鮒通成(こぶなみちなり)

Active DirectoryおよびWindows Serverに関するコンサルタント。あわせて各種コミュニティ活動や執筆活動を行っており,Microsoft Most Valuable Professional (Windows Server System - Directory Services) 表彰を5年連続で受けている。現在はNTTデータ先端技術株式会社に勤務。