
Scripting Guruの
BillITwartは、
WindowsITProに関する彼の
記事で 、Active Directoryグループのユーザーメンバーシップを表示するPowershellスクリプトを作成する際に直面した問題について説明
しています 。 すべてが正常に機能するように、4つの改善を行う必要がありました。 Billがグループメンバーシップの結論をどのように実装したかを知ることができ、Powershellスクリプト自体をダウンロードしてダウンロードできます。
スクリプトの最終バージョンへのリンク。www.windowsitpro.com/content/content/141463/141463.zip私は数を失い、フォーラムで「ADドメインのすべてのユーザーとそのグループメンバーシップに関する情報を取得する方法を誰もが知っていますか?」という質問に何度も会いました。 監査員と情報セキュリティコンサルタントも、組織内のActive Directoryインフラストラクチャ(環境)を評価するときに同様の質問をします。 この問題は非常に緊急であるため、このタスクを簡素化するPowerShellスクリプトを作成することにしました。
最初は、似たようなスクリプトを書くのは些細なことだと思っていましたが、4つの障害が私のやり方で出くわし、仕事が複雑になりました。 これらの問題については後ほど説明しますが、最初に、ADを検索するときにPowershellでMicrosoft.NETを使用する基本についてお話したいと思います。
AD検索に.NETを使用する
.NETを使用してADを検索すると、PowerShellのタイプアクセラレータを使用してオブジェクトを検索できます。 (タイプアクセラレータは.NETクラスの短縮名です)。 たとえば、このドメインのすべてのユーザーをリストするには、次のコマンドを入力します。
PS C:\> $searcher = "(&(objectCategory=user)(objectClass=user))" PS C:\> $searcher.FindAll()
[ADSISearcher]は、.NET System.DirectoryServices.DirectorySearcher .NETオブジェクトの型アクセラレータです。 このタイプのアクセラレータに続く行は、このオブジェクトの
SearchFilterプロパティを設定してすべてのユーザーオブジェクトを検索し、
FindAllメソッドが検索を開始します。 出力で、
System.DirectoryServices.SearchResultオブジェクトのリストを取得します。
次に、ユーザーが属しているグループを判別します。 調べるには、
SearchResultオブジェクトのPropertiesコレクションを使用して、memberofなどのオブジェクト属性を取得します。 前の例の$ searcher変数を使用して、
FindAllメソッドの代わりに
FindOneメソッドを使用して、単一の結果を抽出し、グループのユーザーメンバーシップを推測できます。
PS C:\> $result = $searcher.FindOne() PS C:\> $result.Properties["memberof"] | sort-object
最初のコマンドは検索フィルターに一致する最初のユーザーを検索し、2番目のコマンドはユーザーが所属するグループをリストします。
ただし、このリストをよく見ると、重要な詳細が
欠落していることが
わかります。ユーザーのプライマリグループは
memberof属性に含まれていません。 グループ(メイングループを含む)の完全なリストを取得したいので、最初の問題につながります。
問題#1:メインユーザーグループを見つける方法
memberof属性からメイングループを除外する回避策があります。 この記事では、
support.microsoft.com / kb / 321360で説明されています。次の手順
を実行します。
- (LDAPプロバイダーの代わりに)WinNTプロバイダーを使用してユーザーオブジェクトに接続(接続)します。
- ユーザー属性primaryGroupIDを取得します。
- メイングループを含むWinNTプロバイダーを使用してユーザーグループ名を取得します。
- sAMAccountName属性を使用してこれらのグループのADを検索します。
- primaryGroupToken属性がユーザー属性primaryGroupIDと一致するグループを見つけます。
この「回避策」の問題は、ユーザーオブジェクトに接続するためにWinNTプロバイダースクリプトが必要なことです。 つまり、スクリプトは識別されたユーザー名(CN = Ken Myer、OU = Marketing、DC = fabrikam、DC = com)をWinNTプロバイダーが使用できる形式(WinNT:// FABRIKAM / kenmyerなど)に変換する必要がありますユーザー)。
問題#2:ある名前形式から別の形式への変換
NameTranslateオブジェクトは、ADオブジェクトの名前を変数(代替)形式に変換する
IADsNameTranslateインターフェイスを使用するCOM(ActiveX)オブジェクトです。
NameTranslateオブジェクトを使用するには、オブジェクトを作成し、そのInitメソッドを呼び出して初期化します。 たとえば、リスト1は、
NameTranslateが作成および初期化するスクリプトのVBScriptコードを示しています。
リスト1:VBScriptでNameTranslateを作成および初期化する
Const ADS_NAME_INITTYPE_GC = 3 Dim NameTranslate Set NameTranslate = CreateObject("NameTranslate") NameTranslate.Init ADS_NAME_INITTYPE_GC, vbNull
ただし、図1に示すように、PowerShellでは
NameTranslateオブジェクト
が期待どおりに機能
しません。

図1:PowerShellでのNameTranslateの予期しない動作
問題は、
NameTranslateオブジェクトに
は 、.NET(およびPowerShell)がCOMオブジェクトへの簡単なアクセスを提供するために使用するタイプライブラリ
がないことです。 しかし、幸いなことに、この問題は回避できます
。.NETInvokeMemberメソッドを使用すると、PowerShellでプロパティを取得または設定したり、タイプライブラリにないCOMオブジェクトからメソッドを呼び出したりできます。 リスト2は、表1のVBScriptコードに相当するPowershellを示しています
リスト2:PowerShellでNameTranslateオブジェクトを作成および初期化する
$ADS_NAME_INITTYPE_GC = 3 $NameTranslate = new-object -comobject NameTranslate [Void] $NameTranslate.GetType().InvokeMember("Init", "InvokeMethod", $NULL, $NameTranslate, ($ADS_NAME_INITTYPE_GC, $NULL))
名前に関連する別の問題をスクリプトで解決したかったのです。 ユーザーADの
memberof属性には、ユーザーがメンバーである識別名のリストが含まれていますが、代わりに各グループのsamaccountname属性を取得したかったです。 このスクリプトは、
NameTranslateオブジェクトを使用してこの問題に対処します。
問題#3:特殊文字の処理
識別名に関するMicrosoftのドキュメントでは、個々の文字を正しく解釈するには(たとえば、「\」の接頭辞を付けて)省略しなければならないことが記載されています(
この記事の詳細)。 幸いなことに、Pathname COMオブジェクトはこの機能を提供します。 スクリプトは
Pathnameオブジェクトを使用して、特殊文字を含むこれらの識別名をスキップします。
NameTranslateオブジェクトと同様に、このオブジェクトにはタイプライブラリがないため、
Pathnameオブジェクトには.NET
InvokeMemberメソッドも必要です。
問題4:生産性の向上
問題#1(メインユーザーグループの検索方法)を見ると、回避策にはユーザーグループの検索が必要であることがわかります。 複数のアカウントに対してこの手順を実行すると、どのように最適ではないかを理解できます。 問題#2(名前の形式から別の形式への変換)を検討しながら言及した
memberof属性内の各グループの
samaccountname属性を取得することも、最適ではなく、時間がかかります。 この問題を解決するために、スクリプトは結果をハッシュしてパフォーマンスを向上させる2つのグローバルハッシュテーブルを使用します。
Get-UsersAndGroups.ps1
Get-UsersAndGroups.ps1は、ユーザーとそのグループメンバーシップのリストを表示する既製の
Powershellスクリプトです。 スクリプトのコマンドライン構文は次のとおりです。
Get-UsersAndGroups [[-SearchLocation] <String[]>] [-SearchScope <String>]
-SearchLocationパラメーターは、ユーザーアカウントの1つ以上の識別名です。 識別名にはカンマ(、)が含まれているため、PowerShellが配列として解釈しないように、識別名ごとに括弧(単一または二重)で囲む必要があります。 パラメーター名
-SearchLocationはオプションです。 スクリプトはパイプライン入力も受け入れます。 パイプラインの各値は、検索する識別名である必要があります。
値
-SearchScopeは、AD検索の可能なスケールを示します。 この値は次の3つのうちの1つである必要があります。
ベース -検索はベースオブジェクトに制限され、使用されません。
OneLevel-ベースオブジェクトと
Subtreeの最も
近い子オブジェクトの検索-バックライトによる検索。 この値が指定されていない場合、デフォルトでサブツリーが使用されます。 特定の
組織単位(OU)が必要であるが、その中にネストされているOUがない場合は、
-SearchScope OneLevelを使用します。 スクリプトは、表1にリストされているプロパティを含むオブジェクトを表示します。

4つの課題を克服する
スクリプトは上記の問題を解決します。
- 問題#1:プライマリユーザーグループを見つける方法: get-primarygroupname関数は、プライマリユーザーグループの名前を返します。
- 問題#2:ある名前形式から別の名前形式への変換:スクリプトはNameTranslate COMオブジェクトを使用して、ある名前形式から別の名前形式に変換します。
- 問題#3:特殊文字の処理:スクリプトはget-escaped関数を使用します 。この関数は、 Pathnameオブジェクトを使用して、欠落文字が挿入された識別名を返します(必要な場合)。
- 問題#4:パフォーマンスの向上:スクリプトはハッシュテーブル$ PrimaryGroupsおよび$ Groupsを使用します 。 $ PrimaryGroupsハッシュテーブルのキーはメイングループの識別子であり、その値はメイングループのsamaccountnameの属性です。
グループとユーザーの監査を簡素化する
Get-UsersAndGroups.ps1スクリプトの記述は、一見すると単純ではないように思えましたが、簡単ではありませんでした。 最も単純なスクリプトアプリケーションは次のコマンドです。
PS C:\> Get-UsersAndGroups | Export-CSV Report.csv -NoTypeInformation
特定のドメインのユーザーとグループの完全なリストを含む.csvファイルを作成します。 武器の名前はそのようなスクリプトです。グループやユーザーごとにレポートをすばやく簡単に作成できます。
もう一度、リンクをスクリプトの最終バージョンに複製します。www.windowsitpro.com/content/content/141463/141463.zipスクリプト自体: # Get-UsersAndGroups.ps1 # Written by Bill Stewart (bstewart@iname.com) #requires -version 2 <# .SYNOPSIS Retreves users, and group membership for each user, from Active Directory. .DESCRIPTION Retreves users, and group membership for each user, from Active Directory. Note that each user
WindowsITPro経由PS NetWrix AD Change Reporterを使用して、ADの構造と変更に関するさまざまなレポートを取得できます。 このプログラムを使用すると、ADの変更に遅れずについていくことができ、同時にログを使用した面倒な作業やスクリプトによる手動の自動化が不要になります。 NetWrix Webサイトでプログラムの詳細を確認できます。