C#を使用したグループのポリシー設定を読む
-
24-10-2019 - |
質問
ADドメインの特定のGPO(名前またはGUIDを使用)で利用可能な設定および/または設定を繰り返して回避するにはどうすればよいですか? PowerShellなどを使用してXML/HTMLにエクスポートする必要なく。
C#(.NET 4.0)を使用しています。
解決
その質問は私に誇大宣伝されたので、私はそれを研究に行きました。だから+1
私が一番上から最悪の状態であると私が見つけたいくつかの解決策
他のヒント
同様の問題があり、Microsoft GPOライブラリ(Microsoft.Grouppolicy.Management)をダウンロードしてインストールしたくありませんでした。 System.DirectoryServicesですべてをやりたかったのです。少し掘り下げましたが、それを行うことができます。
最初にdirectorysearcherを使用してコンテナを取得します。検索者に渡すには、すでにディレクトリエントリを開設している必要があります。あなたが望むフィルターは次のとおりです。
string filter = "(&" + "(objectClass=organizationalUnit)" + "(OU=" + container + "))";
そして、あなたが興味を持っているプロパティは「gplink」という名前ですので、そのプロパティを含む配列を作成します。
string[] requestProperties = { "gPLink" };
次に、結果を取得し、利用可能な場合はGPLINKを引き出します。
using (var searcher = new DirectorySearcher(directory, filter, properties, SearchScope.Subtree))
{
SearchResultCollection results = searcher.FindAll();
DirectoryEntry entry = results[0].GetDirectoryEntry();
string gpLink = entry.Properties["gPLink"].Value;
gplinkがnullの場合、コンテナ(ou)に関連するGPOはありません。それ以外の場合、gplinkには次のような文字列が含まれます。
"[LDAP://cn={31B2F340-016D-11D2-945F-00C04FB984F9},cn=policies,cn=system,DC=Test,DC=Domain;0]"
上記のテキストでは、GPOのCNを見ることができます。今やらなければならないのは、DCからGPOを取得することだけです。
そのためには、次のようなフィルターを使用します。
string filter = "(&" +
"(objectClass=groupPolicyContainer)" +
"(cn={31B2F340-016D-11D2-945F-00C04FB984F9}))";
以下を含むプロパティアレイを作成する必要があります。
Properties = { "objectClass", "cn", "distinguishedName", "instanceType", "whenCreated",
"whenChanged", "displayName", "uSNCreated", "uSNChanged", "showInAdvancedViewOnly",
"name", "objectGUID", "flags", "versionNumber", "systemFlags", "objectCategory",
"isCriticalSystemObject", "gPCFunctionalityVersion", "gPCFileSysPath",
"gPCMachineExtensionNames", "dSCorePropagationData", "nTSecurityDescriptor" };
次に、DirectorySearcherを使用してGPOを取得します。 Properties Collectionの上記のすべてのフィールドを含む結果のDirectoryEntryを取り戻すことができます。一部はcomオブジェクトなので、それらを適切に処理する必要があります。
以下は、上記よりも優れた完全な例です。
class Program
{
static void Main(string[] args)
{
DirectoryEntry rootDse = new DirectoryEntry("LDAP://rootDSE");
DirectoryEntry root = new DirectoryEntry("GC://" + rootDse.Properties["defaultNamingContext"].Value.ToString());
DirectorySearcher searcher = new DirectorySearcher(root);
searcher.Filter = "(objectClass=groupPolicyContainer)";
foreach (SearchResult gpo in searcher.FindAll())
{
var gpoDesc = gpo.GetDirectoryEntry().Properties["distinguishedName"].Value.ToString();
Console.WriteLine($"GPO: {gpoDesc}");
DirectoryEntry gpoObject = new DirectoryEntry($"LDAP://{gpoDesc}");
try
{
Console.WriteLine($"DisplayName: {gpoObject.Properties["displayName"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"PCFileSysPath: {gpoObject.Properties["gPCFileSysPath"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"VersionNumber: {gpoObject.Properties["versionNumber"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"UserExtensionNames: {gpoObject.Properties["gPCUserExtensionNames"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"MachineExtensionNames: {gpoObject.Properties["gPCMachineExtensionNames"].Value.ToString()}");
}
catch
{
}
try
{
Console.WriteLine($"PCFunctionality: {gpoObject.Properties["gPCFunctionalityVersion"].Value.ToString()}");
}
catch
{
}
}
Console.ReadKey();
}
}
更新:作業コピー。これで、C#を使用して、PowerShellを使用したり、何かをディスクに書いたりすることなく、特定のGPOを読み取り、解析できます。
using Microsoft.GroupPolicy;
var guid = new Guid("A7DE85DE-1234-F34D-99AD-5AFEDF7D7B4A");
var gpo = new GPDomain("Centoso.local");
var gpoData = gpo.GetGpo(guid);
var gpoXmlReport = gpoData.GenerateReport(ReportType.Xml).ToString();
using (XmlReader reader = XmlReader.Create(new StringReader(gpoXmlReport)))
{
string field;
while (reader.MoveToNextAttribute())
{
foreach (string attr in attributes)
{
// do something
}
}
}
これは、グループポリシー管理コンソール(GPMC)ツールを使用します。https://msdn.microsoft.com/en-us/library/windows/desktop/aa814316(v=vs.85).aspx
Microsoft.Grouppolicyネームスペースhttps://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.grouppolicy(v=vs.85).aspx