C# Active Directory - 如何从注册服务目录对象加载 "certificateTemplates" 属性?
C# Active Directory - How can I load the "certificateTemplates" Property from an Enrollment Services directory object?
我正在尝试通过循环访问注册服务 AD 容器从我的 AD 林加载有关 Microsoft PKI 颁发 CA 的详细信息。我想包括的细节之一是在每个 CA 上启用的证书模板列表。在 ADSIEdit 中,我可以清楚地看到每个注册服务对象中都有一个名为 certificateTemplates 的 属性,其中包含我需要的信息(请原谅所有编辑):
但是,当我将这些对象中的任何一个拉入 .NET DirectoryEntry 对象时,"certificateTemplates" 不是默认包含的属性之一。我发现了 RefreshCache method,它应该允许您从目录条目中提取其他属性(只要它们存在于条目中),但这对我不起作用:
DirectoryEntry EnrollmentServices = new DirectoryEntry($"LDAP://{MyDC}/CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=example,DC=com");
DirectoryEntries CAs = EnrollmentServices.Children;
foreach(DirectoryEntry CA in CAs)
{
object[] objectClass = (object[])CA.Properties[objectClassProperty].Value;
if (objectClass[1].ToString() == @"pKIEnrollmentService")
{
CA.RefreshCache(new string[] { "certificateTemplates" });
var Templates = CA.Properties["certificateTemplates"].Value;
//Templates remains null
}
}
有人encountered/resolved遇到过这个问题吗?
RefreshCache() 方法实际上正确地将 certificateTemplates 属性 添加到每个 CA DirectoryEntry 对象。在我的循环中遇到的第一个 CA 根本没有分配模板,这解释了在我的 foreach 循环的第一次迭代中 Templates 的空值。
更新: 如果 certificateTemplates 属性 仅包含一个条目,则 属性 值将是单个字符串而不是仅包含 1 个元素的数组(谢谢,微软!)。我使用 try/catch 来处理这种边缘情况。如果有人有更优雅的方法,请成为我的客人。
DirectoryEntry EnrollmentServices = new DirectoryEntry($"LDAP://{MyDC}/CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=example,DC=com");
DirectoryEntries CAs = EnrollmentServices.Children;
List<string> templateNames;
foreach(DirectoryEntry CA in CAs)
{
object[] objectClass = (object[])CA.Properties[objectClassProperty].Value;
if (objectClass[1].ToString() == @"pKIEnrollmentService")
{
CA.RefreshCache(new string[] { "certificateTemplates" });
object[] Templates;
try
{
Templates = (object[])CAEntry.Properties[PropertyIndex.CertificateTemplates].Value;
}
catch (InvalidCastException)
{
Templates = new object[] { CAEntry.Properties[PropertyIndex.CertificateTemplates].Value };
}
//I place the template names into a string list for ease of retrieval later.
templateNames = new List<string>();
if (Templates != null)
{
for (int x = 0; x < Templates.Length; x++) templateNames.Add(Templates[x].ToString());
}
}
}
我正在尝试通过循环访问注册服务 AD 容器从我的 AD 林加载有关 Microsoft PKI 颁发 CA 的详细信息。我想包括的细节之一是在每个 CA 上启用的证书模板列表。在 ADSIEdit 中,我可以清楚地看到每个注册服务对象中都有一个名为 certificateTemplates 的 属性,其中包含我需要的信息(请原谅所有编辑):
但是,当我将这些对象中的任何一个拉入 .NET DirectoryEntry 对象时,"certificateTemplates" 不是默认包含的属性之一。我发现了 RefreshCache method,它应该允许您从目录条目中提取其他属性(只要它们存在于条目中),但这对我不起作用:
DirectoryEntry EnrollmentServices = new DirectoryEntry($"LDAP://{MyDC}/CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=example,DC=com");
DirectoryEntries CAs = EnrollmentServices.Children;
foreach(DirectoryEntry CA in CAs)
{
object[] objectClass = (object[])CA.Properties[objectClassProperty].Value;
if (objectClass[1].ToString() == @"pKIEnrollmentService")
{
CA.RefreshCache(new string[] { "certificateTemplates" });
var Templates = CA.Properties["certificateTemplates"].Value;
//Templates remains null
}
}
有人encountered/resolved遇到过这个问题吗?
RefreshCache() 方法实际上正确地将 certificateTemplates 属性 添加到每个 CA DirectoryEntry 对象。在我的循环中遇到的第一个 CA 根本没有分配模板,这解释了在我的 foreach 循环的第一次迭代中 Templates 的空值。
更新: 如果 certificateTemplates 属性 仅包含一个条目,则 属性 值将是单个字符串而不是仅包含 1 个元素的数组(谢谢,微软!)。我使用 try/catch 来处理这种边缘情况。如果有人有更优雅的方法,请成为我的客人。
DirectoryEntry EnrollmentServices = new DirectoryEntry($"LDAP://{MyDC}/CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=example,DC=com");
DirectoryEntries CAs = EnrollmentServices.Children;
List<string> templateNames;
foreach(DirectoryEntry CA in CAs)
{
object[] objectClass = (object[])CA.Properties[objectClassProperty].Value;
if (objectClass[1].ToString() == @"pKIEnrollmentService")
{
CA.RefreshCache(new string[] { "certificateTemplates" });
object[] Templates;
try
{
Templates = (object[])CAEntry.Properties[PropertyIndex.CertificateTemplates].Value;
}
catch (InvalidCastException)
{
Templates = new object[] { CAEntry.Properties[PropertyIndex.CertificateTemplates].Value };
}
//I place the template names into a string list for ease of retrieval later.
templateNames = new List<string>();
if (Templates != null)
{
for (int x = 0; x < Templates.Length; x++) templateNames.Add(Templates[x].ToString());
}
}
}