<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Vadims Podans's blog - PowerShell | Certificate Authority</title>
    <link>http://www.sysadmins.lv/</link>
    <description>PowerShell powered</description>
    <image>
      <url>http://www.sysadmins.lv/images/imgusr/bilde.jpg</url>
      <title>Vadims Podans's blog - PowerShell | Certificate Authority</title>
      <link>http://www.sysadmins.lv/</link>
    </image>
    <language>en-us</language>
    <copyright>Vadims Podāns</copyright>
    <lastBuildDate>Sat, 03 Jul 2010 19:48:17 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>vpodans@sysadmins.lv</managingEditor>
    <webMaster>vpodans@sysadmins.lv</webMaster>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=2c2eef6f-34ae-42cb-8ded-318e96f63f8c</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,2c2eef6f-34ae-42cb-8ded-318e96f63f8c.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,2c2eef6f-34ae-42cb-8ded-318e96f63f8c.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=2c2eef6f-34ae-42cb-8ded-318e96f63f8c</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>Программная обработка запросов сертификатов в папке Pending Requests</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,2c2eef6f-34ae-42cb-8ded-318e96f63f8c.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,2c2eef6f-34ae-42cb-8ded-318e96f63f8c.aspx</link>
      <pubDate>Sat, 03 Jul 2010 19:48:17 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;Как известно, когда запрос попадает в папку Pending Requests, администратор CA должен что-то с ним явно сделать — или одобрить или отклонить. Это можно сделать при помощи оснастки CetSrv.msc или при помощи PowerShell. Ещё можно через certutil, но речь сегодня не о нём. Если вспомнить предыдущие посты посвящённые &lt;a href="http://www.sysadmins.lv/CategoryView,category,PowerShellCryptoAPI.aspx"&gt;CryptoAPI и PowerShell&lt;/a&gt;, можно вспомнить какие-то основные принципы. Как обычно, мы будем использовать интерфейс &lt;a href="http://msdn.microsoft.com/en-us/library/aa383234(VS.85).aspx" target="_blank"&gt;ICertAdmin2&lt;/a&gt;. Для аппрува соответствующих запросов необходимо воспользоваться методом &lt;img src="http://i.msdn.microsoft.com/Global/Images/clear.gif" /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa383250(VS.85).aspx" target="_blank"&gt;ResubmitRequest()&lt;/a&gt;. Как вы видите, метод принимает 2 аргумента:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;code&gt;HRESULT ResubmitRequest(        &lt;br /&gt;&lt;strong&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;&lt;/code&gt;&lt;code&gt;&lt;strong&gt;[in] const BSTR strConfig,          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/strong&gt;&lt;/code&gt;&lt;code&gt;&lt;strong&gt;[in] LONG RequestId,          &lt;br /&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160; [out, retval] LONG *pDisposition         &lt;br /&gt;);&lt;/code&gt;&amp;#160;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;это конфигурационная строка CA вида: CAComputerName\CAName и номер запроса. И в ответ метод возвращает результат выполнения операции. Вот как это можно аккуратно сделать в PowerShell:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;Issue-PendingRequest&lt;/span&gt;&lt;span style="color: #000000"&gt; {
[CmdletBinding()]
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;param&lt;/span&gt;&lt;span style="color: #000000"&gt;(
        [Parameter(Mandatory &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;, ValueFomPipeline &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;)]
        [&lt;font color="#008080"&gt;string&lt;/font&gt;]&lt;/span&gt;&lt;span style="color: #800080"&gt;$CAConfig&lt;/span&gt;&lt;span style="color: #000000"&gt;,
        [Parameter(Mandatory &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;)]
        [&lt;/span&gt;&lt;span style="color: #008080"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800080"&gt;$RequestID&lt;/span&gt;&lt;span style="color: #000000"&gt;
    )
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800080"&gt;$CertAdmin&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;New-Object&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ComObject&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;CertificateAuthority.Admin&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Warning&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Unable to instantiate ICertAdmin2 object!&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;span style="color: #000000"&gt; {
        &lt;/span&gt;&lt;span style="color: #800080"&gt;$status&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;switch&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$CertAdmin&lt;/span&gt;&lt;span style="color: #000000"&gt;.ResubmitRequest(&lt;/span&gt;&lt;span style="color: #800080"&gt;$CAConfig&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #800080"&gt;$RequestID&lt;/span&gt;&lt;span style="color: #000000"&gt;)) {
            &lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The request was not completed.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
            &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The request failed.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
            &lt;/span&gt;&lt;span style="color: #000000"&gt;2&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The request was denied&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
            &lt;/span&gt;&lt;span style="color: #000000"&gt;3&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The certificate was issued.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
            &lt;/span&gt;&lt;span style="color: #000000"&gt;4&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The certificate was issued separately.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
            &lt;/span&gt;&lt;span style="color: #000000"&gt;5&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The request was taken under submission.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
            &lt;/span&gt;&lt;span style="color: #000000"&gt;6&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The certificate is revoked.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
        }
    }
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Host&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Operation status for the request '$RequestID': $ststus&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
}&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Для отклонения запроса, следует воспользоваться методом &lt;a href="http://msdn.microsoft.com/en-us/library/aa383236(VS.85).aspx" target="_blank"&gt;DenyRequest()&lt;/a&gt;. Как и метод ResubmitRequest тоже принимает всего 2 аргумента, но кроме ошибок ничего не возвращает:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code&gt;HRESULT DenyRequest( 
      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [in] const BSTR strConfig, 

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [in] Long RequestId 

      &lt;br /&gt;);&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;И код будет очень похож на предыдущий:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;Deny-PendingRequest&lt;/span&gt;&lt;span style="color: #000000"&gt; {
[CmdletBinding()]
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;param&lt;/span&gt;&lt;span style="color: #000000"&gt;(
        [Parameter(Mandatory &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;, ValueFomPipeline &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;)]
        [&lt;font color="#008080"&gt;string&lt;/font&gt;]&lt;/span&gt;&lt;span style="color: #800080"&gt;$CAConfig&lt;/span&gt;&lt;span style="color: #000000"&gt;,
        [Parameter(Mandatory &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;)]
        [&lt;/span&gt;&lt;span style="color: #008080"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800080"&gt;$RequestID&lt;/span&gt;&lt;span style="color: #000000"&gt;
    )
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800080"&gt;$CertAdmin&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;New-Object&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ComObject&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;CertificateAuthority.Admin&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Warning&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Unable to instantiate ICertAdmin2 object!&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800080"&gt;$CertAdmin&lt;/span&gt;&lt;span style="color: #000000"&gt;.DenyRequest(&lt;/span&gt;&lt;span style="color: #800080"&gt;$CAConfig&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #800080"&gt;$RequestID&lt;/span&gt;&lt;span style="color: #000000"&gt;)}
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Host&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Successfully denied request '$RequestID'&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
}&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;вот так легко можно программным способом управлять реквестами из папки Pending Requests без графических оснасток или certutil. Что касается certutil, я не уверен, что он сможет заапрувить или отклонить реквест на удалённом CA. У него есть параметр –config, но я не уверен, что он работает в данном случае. Плюс, когда я выложу в общий доступ свой PS модуль для PKI, эта операция будет ещё проще. Вам не придётся вручную набивать конфигурационную строку, а просто воспользоваться командой Get-CertificationAuthority.&lt;/p&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=2c2eef6f-34ae-42cb-8ded-318e96f63f8c"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,2c2eef6f-34ae-42cb-8ded-318e96f63f8c.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
      <category>PowerShell / CryptoAPI</category>
    </item>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=2dc109a8-2a1a-4091-9a0d-eb28f4c87159</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,2dc109a8-2a1a-4091-9a0d-eb28f4c87159.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,2dc109a8-2a1a-4091-9a0d-eb28f4c87159.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=2dc109a8-2a1a-4091-9a0d-eb28f4c87159</wfw:commentRss>
      <title>Active Directory PKI object management с помощью PowerShell (часть 3)</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,2dc109a8-2a1a-4091-9a0d-eb28f4c87159.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,2dc109a8-2a1a-4091-9a0d-eb28f4c87159.aspx</link>
      <pubDate>Mon, 14 Dec 2009 18:47:12 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;Продолжаем серию постов, которые посвящены базовому управлению объектами PKI в Active Directory. На данный момент мы рассмотрели сценарии публикации и просмотра сертификатов в Active Directory:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.sysadmins.lv/PermaLink,guid,dd03c789-780d-4b39-9b7b-310905ecde32.aspx"&gt;Active Directory PKI object management с помощью PowerShell&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.sysadmins.lv/PermaLink,guid,55c5304e-baef-4af6-bc0f-e09c214fb630.aspx"&gt;Active Directory PKI object management с помощью PowerShell (часть 2)&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;На данном этапе нам осталось последнее — удаление сертификатов из AD. Логика здесь очень простая: командой &lt;strong&gt;Get-ADPKIObject&lt;/strong&gt; мы получаем коллекцию объектов, которые представляют собой сертификаты и через конвейер командой &lt;strong&gt;Remove-ADPKIObject&lt;/strong&gt; указываем &lt;strong&gt;ID&lt;/strong&gt; объектов, которые необходимо удалить. Если кто-то уже разбирал код предыдущих скриптов, то ему будет совсем нетрудно понять логику скрипта удаления объектов. Вот он, вместе с комментариями:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;Remove-ADPKIObject&lt;/span&gt;&lt;span style="color: #000000"&gt; {
&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;lt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;
.Synopsis
    Deletes certificates from Active Directory containers
.Description
    Deletes certificates from Active Directory containers by specifying particular ID or IDs
.Parameter ID
    Specifies certificate ID to delete that was set in Get-ADPKIObject command.
.EXAMPLE
    Get-ADPKIObject RootCA | Remove-ADPKIObject 2
    
    deletes certificate with ID = 2 in certificate viewer
.Outputs
    This command provide a resultant of operation.
&lt;/span&gt;&lt;span style="color: #008000"&gt;#&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;param&lt;/span&gt;&lt;span style="color: #000000"&gt;([&lt;/span&gt;&lt;span style="color: #008080"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;[]]&lt;/span&gt;&lt;span style="color: #800080"&gt;$ID&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; $(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;you must specify number of the object to delete&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;))
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; объявляем массив для хранения сертификатов из контейнера NTAuthCertificates&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;begin&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800080"&gt;$sum&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; @()}
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;process&lt;/span&gt;&lt;span style="color: #000000"&gt; {
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; проверяем тип контейнера входящего объекта&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.Container &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-ne&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;NTAuthCertificates&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если это не NTAuthCertificates, то проверяем, что ID текущего объекта&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; совпадает с ID, который нужно удалить&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (@(&lt;/span&gt;&lt;span style="color: #800080"&gt;$ID&lt;/span&gt;&lt;span style="color: #000000"&gt;) &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-contains&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.Id) {
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если совпал, то собираем LDAP-запрос&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; [&lt;/span&gt;&lt;span style="color: #008080"&gt;ADSI&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;LDAP://CN=$($_.Container),$script:ConfigContext&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; и удаляем текущий объект из AD&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$retn&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.Delete(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;certificationAuthority&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=$($_.Subject)&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #000080"&gt;$?&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
                    &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Host&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;`'$($_.Subject)`' certificate was sucessfully deleted from `'$($_.Container)`' container&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;`&lt;/span&gt;&lt;span style="color: #000000"&gt;
                    &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ForegroundColor&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;Green&lt;/span&gt;&lt;span style="color: #000000"&gt;
                }
            }
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если контейнер текущего объекта является NTAuthCertificates, то собираем их все в массив&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        } &lt;/span&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800080"&gt;$sum&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;+=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    }
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;end&lt;/span&gt;&lt;span style="color: #000000"&gt; {
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; проверяем, что массив непустой (т.е. надо что-то удалять из NTAuthCertificates)&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$sum&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если массив непустой, то выбираем те элементы, которые нужно сохранить&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; т.е. ID которых не содержится в аргументах скрипта&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #800080"&gt;$sum&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; @(&lt;/span&gt;&lt;span style="color: #800080"&gt;$sum&lt;/span&gt;&lt;span style="color: #000000"&gt; |?{&lt;/span&gt;&lt;span style="color: #800080"&gt;$ID&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-notcontains&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.Id})
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; делаем LDAP-запрос к этому контейнеру&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; [&lt;/span&gt;&lt;span style="color: #008080"&gt;ADSI&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;LDAP://CN=$($_.Container),$script:ConfigContext&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; проверяем, что после фильтрации, хотя бы один сертификат нужно оставить&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$sum&lt;/span&gt;&lt;span style="color: #000000"&gt;.count &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-ge&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; записываем первый сертификат. Это необходимо потому что ADSI не поддерживает запись&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; массива сертификатов в свойство cACertificate, а только один сертификат в виде byte[]&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.put(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;cACertificate&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, [&lt;/span&gt;&lt;span style="color: #008080"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]]&lt;/span&gt;&lt;span style="color: #800080"&gt;$sum&lt;/span&gt;&lt;span style="color: #000000"&gt;[0].RawCertificate)
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; а вот простое добавление он поддерживает. Тогда ADSI сам пересоберёт объекты&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; в свойстве в нужный формат данных. На данном этапе я применил маленькую хитрость:&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; как видно, я первый сертификат записываю дважды - предыдущей строкой и в первой итерации&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; текущей строки. Но это не проблема, поскольку метод SetInfo() записывает только уникальные&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; объекты, а дублирующиеся просто отбросит.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$sum&lt;/span&gt;&lt;span style="color: #000000"&gt; | &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;%&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.cACertificate &lt;/span&gt;&lt;span style="color: #ff0000"&gt;+=&lt;/span&gt;&lt;span style="color: #000000"&gt; ,[&lt;/span&gt;&lt;span style="color: #008080"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]]$(&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.RawCertificate)}
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.SetInfo()
                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #000080"&gt;$?&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
                    &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Host&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;`'$($_.Subject)`' certificate was sucessfully deleted from `'$($_.Container)`' container&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;`&lt;/span&gt;&lt;span style="color: #000000"&gt;
                    &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ForegroundColor&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;Green&lt;/span&gt;&lt;span style="color: #000000"&gt;
                }
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; а вот если после фильтрации объектов, у нас ничего не остаётся на запись, то это означает, что все&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; сертификаты из этого контейнера удаляются. Поэтому мы просто удаляем запись NTAuthCertificates.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            } &lt;/span&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;span style="color: #000000"&gt; {
                ([&lt;/span&gt;&lt;span style="color: #008080"&gt;ADSI&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;LDAP://$script:ConfigContext&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;).Delete(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;certificationAuthority&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=NTAuthCertificates&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #000080"&gt;$?&lt;/span&gt;&lt;span style="color: #000000"&gt;) {&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Host&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;All certificates was sucessfully deleted from NTAuthCertificates entry .&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ForegroundColor&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;Green&lt;/span&gt;&lt;span style="color: #000000"&gt;
                    &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Warning&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;This was last certificate in contaner. NTAuthCertificates entry is removed from Active Directory&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                }
            }
        }
    }
}&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;И теперь можно подвести краткие итоги. Мы смогли реализовать функционал certutil и других графических утилит (консоли MMC) в PowerShell значительно улучшив читабельность выходных объектов, адаптировали под работу из консоли (синтаксис стал значимо короче и более юзерфрендли) и шаг за шагом делаем из PowerShell единое консольное средство управления различными аспектами PKI.&lt;/p&gt;

&lt;p&gt;Можно задать вопрос: а кто целевая аудитория всего этого? Целевая аудитория есть — администраторы PKI. Просто у вас не всегда будет возможность использовать графические консоли для решения этих задач (потому что их функционал далёк от идеального). Можно использовать certutil, который умеет много чего, но тоже имеет свои недостатки. Это и ужасный синтаксис, и вырвиглазный неуправляемый вывод результатов. Вобщем я надеюсь, что рано или поздно PowerShell сможет по-настоящему заменить certutil (который вообще-то ни в чём не виноват) и стать единой консолью всех Windows-администраторов. Вот не знаю на сколько это хорошо или плохо, потому что Microsoft всех насильно переводит на PowerShell (это очень показательно продемонстрировано в MS Exchange, где у вас по сути есть только PowerShell и всё). Обычно, насильно переводят на другой инструмент когда он является УГ и очень тяжело на него перевести людей посредством обычной рекламы. Но является ли PowerShell таким УГ? Я пока не готов ответить на этот вопрос. Моё мнение — PowerShell пока что особой революцией не стал. Даже не смотря на тонны рекламы, пеара и прочего, где восхваляют PowerShell, закидывают ногами CMD/WSH. Это обусловлено тем фактом, что не всегда PowerShell бывает удобней CMD/WSH, особенно в тривиальных задачах. Говорить, что синтаксис стал более простым и компактным тоже нельзя, потому что реально функционала из коробки хватает для решения процентов 10 задач. Всё остальное нужно скриптовать и программировать (да-да!) самому. Благо средств для этого в PowerShell хватает. Во что это обычно выливается? А в то, что в большинстве случаев результирующий объём кода будет не сильно меньше, чем в связке WSH + CMD. В любом случае преимущества PowerShell перед остальными очевидны, но они далеко не определяющие, ведь люди раньше решали свои задачи на WSH/CMD, пирожки продавались, бизнес шёл. С одной стороны Microsoft дал людям простор для творчества, т.е. делать в PowerShell всякие потрясающие штуки и всё такое. Но это не совсем то, что нужно было администраторам. Им нужна одна кнопка на весь экран с надписью «Сделать всё п**дато!». Пока что PowerShell и близко не готов стать такой кнопкой, а является «удочкой». Т.е. удочка у вас уже есть, а что касается конечной рыбы (результата), то дело осталось за малым — написать мега-скрипт. Мне вот интересно, что думают администраторы Exchange (поскольку пока что только они получили полноценную поддержку для своего продукта в PowerShell) — стало ли им жить легче с PowerShell или нет? Если да, то это может быть хорошим знаком, что однажды PowerShell станет такой кнопкой. И не будет более в системе certutil и всеми задачами будет рулить PowerShell (пока что это наиболее логичный сценарий развития событий). А вот если их жизнь не стала легче, то обещанной революции (которая по словам Microsoft уже наступила, как и вендекапец у луноходов) не будет, а будет просто какое-то логическое продолжение предыдущих инструментов для сценариев.&lt;/p&gt;

&lt;p&gt;К чему я написал столько букв? К тому, что я ежедневно задаю себе один и тот же вопрос: а зачем я всё это делаю? А ответ найти очень непросто, потому что отмазы вида «проще, удобней, красивее» не годятся для серьёзного аргумента. На самом деле я не ищу ответ на него, а просто говорю себе «так надо» и делаю. Поэтому не надо меня использовать как пример «правильного пользователя PowerShell» и пытаться повторить что-то подобное астрономических масштабов на овер9000 строк — поверьте, оно не стоит того. Используйте его по мере сил. Если чего-то будет не хватать и его решение потребует значительных усилий — посмотрите на готовые утилиты, они наверняка будут уметь то, что вам надо.&lt;/p&gt;

&lt;p&gt;Удачи!© One&lt;/p&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=2dc109a8-2a1a-4091-9a0d-eb28f4c87159"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,2dc109a8-2a1a-4091-9a0d-eb28f4c87159.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
      <category>PowerShell / Certificates</category>
      <category>PowerShell / Certificates / Active Directory</category>
    </item>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=55c5304e-baef-4af6-bc0f-e09c214fb630</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,55c5304e-baef-4af6-bc0f-e09c214fb630.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,55c5304e-baef-4af6-bc0f-e09c214fb630.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=55c5304e-baef-4af6-bc0f-e09c214fb630</wfw:commentRss>
      <title>Active Directory PKI object management с помощью PowerShell (часть 2)</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,55c5304e-baef-4af6-bc0f-e09c214fb630.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,55c5304e-baef-4af6-bc0f-e09c214fb630.aspx</link>
      <pubDate>Fri, 11 Dec 2009 21:09:45 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;В &lt;a href="http://www.sysadmins.lv/PermaLink,guid,dd03c789-780d-4b39-9b7b-310905ecde32.aspx"&gt;&lt;strong&gt;предыдущем посте&lt;/strong&gt;&lt;/a&gt; мы ознакомились с основными контейнерами с объектами PKI в Active Directory и смогли изучить функциональный аналог ключа dspublish в утилите certutil. Если публикация сертификатов в AD задача простая даже для Certutil, то просмотр содержимого может быть весьма нетривиальным. Например, если вы хотите посмотреть содержимое записи NTAuthCertificates, то придётся выполнить вот такую команду:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;certutil –viewstore &amp;quot;CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration, ForestRootDomainDN&amp;quot;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;такие вещи совершенно неприспособлены к командной строке, поскольку надо набирать много текста и ошибиться весьма просто. Одно хорошо, команда выводит графическое окошко, где мы можем посмотреть содержимое. Но тут есть несколько неудобных моментов: мы не можем посмотреть несколько контейнеров сразу, для каждого контейнера надо выполнять отдельную команду. В этом окошке мы можем только посмотреть на содержимое контейнера и всё. Ни добавить, ни удалить сертификат мы не можем. Для добавления сертификатов мы можем воспользоваться тем же certutil или моим скриптом, который был опубликован в предыдущем посте. Графика — хорошо и замечательно, но мы можем хотеть автоматизировать какие-то задачи или просто посмотреть информацию в консоли. Вы можете подумать, что это не нужно, но преимущество между консольным выводом и графическим диалоговым окном очевидное: из первого можно копировать информацию в буфер обмена. Есть ещё вариант — для просмотра и удаления сертификатов из AD, пользоваться консолью pkiview.msc. Но мы сразу же теряем главную нить — единое средство управления. Т.е. даже похожие операции мы должны выполнять в разных инструментах! Но с появлением PowerShell мы получили единый (хоть и консольный) инструмент, которым можно автоматизировать абсолютно всё! Даже сам PowerShell &lt;img alt=":)" src="/smilies/happy.gif"&gt; Вот, собственно код, который в разы упрощает процесс просмотра содержимого контейнеров:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;Get-ADPKIObject&lt;/span&gt;&lt;span style="color: #000000"&gt; {
&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;lt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;
.Synopsis
    Displays certificates info from Active Directory containers
.Description
    Displays info about certificates that are stored in AD PKI-related containers.
.Parameter Container
    Optional parameter. Specifies particular container to view. May contain one or
    more value from following possible values:
    
    RootCA - retrieves certificates from Certification Authorities container
    SubCA - retrieves certificates from AIA container
    NTAuthCA - retrieves certificates from NTAuthCertificate directory entry.
    
    if no parameter is set, command will return all certificates from all applicable
    containers.
.EXAMPLE
    Get-ADPKIObject RootCA
    
    Retrieves certificates from Certification Authorities container
.EXAMPLE
    Get-ADPKIObject RootCA, AIA
    
    Retrieves certificates from Certification Authorities and AIA containers
.Outputs
    Output AD PKI object collection
&lt;/span&gt;&lt;span style="color: #008000"&gt;#&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
[CmdletBinding()]
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;param&lt;/span&gt;&lt;span style="color: #000000"&gt;([&lt;/span&gt;&lt;span style="color: #008080"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;[]][ValidateSet(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;RootCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;SubCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;NTAuthCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;)]&lt;/span&gt;&lt;span style="color: #800080"&gt;$Container&lt;/span&gt;&lt;span style="color: #000000"&gt;)
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; объявляем массив, который будет хранить выходные объекты&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:sum&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; @()
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; это весьма крутая штука будет. Каждый объект будет содержать свойство Id или просто&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; порядковый номер объекта. При дальнейших операциях с этими объектами вам достаточно&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; будет указать его Id вместо длинных и неудобных LDAP/Thumpbrint значений, как это делается&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; в certutil и подобных ему утилитах. Нумерацию начнём с единицы&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:n&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; итоговая функция, которая будет разбирать бинарные массивы и готовить выходные объекты&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_formatter_&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$certs&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800080"&gt;$type&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; поскольку у нас все объекты в AD находятся в бинарном формате, мы импортируем каждый из них&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; в X509Certificate2 объект.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #800080"&gt;$certs&lt;/span&gt;&lt;span style="color: #000000"&gt; | &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;%&lt;/span&gt;&lt;span style="color: #000000"&gt;{
            &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Import(&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;)
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; здесь мы создаём образец выходного объекта и обвязываем этот объект необходимыми свойстами и данными&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #800080"&gt;$current&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; | &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;select&lt;/span&gt;&lt;span style="color: #000000"&gt; @{n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Id&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;;e&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:n&lt;/span&gt;&lt;span style="color: #000000"&gt;}}, Subject, @{n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Type&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;;e&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$type&lt;/span&gt;&lt;span style="color: #000000"&gt;}}, @{n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Container&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;;e&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt;}},
                @{n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;Thumbprint&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;;e&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Thumbprint}}, @{n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;SerialNumber&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;;e&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.SerialNumber}}, 
                @{n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;ValidFrom&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;;e&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.NotBefore}}, @{n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;ValidTo&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;;e&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.NotAfter}}, 
                @{n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;RawCertificate&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;;e&lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.RawData}}
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; чтобы не писать полный DN поля Subject, мы будем показывать только первую его часть&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; (которая отображается в самом сертификате)&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            [&lt;/span&gt;&lt;span style="color: #008080"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;](&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Subject &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-match&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=([^,]+)&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;)
            &lt;/span&gt;&lt;span style="color: #800080"&gt;$current&lt;/span&gt;&lt;span style="color: #000000"&gt;.Subject &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$matches&lt;/span&gt;&lt;span style="color: #000000"&gt;[1]
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; добавляем объект в массив выходных объектов&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:sum&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;+=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$current&lt;/span&gt;&lt;span style="color: #000000"&gt;
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; очищаем X509Certificate2&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Reset()
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; увеличиваем счётчик и обрабатываем следующий элемент&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;++&lt;/span&gt;&lt;span style="color: #000000"&gt;
        }
    }
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; ещё одна суб-функция, которая выдёргивает сертификаты из AD в бинарном виде и отправляет&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; их в _formatter_, который уже сформирует итоговые объекты.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_switcher_&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; подключаемся к нужному контейнеру&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; [&lt;/span&gt;&lt;span style="color: #008080"&gt;ADSI&lt;/span&gt;&lt;span style="color: #000000"&gt;](&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;LDAP://CN=$name,$script:ConfigContext&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;)
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; как мы знаем, NTAuthCertificates не является контейнером, поэтому для него код будет немного&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; отличаться. А отличие будет состоять в том, что мы не будем залезать в контейнер, а сразу читать&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; свойства объекта NTAuthCA&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-eq&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;NTAuthCertificates&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; убеждаемся, что длина первого элемента свойства cACertificate больше единицы, т.е. содержит ненулевое&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; значение. Так же проверяем свойство crossCertificatePair, которое содержит Cross-certificates&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; и если оно не нулевое, то отправляем и его на формирование вывода&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.cACertificate[0].count &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-gt&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$certs&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; @(&lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.cACertificate)
                &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_formatter_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$certs&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;CA Certificate&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt;
            }
            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.crossCertificatePair[0].count &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-gt&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$certs&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; @(&lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.cACertificate)
                &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_formatter_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$certs&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Cross CA Certificate&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt;
            }
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; и переходим к следующему контейнеру&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;
        }
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если контейнер указан как Certification Authority и/или AIA, то заглядываем&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; внутрь контейнера&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.psbase.children | &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;%&lt;/span&gt;&lt;span style="color: #000000"&gt;{
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; и заглядываем в каждую запись на исследование свойств cACetificate и crossCertificatePair&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #800080"&gt;$certs&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; @(&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.cACertificate)
            &lt;/span&gt;&lt;span style="color: #800080"&gt;$ccerts&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; @(&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.crossCertificatePair)
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; проверяем, что свойство имеет ненулевое значение. Если так, то отправляем&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; содержимое этих свойств на формирование вывода&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$certs&lt;/span&gt;&lt;span style="color: #000000"&gt;[0].count &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-gt&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;) {&lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_formatter_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$certs&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;CA Certificate&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt;}
            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$ccerts&lt;/span&gt;&lt;span style="color: #000000"&gt;[0].count &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-gt&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;) {&lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_formatter_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$ccerts&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Cross CA Certificate&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt;}
        }
    }
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;switch&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$Container&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; конструкцией switch проверяем содержимое аргумента функции, чтобы определить какие именно&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; контейнеры надо обследовать.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;RootCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_switcher_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Certification Authorities&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
        &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;SubCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_switcher_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;AIA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
        &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;NTAuthCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_switcher_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;NTAuthCertificates&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если контейнер в аргументе не указан, то проверяем все контейнеры и записи&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; {
            &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_switcher_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Certification Authorities&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
            &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_switcher_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;AIA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
            &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_switcher_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;NTAUthCertificates&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
        }
    }
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; когда вывод будет полностью сформирован, выбрасываем все объекты в консоль&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:sum&lt;/span&gt;&lt;span style="color: #000000"&gt;
}&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Примечание:&lt;/font&gt;&lt;/strong&gt; данная функция является частью файла &lt;strong&gt;dspublish.ps1&lt;/strong&gt;, т.к. использует глобально объявленные переменные.&lt;/p&gt;

&lt;p&gt;и вывод у него вот такой красивый: 
  &lt;br /&gt;&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;Id             : 3
Subject        : Contoso CA
Type           : CA Certificate
Container      : AIA
Thumbprint     : BA8FECE99165E68CE27C9F0AF5F0664FDA39F7A2
SerialNumber   : 5DD87E4CFFE3B3BC43F608EB57C767F7
ValidFrom      : 2009.02.15. 16:31:15
ValidTo        : 2014.02.15. 16:40:11
RawCertificate : {48, 130, 4, 98...}

Id             : 4
Subject        : sysadmins-LV-CA
Type           : Cross CA Certificate
Container      : AIA
Thumbprint     : 1A28B582E21803D2BFE0DAEEF4593DE372C8EC3C
SerialNumber   : 170AD11B0000000000A7
ValidFrom      : 2009.11.24. 19:43:10
ValidTo        : 2011.03.30. 17:06:53
RawCertificate : {48, 130, 7, 94...}&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;я считаю его достаточно информативным. Но если хотите посмотреть любой сертификат из этого списка, то можно и сделать просмотр. К сожалению я в программировании не шарю и как работать напрямую с библиотекой просмотрщика сертификатов, поэтому я реализовал просмотр обходным путём:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;filter&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;View-ADPKIObject&lt;/span&gt;&lt;span style="color: #000000"&gt; {
&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;lt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;
.Synopsis
    Displays certificates in certificate viewer
.Description
    Displays certificates in certificate viewer by selecting necessary certificates ID.
    Must be placed after Get-ADPKIObject command only.
.Parameter ID
    Specifies certificate ID that was set in Get-ADPKIObject command.
.EXAMPLE
    Get-ADPKIObject RootCA | ViewADPKIObject 1, 3
    
    displays certificate with ID = 2 in certificate viewer
.Outputs
    Script doesn't generate any output except errors
&lt;/span&gt;&lt;span style="color: #008000"&gt;#&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; судя по конструкции int[] мы можем указать несколько чисел, тогда все выбранные&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; сертификаты будут отображены. Номер указывать обязательно.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;param&lt;/span&gt;&lt;span style="color: #000000"&gt;([&lt;/span&gt;&lt;span style="color: #008080"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;[]]&lt;/span&gt;&lt;span style="color: #800080"&gt;$ID&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; $(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;you must specify number of the object to display&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;))
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; и проверяем входные объекты с конвейера на предмет их ID. Если ID совпадает с&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; одним из ID в аргументах, обрабатываем его. Если ID не совпадает, ничего не делаем.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (@(&lt;/span&gt;&lt;span style="color: #800080"&gt;$ID&lt;/span&gt;&lt;span style="color: #000000"&gt;) &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-contains&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.Id) {
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; генерируем в пользовательской папке Temp временный файл с рандомным расширением&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #800080"&gt;$TempFile&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; [&lt;/span&gt;&lt;span style="color: #008080"&gt;System.IO.Path&lt;/span&gt;&lt;span style="color: #000000"&gt;]::&lt;/span&gt;&lt;span style="color: #8b4513"&gt;GetTempFileName&lt;/span&gt;&lt;span style="color: #000000"&gt;() &lt;/span&gt;&lt;span style="color: #ff0000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;.cer&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; записываем бинарный массив сертификата в файл в виде DER кодировки&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        [&lt;/span&gt;&lt;span style="color: #008080"&gt;System.IO.File&lt;/span&gt;&lt;span style="color: #000000"&gt;]::&lt;/span&gt;&lt;span style="color: #8b4513"&gt;WriteAllBytes&lt;/span&gt;&lt;span style="color: #000000"&gt;(&lt;/span&gt;&lt;span style="color: #800080"&gt;$TempFile&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.RawCertificate)
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; запускаем файл (просмоторщик сертификатов)&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &amp;amp; &lt;/span&gt;&lt;span style="color: #800080"&gt;$TempFile&lt;/span&gt;&lt;span style="color: #000000"&gt;
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; в санитарных целях ждём пол секунды&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Start-Sleep&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;0.5&lt;/span&gt;&lt;span style="color: #000000"&gt;
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; и удаляем этот файл, чтобы не копился мусор&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;del&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$TempFile&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-Force&lt;/span&gt;&lt;span style="color: #000000"&gt;
    }
}&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Как вы видите, ничего сверх-космического или магического в этом коде нет, самое трудное здесь — придумать логику работы. А остальное — накидать несколько строк кода и у нас PowerShell в лёгкую может соперничать с certutil за право называться единой утилитой управления PKI &lt;img alt=":)" src="/smilies/happy.gif"&gt;&lt;/p&gt;

&lt;p&gt;Чтобы подкрутить рейтинг PowerShell в этой конкуренции, в следующий раз я покажу как мы можем легко и просто удалять сертификаты из контейнеров AD с использованием PowerShell &lt;img alt=":)" src="/smilies/happy.gif"&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=55c5304e-baef-4af6-bc0f-e09c214fb630"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,55c5304e-baef-4af6-bc0f-e09c214fb630.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
      <category>PowerShell / Certificates</category>
      <category>PowerShell / Certificates / Active Directory</category>
    </item>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=dd03c789-780d-4b39-9b7b-310905ecde32</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,dd03c789-780d-4b39-9b7b-310905ecde32.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,dd03c789-780d-4b39-9b7b-310905ecde32.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=dd03c789-780d-4b39-9b7b-310905ecde32</wfw:commentRss>
      <title>Active Directory PKI object management с помощью PowerShell</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,dd03c789-780d-4b39-9b7b-310905ecde32.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,dd03c789-780d-4b39-9b7b-310905ecde32.aspx</link>
      <pubDate>Wed, 09 Dec 2009 19:35:17 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;Подоспела ещё одна задачка для PowerShell'а — управление объектами PKI в Active Directory. Active Directory содержит целый раздел посвящённый PKI и вот из чего он состоит:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font color="#0000ff"&gt;CN=NTAuthCertificates, CN=Public Key Services, CN=Services, CN=Configuration, &lt;em&gt;ForestRootDomain&lt;/em&gt;&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font color="#0000ff"&gt;CN={CA name},CN=AIA, CN=Public Key Services, CN=Services, CN=Configuration, &lt;em&gt;ForestRootDomain&lt;/em&gt;&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font color="#0000ff"&gt;CN={CA name},CN=CDP, CN=Public Key Services, CN=Services, CN=Configuration, &lt;em&gt;ForestRootDomain&lt;/em&gt;&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font color="#0000ff"&gt;CN={CA name},CN=Certification Authority, CN=Public Key Services, CN=Services, CN=Configuration, &lt;em&gt;ForestRootDomain&lt;/em&gt;&lt;/font&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Вот о них мы сегодня и поговорим. В AD есть ещё несколько контейнеров, которые связаны с PKI, но они сегодня интереса представлять не будут. Как мы уже знаем, в:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;NTAuthCertificates&lt;/strong&gt; публикуются все сертификаты CA, которые выдают сертификаты для аутентификации пользователей в домене. В том числе для логона смарт-картой, аутентификации в IIS или для аутентификации EAP-TLS в VPN. Все сертификаты в этой записи хранятся в виде массива; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;AIA&lt;/strong&gt; публикуются сертификаты промежуточных (Intermediate) CA, за счёт чего можно значительно сократить время построения цепочек сертификатов. При этом не обязательно должен содержать сертификаты CA, которые зарегистрированы в текущем лесу. Это могут быть сертификаты промежуточных CA сторонних компаний, сертификаты которых вы используете. По большому счёту сюда должны публиковаться все сертификаты; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;CDP&lt;/strong&gt; публикуются CRL списки CA для ускорения проверки сертификатов в цепочке. Так же, как и в случае с AIA не обязательно может содержать CRL'ы CA только текущего леса. Сюда могут публиковаться и CRL сторонних CA, сертификаты которых вы используете; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Certification Authority&lt;/strong&gt; публикуются сертификаты корневых CA, которым должен доверять весь лес. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Вы спросите, а зачем это всё, если то же самое можно сделать через групповые политики? Ответ тут достаточно очевиден. Дело в том, что PKI не видит границ доменов и эти сертификаты распространяются по всему лесу вместе с репликацией. Поэтому для добавления нового доверенного корневого CA вам придётся создавать одинаковую политику в каждом домене леса. И вы некоторые объекты (например CRL) не можете распространять через GPO.&lt;/p&gt;  &lt;p&gt;Какие у нас есть инструменты для управления данными контейнерами? Их у нас несколько:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;ADSIEdit.msc&lt;/strong&gt; — обеспечивает только просмотр содержимого контейнеров в AD (но сами записи там нечитабельны); &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;PKIView.msc&lt;/strong&gt; — позволяет просматривать содержимое каждого контейнера и удалять оттуда сертификаты. C использованием данной консоли мы можем добавлять сертификаты только в NTAuthCertificates. Остальные — только чтение и удаление; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;certutil&lt;/strong&gt; — интерфейс командной строки, который позволяет добавлять, просматривать контейнеры и удалять сертифакты из них. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Кажется, что certutil'а хватит всем. Но у него есть одна большая проблема — ужасный синтаксис. Напрмер, если вы хотите посмотреть CRL'ы в AD, то придётся делать что типа такого:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;font color="#0000ff"&gt;certutil –viewstore ldap:///CN=MyCA,CN=CRL,CN=CDP,CN=Public%20Key%        &lt;br /&gt;20Services,CN=Services,CN=Configuration,DC=contoso,DC=com?certificateRevocationList?base?objectClass=cRLDistributionPoint&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;этот синтаксис возможно чем-то универсален, но cовершенно неудобный для использования в командной строке, поэтому я поставил задачу решить этот вопрос с помощью PowerShell. И вот как я его решил:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Примечание:&lt;/font&gt;&lt;/strong&gt; к сожалению я не в состоянии объяснять все особенности работы ADSI и PowerShell, поэтому для понимания работы скрипта нужно иметь представление и некоторый опыт скриптования с использованием ADSI и PowerShell.&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;####################################################################&lt;/span&gt;&lt;span style="color: #008000"&gt;
#&lt;/span&gt;&lt;span style="color: #008000"&gt; dspublish.ps1&lt;/span&gt;&lt;span style="color: #008000"&gt;
#&lt;/span&gt;&lt;span style="color: #008000"&gt; Version 0.7&lt;/span&gt;&lt;span style="color: #008000"&gt;
#
#&lt;/span&gt;&lt;span style="color: #008000"&gt; Adds certificates in Active Directory containers&lt;/span&gt;&lt;span style="color: #008000"&gt;
#
#&lt;/span&gt;&lt;span style="color: #008000"&gt; Vadims Podans (c) 2009&lt;/span&gt;&lt;span style="color: #008000"&gt;
#&lt;/span&gt;&lt;span style="color: #008000"&gt; http://www.sysadmins.lv/&lt;/span&gt;&lt;span style="color: #008000"&gt;
#&lt;/span&gt;&lt;span style="color: #008000"&gt;####################################################################&lt;/span&gt;&lt;span style="color: #008000"&gt;
#&lt;/span&gt;&lt;span style="color: #008000"&gt;requires -Version 2.0&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;
&lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; любая ошибка будет фатальной, поэтому при её возникновении останавливаем работу&lt;/span&gt;&lt;span style="color: #008000"&gt;
#&lt;/span&gt;&lt;span style="color: #008000"&gt; скрипта, чтобы предотвратить фатальные изменения в Active Directory&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #0000ff"&gt;trap&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #0000ff"&gt;break&lt;/span&gt;&lt;span style="color: #000000"&gt;}
&lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; объявляем глобальные переменные, которые будут использоваться всеми функциями скрипта&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:ConfigContext&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; [&lt;/span&gt;&lt;span style="color: #008080"&gt;System.DirectoryServices.ActiveDirectory.Domain&lt;/span&gt;&lt;span style="color: #000000"&gt;]::&lt;/span&gt;&lt;span style="color: #8b4513"&gt;GetCurrentDomain&lt;/span&gt;&lt;span style="color: #000000"&gt;().&lt;/span&gt;&lt;span style="color: #8b4513"&gt;GetDirectoryEntry&lt;/span&gt;&lt;span style="color: #000000"&gt;().distinguishedName
&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:ConfigContext&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=Public Key Services,CN=Services,CN=Configuration,&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:ConfigContext&lt;/span&gt;&lt;span style="color: #000000"&gt;
&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;New-Object&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;System.Security.Cryptography.X509Certificates.X509Certificate2&lt;/span&gt;&lt;span style="color: #000000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;
&lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;Publish-ADPKIObject&lt;/span&gt;&lt;span style="color: #000000"&gt; {
&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;lt;#&lt;/span&gt;&lt;span style="color: #008000"&gt;
.Synopsis
    Publishes certificates to Active Directory containers
.Description
    Publishes certificates to Public Key Services containers in Active Directory.
.Parameter File
    Specifies the path to certificate file or X509Certificate2 object.
    Certificates may be passed through pipeline.
.Parameter Container
    Specifies the AD PKI container to publish file. For certificates only
    following containers MUST be used:
    
    RootCA - indicates that certificate will be published to Certification Authorities container
    SubCA - indicates that certificate will be published to AIA container
    NTAuthCA - indicates that certificate will be added to NTAuthCertificate directory
    entry. If not exist, entry will be created.
    
    you MAY specify several containers at once. Certificate will be added to all
    specified containers. Entry names are based on certificate subject.
    
.Parameter Force
    forces object rewrite if object already exist in Active Directory
.EXAMPLE
    dir *.cer | Publish-ADPKIObject RootCA, SubCA
    
    will publish all .CER certificates to Certification Authorities and AIA containers
.EXAMPLE
    Publish-ADPKIObject certificate.cer RootCA -Force
    
    will publish 'Certificte.cer' certificate to Certification Authorities container. If
    object already exist, it will rewrited
.Outputs
    This command provide a resultant of operation.
&lt;/span&gt;&lt;span style="color: #008000"&gt;#&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
[CmdletBinding()]
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;param&lt;/span&gt;&lt;span style="color: #000000"&gt;(
        [Parameter(Mandatory &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;, ValueFromPipeline &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;, Position &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;)]
        [&lt;/span&gt;&lt;span style="color: #008080"&gt;object&lt;/span&gt;&lt;span style="color: #000000"&gt;[]]&lt;/span&gt;&lt;span style="color: #800080"&gt;$file&lt;/span&gt;&lt;span style="color: #000000"&gt;,
        [Parameter(Mandatory &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;, Position &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;)]
        [&lt;/span&gt;&lt;span style="color: #008080"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;[]]&lt;/span&gt;&lt;span style="color: #800080"&gt;$Container&lt;/span&gt;&lt;span style="color: #000000"&gt;,
        [&lt;/span&gt;&lt;span style="color: #008080"&gt;switch&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800080"&gt;$Force&lt;/span&gt;&lt;span style="color: #000000"&gt;
    )
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;begin&lt;/span&gt;&lt;span style="color: #000000"&gt; {
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; функция, которая будет осуществлять запись сертификатов в AD&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_ldaproutine_&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800080"&gt;$CN&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800080"&gt;$Force&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
            &lt;/span&gt;&lt;span style="color: #800080"&gt;$path&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; [&lt;/span&gt;&lt;span style="color: #008080"&gt;ADSI&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;LDAP://$ldap&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; убеждаемся, что такой же объект не существует в AD&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; ($(&lt;/span&gt;&lt;span style="color: #800080"&gt;$path&lt;/span&gt;&lt;span style="color: #000000"&gt;.psbase.children | ?{&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.cn &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-eq&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$CN&lt;/span&gt;&lt;span style="color: #000000"&gt;})) {
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если существует, проверяем ключ Force, который позволяет перезаписывать&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; объекты&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$force&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
                    &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; [&lt;/span&gt;&lt;span style="color: #008080"&gt;ADSI&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;LDAP://CN=$CN,$ldap&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если ключ Force указан, то мы просто перезаписываем свойство&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; cACertificate новым сертификатом&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                    &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.put(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;cACertificate&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.RawData)
                    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; предыдущей строкой мы просто перезаписали объект, который теперь&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; надо записать в AD методом SetInfo()&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                    &lt;/span&gt;&lt;span style="color: #800080"&gt;$retn&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.SetInfo()
                    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #000080"&gt;$?&lt;/span&gt;&lt;span style="color: #000000"&gt;) {&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Host&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;`'$CN`' certificate is sucessfully rewrited to `'$name`' container&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ForegroundColor&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;Green&lt;/span&gt;&lt;span style="color: #000000"&gt;}
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если объект уже существует и ключ Force не указан, то просто выводим сообщение, что такой объект уже существует&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                } &lt;/span&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Warning&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Object already exist in `'$name`' container. Use -Force switch to rewrite&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
            } &lt;/span&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;span style="color: #000000"&gt; {
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если объект ещё не существует в указанном контейнере, то создаём в нём новый объект&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; с типом certificationAuthority&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$path&lt;/span&gt;&lt;span style="color: #000000"&gt;.Create(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;certificationAuthority&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=$CN&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; записываем сертификат в свойство cACertificate в бинарном виде из объекта X509Certificate2&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt;.Put(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;cACertificate&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.RawData)
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; записываем нулями обязательные поля, которые требуются для создания объекта. Использовать как есть.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt;.Put(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;authorityRevocationList&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt;.Put(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;certificateRevocationList&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; когда объект сформирован, записываем его в AD&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$retn&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt;.SetInfo()
                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #000080"&gt;$?&lt;/span&gt;&lt;span style="color: #000000"&gt;) {&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Host&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;`'$CN`' certificate is sucessfully added to `'$name`' container&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ForegroundColor&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;Green&lt;/span&gt;&lt;span style="color: #000000"&gt;}
            }
        }
    }
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; рабочая секция, которая будет разбирать входные сертификаты и подготавливать необходимые данные&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; которые необходимы для записи &lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;process&lt;/span&gt;&lt;span style="color: #000000"&gt; {
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; выбираем текущий объект сертификата&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Certificate&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;gi&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$file&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ErrorAction&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;Stop&lt;/span&gt;&lt;span style="color: #000000"&gt;
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; проверяем, что объект не является готовым объектом X509Certificate2&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Certificate&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-isnot&lt;/span&gt;&lt;span style="color: #000000"&gt; [&lt;/span&gt;&lt;span style="color: #008080"&gt;System.Security.Cryptography.X509Certificates.X509Certificate2&lt;/span&gt;&lt;span style="color: #000000"&gt;]) {
            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если не является, то это будет файл. Проверяем расширение файла.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; допускаются только расширения CER и CRT&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;.cer&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;.crt&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-contains&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Certificate&lt;/span&gt;&lt;span style="color: #000000"&gt;.Extension) {
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если это CER или CRT файл, то конвертируем его в объект X509Certificate2&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Import(&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Certificate&lt;/span&gt;&lt;span style="color: #000000"&gt;.FullName)
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; в переменную $CN записываем первую часть поля Subject сертификата&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                [&lt;/span&gt;&lt;span style="color: #008080"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;](&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Subject &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-match&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=([^,]+)&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$CN&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$matches&lt;/span&gt;&lt;span style="color: #000000"&gt;[1]
            }
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если у нас на конвейер или через аргументы поступил готовый X509Certificate2, то только выбираем&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; поле Subject в отдельную переменную.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        } &lt;/span&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;span style="color: #000000"&gt; {
            &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Certificate&lt;/span&gt;&lt;span style="color: #000000"&gt;
            [&lt;/span&gt;&lt;span style="color: #008080"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;](&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Subject &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-match&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=([^,]+)&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;)
            &lt;/span&gt;&lt;span style="color: #800080"&gt;$CN&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$matches&lt;/span&gt;&lt;span style="color: #000000"&gt;[1]
        }
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; проверяем аргументы, которые указывают на контейнеры, куда надо записывать наши сертификаты.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; я не делал проверку этих контейнеров в секции param() через использование ValidateSet&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; поскольку данная функция в будущем будет использоваться и для публикации CRL. А для&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; них нужно вручную прописывать имя записи в контейнере CDP и оно может быть произвольным.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; отфильтровываем все неправильные контейнеры, которые были заданы при вызове функции&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #800080"&gt;$Container&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$Container&lt;/span&gt;&lt;span style="color: #000000"&gt; | ?{&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;RootCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;SubCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;NTAuthCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-contains&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;}
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если после фильтрации ни одного валидного контейнера не осталось, то очень сильно ругаемся.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #ff0000"&gt;!&lt;/span&gt;&lt;span style="color: #800080"&gt;$Container&lt;/span&gt;&lt;span style="color: #000000"&gt;) {&lt;/span&gt;&lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;For certificate containers only following values are applicable: RootCA, SubCA, NTAuthCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; проверяем, что входной сертификат содержит свойство CertificateAuthority равным True.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; это свойство соответствует расширению Basic Constraints в сертификате, которое может иметь&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; значения: Subject Type=CA - это сертификат CA и Subject Type=End entity, если это конечный&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; сертификат. А в X509Certificate2 конечный сертификат будет иметь значение False в свойстве&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; CertificateAuthority. Но работу скрипта не прерываем, а просто пропускаем текущий сертификат.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #ff0000"&gt;!&lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Extensions | ?{&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;.CertificateAuthority &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-eq&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$true&lt;/span&gt;&lt;span style="color: #000000"&gt;}) {
            &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Warning&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Input certificate `'$CN`' is not recognized as CA certificate. Skipping&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;
        }
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; а теперь подготавливаем необходимые данные для записи в зависимости от названия контейнера&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;switch&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$Container&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
            &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;RootCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; {
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; указываем название данного контейнера в AD&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Certification Authorities&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; получаем LDAP объект этого контейнера&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=$name,$script:ConfigContext&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; и отправляем всё это в функцию записи&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_ldaproutine_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$CN&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$Force&lt;/span&gt;&lt;span style="color: #000000"&gt;
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Reset()
            }
            &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;SubCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; {
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; здесь то же самое, что и для RootCA&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;AIA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=$name,$script:ConfigContext&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;_ldaproutine_&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$CN&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$Force&lt;/span&gt;&lt;span style="color: #000000"&gt;
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Reset()
            }
            &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;NTAuthCA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; {
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$name&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;NTAuthCertificates&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; [&lt;/span&gt;&lt;span style="color: #008080"&gt;ADSI&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;LDAP://CN=$name,$script:ConfigContext&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; поскольку NTAuthCertificates не является контейнером, а отдельной&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; записью, которая содержит массив сертификатов, то правила записи&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; здесь немного иные. Сначала проверяем, что эта запись уже существует в AD.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #ff0000"&gt;!&lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.cn) {
                    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; если нет, то создаём её&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                    &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; ([&lt;/span&gt;&lt;span style="color: #008080"&gt;ADSI&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;LDAP://$script:ConfigContext&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;).Create(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;certificationAuthority&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;CN=$name&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; заполняем обязательные свойства объекта и первый сертификат.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                    &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt;.Put(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;authorityRevocationList&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                    &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt;.Put(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;certificateRevocationList&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                    &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt;.put(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;cACertificate&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.RawData)
                    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; когда объект уже готов, то просто записываем его в AD&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                    &lt;/span&gt;&lt;span style="color: #800080"&gt;$retn&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$CA&lt;/span&gt;&lt;span style="color: #000000"&gt;.SetInfo()
                    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #000080"&gt;$?&lt;/span&gt;&lt;span style="color: #000000"&gt;) {&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Host&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;`'$CN`' certificate is sucessfully added to `'$name`' container&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ForegroundColor&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;Green&lt;/span&gt;&lt;span style="color: #000000"&gt;}
                    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;
                }
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; а вот если эта запись уже есть, то ничего создавать не надо, а просто добавляем&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; новый сертификат вдобавок к существующим. При этом обратите внимание, что объект добавляется&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; как массив (используется запятуя сразу за оператором). Это связано с особенностью работы PowerShell с&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; массивами. Поскольку бинарный сертификат сам по себе является массивом, то при простом добавлении&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; к существующему бинарному массиву, просто сделает ресайз текущего массива. Чтобы новый массив&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; записать как отдельный элемент нового массива - надо при помощи запятой явно это указать&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.cACertificate &lt;/span&gt;&lt;span style="color: #ff0000"&gt;+=&lt;/span&gt;&lt;span style="color: #000000"&gt; ,&lt;/span&gt;&lt;span style="color: #800080"&gt;$cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.RawData
                &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; и записываем объект обратно в AD.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                &lt;/span&gt;&lt;span style="color: #800080"&gt;$retn&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$ldap&lt;/span&gt;&lt;span style="color: #000000"&gt;.SetInfo()
                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #000080"&gt;$?&lt;/span&gt;&lt;span style="color: #000000"&gt;) {&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Write-Host&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;`'$CN`' certificate is sucessfully added to `'$name`' container&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="font-style: italic; color: #5f9ea0"&gt;-ForegroundColor&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;Green&lt;/span&gt;&lt;span style="color: #000000"&gt;}
                &lt;/span&gt;&lt;span style="color: #800080"&gt;$script:Cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.Reset()
            }
        }
    }
}&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;А примеры использования этого скрипта приведены во встроенном хелпе и сводятся к одной из схем:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font color="#0000ff"&gt;Publish-ADPKIObject &amp;lt;certificate&amp;gt; &amp;lt;container&amp;gt; –Force
      &lt;br /&gt;&amp;lt;certificate&amp;gt; | Publish-ADPKIObject –Force&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Причём вы можете указывать несколько контейнеров сразу, например: &lt;font color="#0000ff"&gt;Publish-ADPKIObject file.cer NTAuthCA, RootCA, SubCA&lt;/font&gt;. Я думаю, что этот скрипт получился не такой уж и сложный и его разобрать с помощью моих комментариев не так и сложно. Его можно спокойно расширить под другие контейнеры, например, CDP или KRA. Единственное, что здесь пока не реализовано — санитизация имён объектов. На сколько я знаю, certutil этого тоже не поддерживает. Но сделать её надо. Правда, я пока не нашёл ни одного стандартного механизма, который бы санитизировал имена &lt;img alt=":'(" src="/smilies/unhappy.gif"&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=dd03c789-780d-4b39-9b7b-310905ecde32"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,dd03c789-780d-4b39-9b7b-310905ecde32.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
      <category>PowerShell / Certificates</category>
      <category>PowerShell / Certificates / Active Directory</category>
    </item>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=eabb97f4-c14f-41ef-bc4c-c3df83ecd98f</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,eabb97f4-c14f-41ef-bc4c-c3df83ecd98f.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,eabb97f4-c14f-41ef-bc4c-c3df83ecd98f.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=eabb97f4-c14f-41ef-bc4c-c3df83ecd98f</wfw:commentRss>
      <title>CryptoAPI и управление Certification Authority с помощью PowerShell (часть 4)</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,eabb97f4-c14f-41ef-bc4c-c3df83ecd98f.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,eabb97f4-c14f-41ef-bc4c-c3df83ecd98f.aspx</link>
      <pubDate>Fri, 20 Nov 2009 16:40:36 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;В продолжении темы исследования COM интерфейсов CryptoAPI для управления службами Certificate Services предлагаю теперь разобрать вопросы KRA — Key Recovery Agents. Сначала напомню уже изученные темы по CryptoAPI:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.sysadmins.lv/PermaLink,guid,1cec0947-9113-4de2-bf48-809a09849f4c.aspx"&gt;&lt;strong&gt;CryptoAPI и управление Certification Authority с помощью PowerShell&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.sysadmins.lv/PermaLink,guid,ca3a2177-92b3-46af-bc7b-0497cdbce74e.aspx"&gt;&lt;strong&gt;CryptoAPI и управление Certification Authority с помощью PowerShell (часть 2)&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.sysadmins.lv/PermaLink,guid,26d5addd-f057-4e3f-8a71-a4ed0f01a836.aspx"&gt;&lt;strong&gt;CryptoAPI и управление Certification Authority с помощью PowerShell (часть 3)&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;И на сегодня наш план выглядит достаточно интересно:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Получение списка доступных KRA в лесу и просмотр их сертификатов &lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Получение списка KRA назначенных на сервере CA; &lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Назначение новых KRA для CA.&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h1 align="center"&gt;Получение списка доступных KRA в лесу&lt;/h1&gt;  &lt;p&gt;KRA используется для архивирования закрытых ключей сертификатов в БД CA. В случае если пользователь уничтожил свой закрытый ключ он может его восстановить. Для этого нужно обратиться к администратору CA для извлечения &lt;strong&gt;BLOB&lt;/strong&gt; (&lt;em&gt;Binary Large OBject&lt;/em&gt;) в файл. После чего агент восстановления (&lt;strong&gt;KRA&lt;/strong&gt;) использует свой закрытый ключ для расшифровки закрытого ключа из BLOB'а. Учитывая, что я и не только уже рассматривали этот вопрос, я не буду пересказывать принцип работы Key Archival:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.sysadmins.lv/PermaLink,guid,a13d0c06-3608-42d9-b11e-0aef08354dd8.aspx"&gt;&lt;strong&gt;EFS и смарт-карты в Windows Server 2008 (часть 2)&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.sysadmins.lv/PermaLink,guid,8b5e58cc-9017-4575-9c9c-17dd81c25866.aspx"&gt;&lt;strong&gt;EFS и смарт-карты в Windows Server 2008 (часть 3)&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.technet.com/pki/archive/2009/08/07/understanding-key-archival.aspx"&gt;&lt;strong&gt;Understanding Key Archival&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Все сертификаты KRA публикуются в forest naming configuration context партиции AD и реплицируется между всеми контроллерами в лесу. Публикация просисходит в точке:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;CN=KRA, CN=Public Key Services, CN=Services, CN=Configuration, DC=ForestRootDomain&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;div style="width: 935px"&gt;   &lt;blockquote&gt;     &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $ldap = [ADSI]&amp;quot;LDAP://CN=KRA, CN=Public Key Services, CN=Services, CN=Configuration, DC=contoso,dc=com&amp;quot;
PS C:\&amp;gt; $ldap

distinguishedName
-----------------
{CN=KRA,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com}


PS C:\&amp;gt; $kra = $ldap.psbase.children | %{$_}
PS C:\&amp;gt; $kra

distinguishedName
-----------------
{CN=contoso-DC2-CA,CN=KRA,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com}
{CN=Contoso CA,CN=KRA,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com}&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Мы получили список CA в лесу и посмотрев каждый из них можем посмотреть сколько KRA сертификатов выпустил каждый CA:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $kra[1] | fl *


objectClass            : {top, msPKI-PrivateKeyRecoveryAgent}
cn                     : {Contoso CA}
userCertificate        : {48 130 6 104 48 130 5 80 160 3 2 1 2 2 10 21 29 22 96 0 0 0 0 0 4 48 13 6 9 42 134 72 134 247
                          13 1 1 5 5 0 48 67 49 19 48 17 6 10 9 146 38 137 147 242 44 100 1 25 22 3 99 111 109 49 23 48
                          21 6 10 9 146 38 137 147 242 44 100 1 25 22 7 99 111 110 116 111 115 111 49 19 48 17 6 3 85 4
                          3 19 10 67 111 110 116 111 115 111 32 67 65 48 30 23 13 48 57 48 50 49 53 49 53 48 53 50 53 9
                         0 23 13 49 49 48 50 49 53 49 53 48 53 50 53 90 48 86 49 19 48 17 6 10 9 146 38 137 147 242 44
                         100 1 25 22 3 99 111 109 49 23 48 21 6 10 9 146 38 137 147 242 44 100 1 25 22 7 99 111 110 116
&amp;lt;...&amp;gt;
&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Свойство &lt;strong&gt;UserCertificate&lt;/strong&gt; в виде массива может содержать сертификаты KRA в виде байтового массива. Например, указанный CA выпустил 2 сертификата KRA:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $kra[1].usercertificate.count
2&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;И обратившись к индексам этого свойства можно получить конкретные сертификаты: $kra[1].usercertificate[0]. Если CA не выпускал сертификаты для KRA, то свойство UserCertificate будет содержать число ноль:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $kra[0] | fl *


objectClass            : {top, msPKI-PrivateKeyRecoveryAgent}
cn                     : {contoso-DC2-CA}
userCertificate        : {0}
&amp;lt;...&amp;gt;&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Поэтому для получения всех сертификатов KRA нужно пройтись по всем членам CN=KRA и выбрать из них ненулевые значения свойства UserCertificate. Если сертификатов больше, чем 1, то они будут храниться в этом свойстве в виде массива. Чтобы посмотреть сам сертификат, вы можете просто сохранить этот массив байтов в файл:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; [System.IO.File]::WriteAllBytes(&amp;quot;C:\kra.cer&amp;quot;,$kra[1].usercertificate[1])
PS C:\&amp;gt; &amp;amp; .\kra.cer&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;h1 align="center"&gt;Получение списка KRA назначенных на сервере CA&lt;/h1&gt;

&lt;p&gt;А теперь вернёмся к интерфейсу ICertAdmin2. С его помощью мы можем посмотреть количество агентов восстановления, которые назначены на CA и посмотреть их сертификаты. Однако, этот интерфейс имеет какой-то баг с PropID, которые связаны с KRA, о которых я писал в &lt;a href="http://www.sysadmins.lv/PermaLink,guid,26d5addd-f057-4e3f-8a71-a4ed0f01a836.aspx"&gt;&lt;strong&gt;предыдущей статье&lt;/strong&gt;&lt;/a&gt;, поэтому для получения этих данных мы будем использовать интерфейс &lt;a href="http://msdn.microsoft.com/en-us/library/ee373776(VS.85).aspx"&gt;&lt;strong&gt;ICertRequest3&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $CertRequest = New-Object -ComObject CertificateAuthority.Request.1
PS C:\&amp;gt; $CertRequest.GetCAProperty(&amp;quot;dc1\contoso ca&amp;quot;,0x18,0,1,0)
1
PS C:\&amp;gt; $CertRequest.GetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x18,0,1,0)
0
PS C:\&amp;gt; $CertRequest.GetCAProperty(&amp;quot;dc1\contoso ca&amp;quot;,0x19,0,1,0)
1
PS C:\&amp;gt; $CertRequest.GetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x19,0,1,0)
0&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Мы видим, что на сервере DC1 назначен 1 агент восстановления, а на DC2 ни одного. Сегодня мы добавим агентов восстановления на DC2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Примечание:&lt;/font&gt;&lt;/strong&gt; чем отличаются &lt;strong&gt;KRACERTUSEDCOUNT&lt;/strong&gt; и &lt;strong&gt;KRACERTCOUNT&lt;/strong&gt;? KRACERTCOUNT показывает сколько всего KRA назначено на конкретном сервере CA. А KRACERTUSEDCOUNT показывает сколько из них будет использовать CA при архивации каждого закрытого ключа сертификата и это число может быть меньше, чем общее количество сертификатов KRA. В таком случае CA рандомно выбирает KRACERTUSEDCOUNT сертификатов и шифрует ими закрытый ключ. Например, KRACERTCOUNT = 5, а KRACERTUSEDCOUNT = 3, то CA при архивации ключа выберет рандомно 3 сертификата KRA из списка и зашифрует ими ключ. И только эти 3 агента восстановления могут восстановить ключ, а остальные 2 уже не смогут.&lt;/p&gt;

&lt;h1 align="center"&gt;&lt;strong&gt;Получение списка KRA назначенных на сервере CA&lt;/strong&gt;&lt;/h1&gt;

&lt;p&gt;Чтобы посмотреть сами сертификаты KRA, мы должны воспользоваться &lt;strong&gt;PropID = CR_PROP_KRACERT (0x1A)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;И вот что мы увидим:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $CertAdmin.GetCAProperty(&amp;quot;dc1\contoso ca&amp;quot;,0x1A,0,3,0)
-----BEGIN CERTIFICATE-----
MIIGaDCCBVCgAwIBAgIKFR0WYAAAAAAABDANBgkqhkiG9w0BAQUFADBDMRMwEQYK
CZImiZPyLGQBGRYDY29tMRcwFQYKCZImiZPyLGQBGRYHY29udG9zbzETMBEGA1UE
AxMKQ29udG9zbyBDQTAeFw0wOTAyMTUxNTA1MjVaFw0xMTAyMTUxNTA1MjVaMFYx
EzARBgoJkiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJk/IsZAEZFgdjb250b3NvMQ4w
DAYDVQQDEwVVc2VyczEWMBQGA1UEAxMNQWRtaW5pc3RyYXRvcjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAJG7T5yMninhrkXFQU8WGUr5BYYUeOz10Rkn
&amp;lt;...&amp;gt;&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;В нулевом индексе мы видим первый сертификат. Последующие будут храниться в других индексах:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font color="#0000ff"&gt;$CertAdmin.GetCAProperty(&amp;quot;dc1\contoso ca&amp;quot;,0x1A,$Index,3,0)&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Этот сертификат можно спокойно записать в файл и через GUI просмотреть его свойства. Но вообще это не родной формат сертификата KRA для данного интерфейса, поскольку добавлять сертификаты KRA на сервере CA нужно в &lt;strong&gt;ASN1 DER-encoded string&lt;/strong&gt; формате. Т.е. &lt;strong&gt;Flags&lt;/strong&gt; должен быть не 0, а 2:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font color="#0000ff"&gt;$CertAdmin.GetCAProperty(&amp;quot;dc1\contoso ca&amp;quot;,0x1A,$Index,3,&lt;strong&gt;2&lt;/strong&gt;)&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;и увидим примерно такое:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $kra = $CertAdmin.GetCAProperty(&amp;quot;dc1\contoso ca&amp;quot;,0x1a,0,3,2)
PS C:\&amp;gt; $kra
?????A???`  ?????c?♣??????????????????T???????????????????????????????????????T????????????????????????????????????????
??ca♣??????☺???????????????????????????????????????????????????????????????????????????????????????????????????????????
??????????????????????☺????????Є?????????????????☻???????☻??????????????ЎЖ?????????????CA??????Ё????????????h??A???????
??????????????????????????????????????????????╣????????????????????????????????????????????????????????????????????????
?????????????????????C?cЁ??????C???????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????Х???CA?????Ё???????CA?????Б????CA??????????????????????a???☺????????????????????
????????????????????????????????????c?????????????????????????????????????H╝??????????????????{?????????????&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;выглядит весьма уныло, но вот в таком формате и надо записывать сертификаты агентов восстановления в CA.&lt;/p&gt;

&lt;h1 align="center"&gt;Назначение новых KRA для CA&lt;/h1&gt;

&lt;p&gt;Когда мы рассмотрели основные моменты связанные с агентами восстановления в контексте CryptoAPI, мы можем приступить к финальной части — назначению новых агентов восстановления. В принципе, здесь нет ничего сложного, поскольку для добавления KRA нужно сделать 5 вещи:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Получить массив байтов, которые бы представляли сертификат агента восстановления откуда угодно. Хоть из AD, хоть из файла сертификата; &lt;/li&gt;

  &lt;li&gt;Используя специальный конвертер, разобрать этот массив на пары байтов, сконвертировать эти пары в little-endian hex строку, получить десятичное представление этой hex-строки и получить итоговую символьную строку; &lt;/li&gt;

  &lt;li&gt;Записать эту строку используя метод SetCAProperty(); &lt;/li&gt;

  &lt;li&gt;Задать новое количество используемых агентов восстановления; &lt;/li&gt;

  &lt;li&gt;Перезапустить службу CA. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Первый этап у нас уже пройден, поскольку у нас уже есть такой массив в AD. Если сертификата агента восстановления нет в AD, то можно его получить из файла:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #800080"&gt;$cert&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;New-Object&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;System.Security.Cryptography.X509Certificates.X509Certificate2&lt;/span&gt;&lt;span style="color: #000000"&gt;
&lt;/span&gt;&lt;span style="color: #800080"&gt;$cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #8b4513"&gt;Import&lt;/span&gt;&lt;span style="color: #000000"&gt;(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;.\desktop\kra.cer&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;)
&lt;/span&gt;&lt;span style="color: #800080"&gt;$bytes&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$cert&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #8b4513"&gt;RawData&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;и переменная $bytes будет содержать такой же байтовый массив.&lt;/p&gt;

&lt;p&gt;А вот с конвертером чуть сложнее. Я не нашёл ни одного готового конвертера, который бы выполнял все шаги из пункта 2, поэтому я написал свой конвертер с блек-джеком и шлюхами:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0"&gt;ConvertTo-DERstring&lt;/span&gt;&lt;span style="color: #000000"&gt; ([&lt;/span&gt;&lt;span style="color: #008080"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]]&lt;/span&gt;&lt;span style="color: #800080"&gt;$bytes&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; создаём объект StringBuilder, который нам будет собирать конечную символьную строку&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #800080"&gt;$SB&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;New-Object&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800000"&gt;System.Text.StringBuilder&lt;/span&gt;&lt;span style="color: #000000"&gt;
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; преобразовываем каждый байт в его hex значение&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #800080"&gt;$bytes1&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$bytes&lt;/span&gt;&lt;span style="color: #000000"&gt; | &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;%&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;{0:X2}&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-f&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; циклом перебираем каждую пару байт&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$n&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;; &lt;/span&gt;&lt;span style="color: #800080"&gt;$n&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-lt&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$bytes1&lt;/span&gt;&lt;span style="color: #000000"&gt;.count; &lt;/span&gt;&lt;span style="color: #800080"&gt;$n&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$n&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;2&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; переставляем элементы пары местами, чтобы получить little-endian hex-строку&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; после чего получаем десятичное представление этой строки и получаем Unicode&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        &lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; символ, который соответствует этому десятичному значению.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;        [&lt;/span&gt;&lt;span style="color: #008080"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;]&lt;/span&gt;&lt;span style="color: #800080"&gt;$SB&lt;/span&gt;&lt;span style="color: #000000"&gt;.Append([&lt;/span&gt;&lt;span style="color: #008080"&gt;char&lt;/span&gt;&lt;span style="color: #000000"&gt;](&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Invoke-Expression&lt;/span&gt;&lt;span style="color: #000000"&gt; 0x$((&lt;/span&gt;&lt;span style="color: #800080"&gt;$bytes1&lt;/span&gt;&lt;span style="color: #000000"&gt;[&lt;/span&gt;&lt;span style="color: #800080"&gt;$n&lt;/span&gt;&lt;span style="color: #ff0000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;]) &lt;/span&gt;&lt;span style="color: #ff0000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$bytes1&lt;/span&gt;&lt;span style="color: #000000"&gt;[&lt;/span&gt;&lt;span style="color: #800080"&gt;$n&lt;/span&gt;&lt;span style="color: #000000"&gt;]))))
    }
    &lt;/span&gt;&lt;span style="color: #800080"&gt;$SB&lt;/span&gt;&lt;span style="color: #000000"&gt;.ToString()
}&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;А дальше уже по накатанной дороге:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;[Administrator] # создаём COM объект ICertAdmin2
[Administrator] $CertAdmin = new-object -com certificateauthority.admin.1
[Administrator] # выбираем все Enterprise CA
[Administrator] $ldap = [ADSI]&amp;quot;LDAP://CN=KRA, CN=Public Key Services, CN=Services, CN=Configuration, DC=contoso,dc=com&amp;quot;
[Administrator] $kra = $ldap.psbase.children | %{$_}
[Administrator] # сразу конвертируем все сертификаты в DER-encoded string
[Administrator] $kra1 = ConvertTo-DERstring $kra[1].usercertificate[0]
[Administrator] $kra2 = ConvertTo-DERstring $kra[1].usercertificate[1]
[Administrator] # можем убедиться на месте, что строка имеет ожидаемый вид
[Administrator] $kra2
?????A???E  ?????c?♣??????????????????T???????????????????????????????????????T????????????????????????????????????????
??ca♣??????☺????????????????????????????K?????????????????????????????????????????????т????????????????????????????????
??????????????????????☺????????Є?????????????????☻???????☻??????????????ЎЖ?????????????CA??????Ё????????????h??A???????
??????????????????????????????????????????????╣????????????????????????????????????????????????????????????????????????
?????????????????????C?cЁ??????C???????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????Х???CA?????Ё???????CA?????Б????CA??????????????????????a???☺????????????????????
????????????????????????????????????????????????????????????????????????????????????????????????????????????
[Administrator] # и записываем первую строку сертификат агента восстанвовления в нулевой индекс
[Administrator] $CertAdmin.SetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x1a,0,3,$kra1)
[Administrator] # все последующие строки сертификатов записываются в последующие индексы массива
[Administrator] $CertAdmin.SetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x1a,1,3,$kra2)
[Administrator] # используем PropID = KRACERTUSEDCOUNT (0x18), чтобы сказать сколько у нас будет использоваться агентов
[Administrator] # я буду их использовать все
[Administrator] $CertAdmin.SetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x18,0,1,2)
[Administrator] # перезапускаем службу CertSvc
[Administrator] $wmi = gwmi win32_service -comp dc2 -filter &amp;quot;name='certsvc'&amp;quot;
[Administrator] [void]$wmi.StopService()
[Administrator] [void]$wmi.StartService()
[Administrator] # и проверяем нашу работу:
[Administrator] $CertReq = new-object -com certificateauthority.request.1
[Administrator] $CertReq.GetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x18,0,1,0)
2
[Administrator] $CertReq.GetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x19,0,1,0)
2
[Administrator]&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;всё.&lt;/p&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=eabb97f4-c14f-41ef-bc4c-c3df83ecd98f"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,eabb97f4-c14f-41ef-bc4c-c3df83ecd98f.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
      <category>PowerShell / CryptoAPI</category>
    </item>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=26d5addd-f057-4e3f-8a71-a4ed0f01a836</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,26d5addd-f057-4e3f-8a71-a4ed0f01a836.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,26d5addd-f057-4e3f-8a71-a4ed0f01a836.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=26d5addd-f057-4e3f-8a71-a4ed0f01a836</wfw:commentRss>
      <title>CryptoAPI и управление Certification Authority с помощью PowerShell (часть 3)</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,26d5addd-f057-4e3f-8a71-a4ed0f01a836.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,26d5addd-f057-4e3f-8a71-a4ed0f01a836.aspx</link>
      <pubDate>Mon, 16 Nov 2009 16:04:48 GMT</pubDate>
      <description>&lt;div&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;Update 05.12.2009:&lt;/FONT&gt;&lt;/STRONG&gt; разработчики подтвердили баг в ICertAdmin2 интерфейсе. Проблема заключается&amp;nbsp;в том, что после первого запроса указанных PropID они кешируются и при смене контекста конфигурации (Certification Authority), этот кеш не очищается.&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;Прежде чем продолжать исследование CryptoAPI COM интерфейсов, предлагаю посмотреть несколько полезных ссылок и поговорить о багах в интерфейсе &lt;STRONG&gt;ICertAdmin2&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;При использовании интерфейса ICertAdmin2, ICertRequest2D (этот интерфейс мы ещё посмотрим в будущих постах) мы используем различные аргументы для получения свойст CA с использованием метода &lt;STRONG&gt;GetCAProerty()&lt;/STRONG&gt;. И вот их где мы можем получить числовые значения этих аргументов:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;PropID&lt;/STRONG&gt; и &lt;STRONG&gt;PropType&lt;/STRONG&gt; — &lt;A href="http://msdn.microsoft.com/en-us/library/cc249749(PROT.10).aspx" target=_blank&gt;&lt;STRONG&gt;3.2.1.4.3.2 ICertRequestD2::GetCAProperty (Opnum 7)&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;STRONG&gt;Flags&lt;/STRONG&gt; — &lt;A href="http://msdn.microsoft.com/en-us/library/aa374936(VS.85).aspx" target=_blank&gt;&lt;STRONG&gt;EncodingType Enumeration&lt;/STRONG&gt;&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;А теперь поговорим о багах. Как выяснилось, &lt;STRONG&gt;ICertAdmin2::GetCAProperty()&lt;/STRONG&gt;, который определён в библиотеке &lt;EM&gt;certadm.dll&lt;/EM&gt; имеет баги с PropID, которые связаны с количественной информацией. Будь то количество сертификатов CA, количество агентов восстановления ключей (&lt;STRONG&gt;Key Recovery Agents&lt;/STRONG&gt;) и т.д. И вот в чём это выражается:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;DC1&lt;/STRONG&gt; — корневой CA с именем Contoso CA. Имеет 2 сертификата CA и одного назначенного агента восстановления; 
&lt;LI&gt;&lt;STRONG&gt;DC2&lt;/STRONG&gt; — подчинённый CA с именем Contoso-DC2-CA. Имеет 1 сертификат CA и ни одного назначенного агента восстановления. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Мы будем получать данные как с локального CA, так и с удалённого CA запуская код с каждого сервера. Кратко об используемых PropID:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;0x0B&lt;/STRONG&gt; — количество сертификатов CA; 
&lt;LI&gt;&lt;STRONG&gt;0x19&lt;/STRONG&gt; — общее количество агентов восстановления на CA; 
&lt;LI&gt;&lt;STRONG&gt;0x18&lt;/STRONG&gt; — общее количество используемых агентов восстановления; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;И вот какие результаты мы видим, когда собираем эти свойства с сервера &lt;STRONG&gt;DC1&lt;/STRONG&gt;:&lt;/P&gt;
&lt;DIV style="WIDTH: 935px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;[Administrator] # создаём COM объек:
[Administrator] $CertAdmin = New-Object -com CertificateAuthority.Admin.1
[Administrator] # получаем список сертификатов CA на локальном серве
[Administrator] # мы видим 2 сертификата, как положено
[Administrator] $certadmin.GetCAProperty("dc1\contoso ca",0xb,0,1,0)
2
[Administrator] # и он то же самое показывает и для удалённого сервера, хотя там всего 1 сертификат
[Administrator] $certadmin.GetCAProperty("dc2\contoso-dc2-ca",0xb,0,1,0)
2
[Administrator] # ладно, смотрим, сколько всего KRA у нас на локальном сервере. Их 1, как на самом деле
[Administrator] $certadmin.GetCAProperty("dc1\contoso ca",0x19,0,1,0)
1
[Administrator] # используемых сертификатов тоже 1.
[Administrator] $certadmin.GetCAProperty("dc1\contoso ca",0x18,0,1,0)
1
[Administrator] # как я уже говорил, на DC2 нет агентов восстановления, хотя метод показывает их по одному в обоих случаях
[Administrator] $certadmin.GetCAProperty("dc2\contoso-dc2-ca",0x19,0,1,0)
1
[Administrator] $certadmin.GetCAProperty("dc2\contoso-dc2-ca",0x18,0,1,0)
1
[Administrator]&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;собираем ту же информацию, запуская код с сервера &lt;STRONG&gt;DC2&lt;/STRONG&gt;:&lt;/P&gt;
&lt;DIV style="WIDTH: 935px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;PS C:\&amp;gt; # создаём COM объект:
PS C:\&amp;gt; $CertAdmin = New-Object -com CertificateAuthority.Admin.1
PS C:\&amp;gt; # получаем список сертификатов CA с локального сервера.
PS C:\&amp;gt; # их мы видим ровно 1, как и должно быть
PS C:\&amp;gt; $certadmin.GetCAProperty("dc2\contoso-dc2-ca",0xb,0,1,0)
1
PS C:\&amp;gt; # в предыдущем примере мы видели, что на DC1 2 сертификата CA.
PS C:\&amp;gt; # проверим, так ли это?
PS C:\&amp;gt; $certadmin.GetCAProperty("dc1\contoso ca",0xb,0,1,0)
1
PS C:\&amp;gt; # wow! обломс, метод возвращает тоже 1. А сколько у нас агентов восстановления?
PS C:\&amp;gt; # и снова облом. На сервере DC1 нет агентов восстановления (хотя предыдущий пример говорит об обратном):
PS C:\&amp;gt; $certadmin.GetCAProperty("dc1\contoso ca",0x19,0,1,0)
0
PS C:\&amp;gt; $certadmin.GetCAProperty("dc1\contoso ca",0x18,0,1,0)
0&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;а теперь посмотрим на результаты с использованием того же метода и тех же PropID, но с использованием интерфейса ICertRequest, который определён в библиотеке &lt;EM&gt;certcli.dll&lt;/EM&gt;. Те же тесты уже возвращают правильные результаты:&lt;/P&gt;
&lt;P&gt;с &lt;STRONG&gt;DC1&lt;/STRONG&gt;:&lt;/P&gt;
&lt;DIV style="WIDTH: 935px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;[Administrator] $request = New-Object -com CertificateAuthority.Request.1
[Administrator] $request.GetCAProperty("dc1\contoso ca",0xb,0,1,0)
2
[Administrator] $request.GetCAProperty("dc2\contoso-dc2-ca",0xb,0,1,0)
1
[Administrator] $request.GetCAProperty("dc1\contoso ca",0x19,0,1,0)
1
[Administrator] $request.GetCAProperty("dc1\contoso ca",0x18,0,1,0)
1
[Administrator] $request.GetCAProperty("dc2\contoso-dc2-ca",0x19,0,1,0)
0
[Administrator] $request.GetCAProperty("dc2\contoso-dc2-ca",0x18,0,1,0)
0
[Administrator]&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;с &lt;STRONG&gt;DC2&lt;/STRONG&gt;:&lt;/P&gt;
&lt;DIV style="WIDTH: 935px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;PS C:\&amp;gt; $request = New-Object -com CertificateAuthority.Request.1
PS C:\&amp;gt; $request.GetCAProperty("dc2\contoso-dc2-ca",0xb,0,1,0)
1
PS C:\&amp;gt; $request.GetCAProperty("dc1\contoso ca",0xb,0,1,0)
2
PS C:\&amp;gt; $request.GetCAProperty("dc1\contoso ca",0x19,0,1,0)
1
PS C:\&amp;gt; $request.GetCAProperty("dc1\contoso ca",0x18,0,1,0)
1
PS C:\&amp;gt; $request.GetCAProperty("dc2\contoso-dc2-ca",0x19,0,1,0)
0
PS C:\&amp;gt; $request.GetCAProperty("dc2\contoso-dc2-ca",0x18,0,1,0)
0
PS C:\&amp;gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;Поэтому следует с осторожностью относиться к выводу &lt;STRONG&gt;ICertAdmin2::GetCAProperty()&lt;/STRONG&gt;, а ещё лучше — использовать этот метод, который реализован в интерфейсе &lt;A href="http://msdn.microsoft.com/en-us/library/aa385043(VS.85).aspx" target=_blank&gt;&lt;STRONG&gt;ICertRequest::GetCAProperty()&lt;/STRONG&gt;&lt;/A&gt;. Чем это вызвано я пока не знаю, но задал я задал вопрос нужным людям, поэтому я дам знать в случае ответа на вопрос.&lt;/P&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=26d5addd-f057-4e3f-8a71-a4ed0f01a836"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,26d5addd-f057-4e3f-8a71-a4ed0f01a836.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
      <category>PowerShell / CryptoAPI</category>
    </item>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=ca3a2177-92b3-46af-bc7b-0497cdbce74e</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,ca3a2177-92b3-46af-bc7b-0497cdbce74e.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,ca3a2177-92b3-46af-bc7b-0497cdbce74e.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=ca3a2177-92b3-46af-bc7b-0497cdbce74e</wfw:commentRss>
      <title>CryptoAPI и управление Certification Authority с помощью PowerShell (часть 2)</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,ca3a2177-92b3-46af-bc7b-0497cdbce74e.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,ca3a2177-92b3-46af-bc7b-0497cdbce74e.aspx</link>
      <pubDate>Tue, 10 Nov 2009 16:04:48 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;В &lt;a href="http://www.sysadmins.lv/PermaLink,guid,1cec0947-9113-4de2-bf48-809a09849f4c.aspx"&gt;&lt;strong&gt;первой части&lt;/strong&gt;&lt;/a&gt; управления Certification Authority (CA) мы рассмотрели метод &lt;a href="http://msdn.microsoft.com/en-us/library/aa383238(VS.85).aspx"&gt;&lt;strong&gt;GetCAProperty&lt;/strong&gt;&lt;/a&gt;, при помощи которого мы можем получать различные сведения про сервер CA. Сегодня мы посмотрим ещё несколько интересных моментов, которые будут связаны с CRL и опять будет немного треша с CryptoAPI, а именно:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Получение статуса публикации CRL; &lt;/li&gt;    &lt;li&gt;Получение Base и Delta CRL из CA в виде файлов; &lt;/li&gt;    &lt;li&gt;Отзыв сертификатов; &lt;/li&gt;    &lt;li&gt;Извлечение сертификатов из CRL; &lt;/li&gt;    &lt;li&gt;Публикация новых CRL. &lt;/li&gt; &lt;/ul&gt;  &lt;h1 align="center"&gt;Начало работы&lt;/h1&gt;  &lt;p&gt;Для начала мы должны будем создать &lt;a href="http://msdn.microsoft.com/en-us/library/aa383234(VS.85).aspx"&gt;&lt;strong&gt;ICertAdmin2&lt;/strong&gt;&lt;/a&gt; COM объект для управления CA, который будет использоваться нами для всех сегодняшних операций:&lt;/p&gt;  &lt;div style="width: 935px"&gt;   &lt;blockquote&gt;     &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $CertAdmin = New-Object -ComObject &amp;quot;CertificateAuthority.Admin.1&amp;quot;
&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;h1 align="center"&gt;Получение Base и Delta CRL из CA в виде файлов&lt;/h1&gt;

&lt;p&gt;Далее мы должны узнать PropID, который бы отвечал за показ CRL вот по этой ссылке: &lt;a href="http://msdn.microsoft.com/en-us/library/cc249749(PROT.10).aspx"&gt;&lt;strong&gt;3.2.1.4.2.2 ICertRequestD2::GetCAProperty (Opnum 7)&lt;/strong&gt;&lt;/a&gt;. Нас будет интересовать 2 этих ID: &lt;strong&gt;CR_PROP_BASECRL (0x11)&lt;/strong&gt; и &lt;strong&gt;CR_PROP_DELTACRL (0x12)&lt;/strong&gt;. Поскольку тип возвращаемых данных будет &lt;strong&gt;Binary&lt;/strong&gt;, то &lt;strong&gt;PropType&lt;/strong&gt; будет равен 3, а &lt;strong&gt;Flags&lt;/strong&gt; выставим в 0 (Base64CRLHeader). Можно и другой указать, от этого только зависит метод записи в файл.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Примечание:&lt;/font&gt;&lt;/strong&gt; напоминаю, что индекс &lt;strong&gt;PropType&lt;/strong&gt; начинается с 1, а &lt;strong&gt;Flags&lt;/strong&gt; с 0 и их возможные значения описаны здесь: &lt;a href="http://msdn.microsoft.com/en-us/library/aa383238(VS.85).aspx"&gt;&lt;strong&gt;GetCAProperty&lt;/strong&gt;&lt;/a&gt;. А так же то, что в Flags первые 2 значения перепутаны местами на MSDN.&lt;/p&gt;

&lt;p&gt;И вот как мы их можем получить:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $BaseCRL =  $certadmin.GetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x11,0,3,0)
PS C:\&amp;gt; $BaseCRL
-----BEGIN X509 CRL-----
MIIEDTCCAvUCAQEwDQYJKoZIhvcNAQEFBQAwRzETMBEGCgmSJomT8ixkARkWA2Nv
bTEXMBUGCgmSJomT8ixkARkWB2NvbnRvc28xFzAVBgNVBAMTDmNvbnRvc28tREMy
LUNBFw0wOTExMDkwNjI0NDlaFw0wOTExMTcwNjQ0NDlaMIIBzDAbAgpG7E9iAAAA
AACSFw0wOTExMDgxODM5MDBaMCkCCm716aoAAAAAAI8XDTA5MTAyMjE2MjI1OVow
DDAKBgNVHRUEAwoBBDAbAgpxOBcQAAAAAACLFw0wOTA5MjgwNjMzMDBaMBsCCl6/
ZbYAAAAAAIkXDTA5MDkyNDE3MTcwMFowGwIKXnVZiQAAAAAAiBcNMDkwOTI0MTUw
MjAwWjApAgoggMu3AAAAAAAVFw0wOTA1MTcyMDE0MDBaMAwwCgYDVR0VBAMKAQUw
KQIKYRZ2nAAAAAAADRcNMDkwNTAxMTk1MzAwWjAMMAoGA1UdFQQDCgEFMCkCCmJ0
33IAAAAAAAoXDTA5MDQxOTEzMDUwMFowDDAKBgNVHRUEAwoBBDApAgphINAVAAAA
AAAHFw0wOTAzMzExMTEzMDBaMAwwCgYDVR0VBAMKAQUwKQIKYRT3zAAAAAAABhcN
MDkwMzMxMTAzMTAwWjAMMAoGA1UdFQQDCgEFMCkCCmERwOwAAAAAAAUXDTA5MDMz
MTEwMTgwMFowDDAKBgNVHRUEAwoBBDApAgphDxXgAAAAAAAEFw0wOTAzMzExMDE0
MDBaMAwwCgYDVR0VBAMKAQSggakwgaYwHwYDVR0jBBgwFoAUZiAsZ5wOPk1F8vmX
BZdmE1QTJjYwEAYJKwYBBAGCNxUBBAMCAQAwCwYDVR0UBAQCAgDyMBwGCSsGAQQB
gjcVBAQPFw0wOTExMTYwNjM0NDlaMEYGA1UdLgQ/MD0wO6A5oDeGNWh0dHA6Ly9k
YzIuY29udG9zby5jb20vQ2VydEVucm9sbC9jb250b3NvLURDMi1DQSsuY3JsMA0G
CSqGSIb3DQEBBQUAA4IBAQCCNVxtZbAbB5C1bI5Z6PF+Eph2MaRhl9pv0FjYhH/j
Xlvffau1m5bW72No7FC2k8FFU2oHFSZvAVNKgjm6+ECb4iEpzREcHpwsot1TG0kn
Pv+DRGjQ2ndes8OM11v3oYUJxlNOMqY6q03lj/BEJb+ocNerWRay8G0sycy1ABCD
/UPvP9qq54WvwQnJyV5bZJcJG3WYtN7zkZZzf5MR3v+c4OODLiLw5pXgku49USFu
kTuEh5DYcF5zbo6h5IqAW+OP6iMFepxkUEZUb/5VOYK8VcpXDwMzIRzlf+bITHyX
6PVugwm6TXkn9eVrAfJUd70S9LV7XVTz32IykC3tNXFY
-----END X509 CRL-----


PS C:\&amp;gt; $DeltaCRL =  $certadmin.GetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x12,0,3,0)
PS C:\&amp;gt; $BaseCRL &amp;gt; base.crl
PS C:\&amp;gt; $DeltaCRL &amp;gt; delta.crl
PS C:\&amp;gt; &amp;amp; .\base.crl
PS C:\&amp;gt; &amp;amp; .\delta.crl
PS C:\&amp;gt;&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;последние 2 команды просто запускают эти CRL файлы. К сожалению не существует ни одного родного класса, который бы представлял собой объект CRL, поэтому как-то разбирать его на таком уровне пока не представляется возможным. Хотя существуют сторонние библиотеки (например, в Mono есть класс X509CRL).&lt;/p&gt;

&lt;h1 align="center"&gt;Получение статуса публикации CRL&lt;/h1&gt;

&lt;p&gt;Но мы можем кое что узнать о статусе наших CRL. Для этого существует PropID = &lt;strong&gt;CR_PROP_CRLSTATE (0x14)&lt;/strong&gt;. Тип возвращаемых данных будет Long, значит PropType будет 1, а Flags будет игнорироваться, поэтому поставим его в 0:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $certadmin.GetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x14,0,1,0)
3&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Расшифровку этого значения можно найти здесь:&amp;#160; &lt;a href="http://msdn.microsoft.com/en-us/library/cc249794(PROT.10).aspx" target="_blank"&gt;&lt;strong&gt;3.2.1.4.2.2.20 PropID = 0x00000014 (CR_PROP_CRLSTATE) &amp;quot;CA CRL State&amp;quot;&lt;/strong&gt;&lt;/a&gt;. Число 3 означает, что с CRL у нас всё хорошо (&lt;strong&gt;CA_DISP_VALID (0x03)&lt;/strong&gt;). В принципе, на данном этапе нам больше ничего и не нужно. Но мы можем посмотреть более детальные сведения по каждому типу CRL. Для получения более детальной ошибки мы должны использовать следующие PropID:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;CR_PROP_BASECRLPUBLISHSTATUS (0x1E) &lt;/strong&gt;&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;CR_PROP_DELTACRLPUBLISHSTATUS (0x1F)&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Для этих PropID тип данных так же указан Long, поэтому PropType выставим в 1, а Flags в 0:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $certadmin.GetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x1E,0,1,0)
5
PS C:\&amp;gt; $certadmin.GetCAProperty(&amp;quot;dc2\contoso-dc2-ca&amp;quot;,0x1F,0,1,0)
6
PS C:\&amp;gt;&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Мы получили число 5 для BaseCRL и 6 для DeltaCRL. Расшифровку этих значений можно посмотреть вот здесь: &lt;a href="http://msdn.microsoft.com/en-us/library/cc249804(PROT.10).aspx" target="_blank"&gt;&lt;strong&gt;3.2.1.4.2.2.30 PropID = 0x0000001E (CR_PROP_BASECRLPUBLISHSTATUS) &amp;quot;Base CRL Publishing Status&amp;quot;&lt;/strong&gt;&lt;/a&gt;. Поскольку вывод — не конкретное число, а результат двоичного оператора И (AND), то мы это число должны разбить на составляющие. И вот как это делается:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #800080"&gt;$Return&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;$certadmin&lt;/span&gt;&lt;span style="color: #000000"&gt;.GetCAProperty(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;ServerName\CA Name&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;0x1E&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;)
&lt;/span&gt;&lt;span style="color: #800080"&gt;$options&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;2&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;4&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;8&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;16&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;32&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;64&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;128&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;256&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;512&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;1024&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;2048&lt;/span&gt;&lt;span style="color: #000000"&gt; | &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;%&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$Return&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-band&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;} | ?{&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;}
&lt;/span&gt;&lt;span style="color: #008000"&gt;#&lt;/span&gt;&lt;span style="color: #008000"&gt; поскольку значения масок являются результаты возведения двойки в степень&lt;/span&gt;&lt;span style="color: #008000"&gt;
#&lt;/span&gt;&lt;span style="color: #008000"&gt; начиная от 0 до 11, то эту строчку можно переписать более готично.&lt;/span&gt;&lt;span style="color: #008000"&gt;
#&lt;/span&gt;&lt;span style="color: #008000"&gt; Напоминаю, что возведение любого числа в нулевую степень&lt;/span&gt;&lt;span style="color: #008000"&gt;
#&lt;/span&gt;&lt;span style="color: #008000"&gt; всегда вернёт 1. Кажется, это из алгебры 5-6 класса.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #800080"&gt;$options&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;.11&lt;/span&gt;&lt;span style="color: #000000"&gt;| &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;%&lt;/span&gt;&lt;span style="color: #000000"&gt;{[&lt;/span&gt;&lt;span style="color: #008080"&gt;Math&lt;/span&gt;&lt;span style="color: #000000"&gt;]::&lt;/span&gt;&lt;span style="color: #8b4513"&gt;Pow&lt;/span&gt;&lt;span style="color: #000000"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;2&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;)} | &lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;%&lt;/span&gt;&lt;span style="color: #000000"&gt;{&lt;/span&gt;&lt;span style="color: #800080"&gt;$Return&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #ff0000"&gt;-band&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;} | ?{&lt;/span&gt;&lt;span style="color: #000080"&gt;$_&lt;/span&gt;&lt;span style="color: #000000"&gt;}
&lt;/span&gt;&lt;span style="color: #0000ff"&gt;switch&lt;/span&gt;&lt;span style="color: #000000"&gt; (&lt;/span&gt;&lt;span style="color: #800080"&gt;$options&lt;/span&gt;&lt;span style="color: #000000"&gt;) {
    &lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The CRL is a base CRL&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;2&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The CRL is a delta CRL&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;4&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The last CRL publication that was completed and published to the locations specified in the CA&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;8&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The CRL is a shadow delta CRL&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;16&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The CA MAY publish the CRL to a local store that is not externally accessible.
        This error is returned when publishing to this intermediate store failed&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;32&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;An error occurred during publication of the CRL.
        The error indicates that the file schema cannot be recognized.The schema must be file: or ldap:&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;64&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Publication of the CRL was manually initiated by an administrator&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;128&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;A CRL signature error was detected. The CSP was not correct&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;256&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;An error occurred during publication of the CRL to an LDAP URL&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;512&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;An error occurred during publication of the CRL to a file URL&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;1024&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;An error occurred during publication of the CRL to an FTP URL. FTP URLs are not supported&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
    &lt;/span&gt;&lt;span style="color: #000000"&gt;2048&lt;/span&gt;&lt;span style="color: #000000"&gt; {&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The CA cannot publish CRLs to HTTP URLs. This error is returned if a CA administrator
        configured the CA to publish CRLs to HTTP URLs&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;}
}&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Следовательно число 5 (1+4) говорит нам о том, что это был Base CRL и он был опубликован успешно. А 6 (2+4) — Delta CRL был опубликован успешно.&lt;/p&gt;

&lt;h1 align="center"&gt;Отзыв сертификатов&lt;/h1&gt;

&lt;p&gt;Интерфейс IcertAdmin2 позволяет нам отзывать сертификаты на сервере CA. Для этого мы воспользуемся методом &lt;a href="http://msdn.microsoft.com/en-us/library/aa383251(VS.85).aspx" target="_blank"&gt;&lt;strong&gt;RevokeCertificate()&lt;/strong&gt;&lt;/a&gt;. Метод достаточно простой и примерная команда для отзыва сертификата будет выглядеть так:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #800080"&gt;$CertAdmin&lt;/span&gt;&lt;span style="color: #000000"&gt;.RevokeCertificate(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;ServerName\CA Name&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;0123456789&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;4&lt;/span&gt;&lt;span style="color: #000000"&gt;,(&lt;/span&gt;&lt;span style="color: #5f9ea0; font-weight: bold"&gt;Get-Date&lt;/span&gt;&lt;span style="color: #000000"&gt;).AddDays(&lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;))&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;0123456789&lt;/strong&gt; будет обозначать серийный номер сертификата, &lt;strong&gt;4&lt;/strong&gt; — причина отзыва будет Superseded и эффективная дата отзыва (когда сертификат будет помещён в Revoked Certificates) будет 24 часа после выполнения команды. Да, именно этим методом можно отзывать корневые сертификаты &lt;img alt=":)" src="/smilies/happy.gif"&gt;.&lt;/p&gt;

&lt;h1 align="center"&gt;Извлечение сертификатов из CRL&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Примечание:&lt;/font&gt;&lt;/strong&gt; хоть Microsoft и поддерживает извлечение сертификатов из CRL (отмена статуса Revoked), этой возможностью не следует пользоваться в силу определённых причин, как невозможность определеления в какое время сертификат был помещён и извлечён из CRL.&lt;/p&gt;

&lt;p&gt;Если сертификат был отозван со статусом Certificate Hold (6), то его можно в любое время вернуть обратно. Для всех остальных типов отзыва такая возможность не поддерживается. Для отмены статуса Revoked нужно использовать этот же метод, только в качестве причины отзыва указать значение MAX_DWORD, которое является &lt;strong&gt;0xffffffff&lt;/strong&gt; или просто &lt;strong&gt;–1&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #800080"&gt;$CertAdmin&lt;/span&gt;&lt;span style="color: #000000"&gt;.RevokeCertificate(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;ServerName\CA Name&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #000000"&gt;0123456789&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000"&gt;-&lt;/span&gt;&lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;h1 align="center"&gt;Публикация новых CRL&lt;/h1&gt;

&lt;p&gt;Если вы хотите опубликовать новые CRL вручную (т.е. в промежутке между плановой публикацией CRL), то мы должны воспользоваться методом &lt;a href="http://msdn.microsoft.com/en-us/library/aa383249(VS.85).aspx" target="_blank"&gt;&lt;strong&gt;PublishCRLs()&lt;/strong&gt;&lt;/a&gt;. Его синтаксис достаточно простой:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #800080"&gt;$CertAdmin&lt;/span&gt;&lt;span style="color: #000000"&gt;.PublishCRLs(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;ServerName\CA Name&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Эта команда переопубликует как основной, так и инкрементальный CRL (при публикации Base CRL инкрементальный CRL публикуется всегда, потому что Effective Date у него не может быть меньше, чем у Base CRL). Что касается последнего аргумента, то он бывает ещё полезен, если по каким-то причинам потерялся какой-то файл CRL. Тогда вы можете выставить CRLFlags в 4 (0x4) и тогда CA переопубликует текущие CRL без обновления их содержимого и дат.&lt;/p&gt;

&lt;p&gt;На сегодня это всё.&lt;/p&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=ca3a2177-92b3-46af-bc7b-0497cdbce74e"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,ca3a2177-92b3-46af-bc7b-0497cdbce74e.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
      <category>PowerShell / CryptoAPI</category>
    </item>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=1cec0947-9113-4de2-bf48-809a09849f4c</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,1cec0947-9113-4de2-bf48-809a09849f4c.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,1cec0947-9113-4de2-bf48-809a09849f4c.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=1cec0947-9113-4de2-bf48-809a09849f4c</wfw:commentRss>
      <title>CryptoAPI и управление Certification Authority с помощью PowerShell</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,1cec0947-9113-4de2-bf48-809a09849f4c.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,1cec0947-9113-4de2-bf48-809a09849f4c.aspx</link>
      <pubDate>Thu, 05 Nov 2009 20:22:36 GMT</pubDate>
      <description>&lt;div&gt;&lt;p&gt;Продолжая тему криптографии, предлагаю несколько ближайших постов посвятить вопросам использования CryptoAPI в PowerShell для управления &lt;strong&gt;Cerficiation Authority&lt;/strong&gt; (сокращённо &lt;strong&gt;CA&lt;/strong&gt;). Я считаю эту тему достаточно интересной, хоть у нас есть космическая утилита certutil.exe. Но тот, кто видел хелп к нему, тот знает какой это ужас, автоматизировать что-то с использованием certutil. Microsoft подарил нам не менее космический и православный инструмент автоматизации — PowerShell. К сожалению, вынужден признать, что в ряде задач PowerShell сильно уступает аналогам в cmd и с этим ничего нельзя поделать. Но по мере своих сил буду пытаться доказывать обратное. Одно из преимуществ PowerShell является поддержка .NET, который очень удобен в использовании. Но .NET не всемогущ и не содержит в себе ни единого класса, при помощи которого можно было бы управлять службой certificate services (точнее самим CA). CryptoAPI неплохо документированы на уровне unmanaged code (а это подразумевает использование низкоуровневых языков программирования, как C++). Но, опять, слава &lt;strike&gt;сиськамСноверу&lt;/strike&gt;Протоколу у нас есть одна лазейка — COM интерфейсы к CryptoAPI. Изучив немного эти интерфейсы, обнаружил, что они местами очень интересные и досточно легко управляемы. Но это не всегда так, иногда они бывают достаточно сложными для понимания с первого раза. В процессе исследования, были обнаружены вообще нелогичные вещи, с которыми нам придётся считаться.&lt;/p&gt;  &lt;p&gt;Эти COM интерфейсы позволили мне реализовать едва ли не половину функционала моего PowerPack'а для PowerGUI. Оценить моё детище можно по этой ссылке: &lt;a href="http://powergui.org/entry.jspa?externalID=2552&amp;amp;categoryID=21" target="_blank"&gt;&lt;strong&gt;Enterprise PKI management&lt;/strong&gt;&lt;/a&gt;. Я в него вложил достаточно много знаний для того, чтобы упростить жизнь администраторам инфраструктур PKI. Пока прогресс неважный, т.к. я пока только повторяю функционал консолей certmgr.msc, certsrv.msc, ocsp.msc и certutil.exe. Но я надеюсь реализовать там действительно что-то нужное и очень полезное.&lt;/p&gt;  &lt;p&gt;Наша отправная точка на MSDN будет находиться здесь: &lt;a href="http://msdn.microsoft.com/en-us/library/aa380253(VS.85).aspx" target="_blank"&gt;&lt;strong&gt;Cryptography Interfaces&lt;/strong&gt;&lt;/a&gt;. Для начала мы поработаем с интерфейсом &lt;a href="http://msdn.microsoft.com/en-us/library/aa383234(VS.85).aspx" target="_blank"&gt;&lt;strong&gt;ICertAdmin2&lt;/strong&gt;&lt;/a&gt;, который зарегистрирован в системе как COM класс &lt;strong&gt;CertificateAuthority.Admin.1&lt;/strong&gt;. Вот как он создаётся:&lt;/p&gt;  &lt;div style="width: 935px"&gt;   &lt;blockquote&gt;     &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $CertAdmin = New-Object -ComObject &amp;quot;CertificateAuthority.Admin.1&amp;quot;
PS C:\&amp;gt; $CertAdmin | gm


   TypeName: System.__ComObject#{f7c3ac41-b8ce-4fb4-aa58-3d1dc0e36b39}

Name                     MemberType Definition
----                     ---------- ----------
DeleteRow                Method     int DeleteRow (string, int, Date, int, int)
DenyRequest              Method     void DenyRequest (string, int)
GetArchivedKey           Method     string GetArchivedKey (string, int, int)
GetCAProperty            Method     Variant GetCAProperty (string, int, int, int, int)
GetCAPropertyDisplayName Method     string GetCAPropertyDisplayName (string, int)
GetCAPropertyFlags       Method     int GetCAPropertyFlags (string, int)
GetConfigEntry           Method     Variant GetConfigEntry (string, string, string)
GetCRL                   Method     string GetCRL (string, int)
GetMyRoles               Method     int GetMyRoles (string)
GetRevocationReason      Method     int GetRevocationReason ()
ImportCertificate        Method     int ImportCertificate (string, string, int)
ImportKey                Method     void ImportKey (string, int, string, int, string)
IsValidCertificate       Method     int IsValidCertificate (string, string)
PublishCRL               Method     void PublishCRL (string, Date)
PublishCRLs              Method     void PublishCRLs (string, Date, int)
ResubmitRequest          Method     int ResubmitRequest (string, int)
RevokeCertificate        Method     void RevokeCertificate (string, string, int, Date)
SetCAProperty            Method     void SetCAProperty (string, int, int, int, Variant)
SetCertificateExtension  Method     void SetCertificateExtension (string, int, string, int, int, Variant)
SetConfigEntry           Method     void SetConfigEntry (string, string, string, Variant)
SetRequestAttributes     Method     void SetRequestAttributes (string, int, string)


PS C:\&amp;gt;&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Как вы видите, этот интерфейс позволяет использовать достаточно много интересных методов. Давайте начнём с простого (а может быть и не очень простого) — &lt;a href="http://msdn.microsoft.com/en-us/library/aa383238(VS.85).aspx" target="_blank"&gt;&lt;strong&gt;GetCAProperty&lt;/strong&gt;&lt;/a&gt;. По ссылке вообще ничего непонятно, что и как там использовать. Единственное, что я понял — это то, что данный метод принимает 5 параметров в определённом порядке и всё. Поэтому давайте будем считать, что этой странички не существует в природе (кроме случаев, когда будем преследовать порядок расположения аргументов). Пошарившись на MSDN, нашёл более годную ссылку в спецификациях &lt;strong&gt;Windows Communications Protocols&lt;/strong&gt; — &lt;a href="http://msdn.microsoft.com/en-us/library/cc249749(PROT.10).aspx" target="_blank"&gt;&lt;strong&gt;3.2.1.4.2.2 ICertRequestD2::GetCAProperty (Opnum 7)&lt;/strong&gt;&lt;/a&gt;. И вот как должны выглядеть параметры:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;strConfig&lt;/strong&gt; — имя компьютера и сервера CA в формате &lt;font color="#0000ff"&gt;ComputerName\CAName&lt;/font&gt;. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;PropId&lt;/strong&gt; — ID требуемого свойства. Должно указываться в числовом формате (т.к. тип данных указан Long). Это число можно взять из колонки &lt;strong&gt;Numerical Value&lt;/strong&gt; таблички &lt;a href="http://msdn.microsoft.com/en-us/library/cc249749(PROT.10).aspx" target="_blank"&gt;&lt;strong&gt;3.2.1.4.2.2 ICertRequestD2::GetCAProperty (Opnum 7)&lt;/strong&gt;&lt;/a&gt;. Например, для получения DeltaCRL надо указать число &lt;strong&gt;18&lt;/strong&gt; (0x12). &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;PropIndex&lt;/strong&gt; — если свойство индексированное (т.е. содержит несколько искомых объектов), то PropIndex указывает на индекс массива, в котором хранится определённый объект искомого свойства. Например, CA может содержать несколько своих сертификатов. И с использованием PropIndex мы сможем выбирать различные сертификаты, выбирая их из массива. Начало индексирования начинается с нуля. Если свойство неиндексируемое, то это значение будет игнорироваться. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;PropType&lt;/strong&gt; — указываете тип данных, в котором хотите получить конкретное свойство. Во второй таблице уже указаны рекомендованные значения типов данных для каждого набора свойств. Тип данных так же нужно указывать в числовом формате. Однако, &lt;font color="#ff0000"&gt;здесь индекс начинается не с нуля, а с единицы&lt;/font&gt;. Т.е. тип данных &lt;strong&gt;String&lt;/strong&gt; будет иметь значение &lt;strong&gt;4&lt;/strong&gt;. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Flags&lt;/strong&gt; — помимо типа возвращаемых данных нам нужно указать формат этих данных. Во второй таблице так же приведены рекомендованные (хотя слово MUST и ещё капсом как бы намекает на обязательность. Хотя, это не совсем так. Если вы в первый раз будете этим заниматься, то используйте значения из второй таблички). А вот здесь индекс начинается с нуля. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Примечание:&lt;/font&gt;&lt;/strong&gt; по всей видимости в табличке с флагами закралась ошибка, т.к. использование первого флага даёт Base64, но с заголовками Begin/End Certificate. А второй — наоборот, без заголовка.&lt;/p&gt;

&lt;p&gt;Вам кажется, что это всё ужасно и сложно? Поверьте, это не так. Давайте прочитаем парочку свойств. Например, прочитаем ссылки на CRL и CRT, которые публикуются в CDP и AIA издаваемых сертификатах. Исходя из таблички мы знаем, что CRL'ы вызываются &lt;strong&gt;PropID = 0x29&lt;/strong&gt; (или 41 в десятичной нотации), а CRT — &lt;strong&gt;PropID = 0x2A&lt;/strong&gt; (или 42). Поскольку это индексируемое свойство, то первая ссылка будет содержаться в индексе 0 (первый индекс массива), а последующие ссылки в индексах 1 и далее и &lt;strong&gt;PropIndex&lt;/strong&gt; мы укажем &lt;strong&gt;0&lt;/strong&gt;. PropType у нас будет &lt;strong&gt;String&lt;/strong&gt; и числовое значение — 4 (не забываем, что PropType считаются начиная с единицы). &lt;strong&gt;Flags&lt;/strong&gt; может быть любой, т.к. он будет игнорироваться при &lt;strong&gt;PropType = 4&lt;/strong&gt;:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $CertAdmin.GetCAProperty(&amp;quot;ca\sysadmins-lv-ca&amp;quot;, 41, 0, 4, 0)
http://ca.sysadmins.lv/sysadmins-LV-CA.crl

PS C:\&amp;gt; $CertAdmin.GetCAProperty(&amp;quot;ca\sysadmins-lv-ca&amp;quot;, 42, 0, 4, 0)
http://ca.sysadmins.lv/sysadmins-LV-CA.crt

PS C:\&amp;gt;&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Как вы видите, на самом деле здесь нет ничего страшного. Нужно лишь научиться оперировать табличкой. Давайте для разнообразия посмотрим на сертификат CA. Для этого мы должны найти PropID, который отвечал за сертификат. Это будет &lt;strong&gt;PropID = 0xC&lt;/strong&gt;. Поскольку этот параметр так же индексируемый, то он будет содержать все сертификаты CA, если их там несколько. Самый первый сертификат будет храниться в индексе 0, следующий сертификат в индексе 1 и т.д. Исходя из таблички, PropType должен быть 3. Посмотрим сертификат в Base64 кодировке, т.е. Flags должен быть 0 или 1:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $cert = $CertAdmin.GetCAProperty(&amp;quot;ca\sysadmins-lv-ca&amp;quot;, 0xc, 0, 3, 0)
PS C:\&amp;gt; $cert
-----BEGIN CERTIFICATE-----
MIIFbTCCA1WgAwIBAgIQPf+vkU1hMoJCe9WRwftYbTANBgkqhkiG9w0BAQUFADBJ
MRIwEAYKCZImiZPyLGQBGRYCbHYxGTAXBgoJkiaJk/IsZAEZFglzeXNhZG1pbnMx
GDAWBgNVBAMTD3N5c2FkbWlucy1MVi1DQTAeFw0wOTA4MDYwNzIxMDFaFw0xNDA4
MDYwNzMwNTRaMEkxEjAQBgoJkiaJk/IsZAEZFgJsdjEZMBcGCgmSJomT8ixkARkW
CXN5c2FkbWluczEYMBYGA1UEAxMPc3lzYWRtaW5zLUxWLUNBMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEAwL5wHTMEsMg6yDzqWPd9e/GT856o9OWJrv4Y
9iXtTa5mkdEZsbckVmAJODG28lcI7ScuD0rfceB6/gVn4VMK2SITsOv2XzC3ApRE
zExEIuRmspFlpaDmOvBTYafkzokN2RJ+UQq8M9RSnSBHrOcvNJQYgglbjQOHsg4f
qyMoPoZ+LYjoGZcCtqmR+FMOnalUGohnanf/fQJ/gcoAET6H45rqAB/P90sWOsZo
pwCgGmvJe4GBXbZDg4ADZIbrYm2baxwKJlhsDAhzZ8Fo2irnSBFJavu6+LwQHv8P
fL/ZGHBlf8s+uTeHfluG95bIe8VAGRwEwCyV5t+emBLq4ny5Q21MjWGDD3YjkKjA
lqC7c2mpCC6YVxBArVVm1G7/d8mpBuO5ZzyqIVkEhxZuYPfK6k7EEKx3BuCC97UT
ZcSVJBCHmxbxWm/U30VIpu0HDlbCiHX0OSDRJhv32ppazDonGSp/GiBocXNKTLA+
PyXQqRvObovTFPMutzLQDczeee5zvfJ7Gs7xCskcsLp8uBuhGJMnW87hRglm4p0/
tdIViIbMrwbVxjtHPnp5MARvQBT26ZzE3k0zr9Do3Gi6AY8Jt6ssD6r5CXbBA5SF
iGgp1czWb2xToqJtzuEjG1ssBj5MTMzINa4bMhQs52nXdUI2aG7n7mwoAVR3tHiW
sK1lvdsCAwEAAaNRME8wCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
VR0OBBYEFHrmiNrp+Fw+BwTeEaI4Iql1oxOrMBAGCSsGAQQBgjcVAQQDAgEAMA0G
CSqGSIb3DQEBBQUAA4ICAQCuLfQSOcRoQ8EcuVMgIVjepuonY1MG7PhPvJ1fyanw
0MeKonNZ4a7gOop7R/8DSGBfnQMQJClVcFTxe8Osa88OkeJmb9LQix9wMfR1GAaw
NwaX6ve0x4Ixr7m3KQEBOc+fAAGNLcxnlIDUD9EiSlFqqH+HkjxREU5RmE0TQFVS
NfNtwFSX0loMuL8mo10m8CD/ETRdq6jXO6vMWll8wBirSD9/Zostn5+t1g6TU4fi
bpR/56ueiRh0px2A1lhDTTGjV7UTqPvavUqJejZJCHf269xJb1r8mc+AJn/O4g4q
WvVsTILLMw+Oit/7ZagFbjZa7jSBRFfEyU4lKnV9oxIO47FTjWgGi7R+Rg8VDWvQ
a5JMhMadUWrz5VQRY9iBr1wlmvZH5100otrikZLfVxQ+HZVccgLvZ4BJpdk+Lzyk
bqZSAwbOJlFF0po+4wWbakhzS/jZLcoO8NzE4SgW3NTcuWYsS2G8ubV139IykSCy
RA9UcyoNNQM8CXr6I2UmhQwBqMrGZIi/rybPRQvlVSssuusfbxIiWMjdo/mQyUH2
A1diiIt1bpkVdJ9yRSDtuldoYe2w0QtId6WWAg2H8bTiF+/cu1kZ//rcK5UQyuku
1ggS22YqWCUrSQ4/heQdP1Ni619sMHFcMYWZTP5XySLiN+BBrs6/4pnJOVNsy742
KQ==
-----END CERTIFICATE-----

PS C:\&amp;gt; $cert &amp;gt; file.cer
PS C:\&amp;gt; &amp;amp; c:\file.cer
PS C:\&amp;gt;&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Последней строчкой я вызвал команду, которая покажет мне сертификат как я бы запустил сам файл (я это и сделал этой командой на самом деле). Если там сертификат не один, то следующий сертификат можно было бы получить вот такой командой:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font color="#0000ff"&gt;$CertAdmin.GetCAProperty(&amp;quot;ServerName\CA Name&amp;quot;, 0xC, 1, 3, 0)&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Я просто увеличил PropIndex на единицу. Чтобы узнать сколько же там всего сертификатов, достаточно посмотреть PropID = 0x0B, PropType = 1 (т.к. команда нам вернёт число, то тип должен быть числовой — &lt;strong&gt;Long&lt;/strong&gt;):&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;PS C:\&amp;gt; $CertAdmin.GetCAProperty(&amp;quot;ca\sysadmins-lv-ca&amp;quot;, 0xb, 0, 1, 0)
1
PS C:\&amp;gt;&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Вот в данном случае у меня там всего 1 сертификат. На другом сервере у меня 2 сертификата:&lt;/p&gt;

&lt;div style="width: 935px"&gt;
  &lt;blockquote&gt;
    &lt;pre style="background-color: #000040; font: 9pt consolas, lucida console"&gt;&lt;font color="#c0c0c0"&gt;&lt;span&gt;&lt;p&gt;[Administrator] $CertAdmin.GetCAProperty(&amp;quot;dc1\contoso ca&amp;quot;, 0xb, 0, 1, 0)
2
[Administrator]&lt;/p&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Если вам это интересно, то советую поупражняться в получении различных свойств в различном формате с использованием ICertAdmin2 интерфейса и таблички: &lt;a href="http://msdn.microsoft.com/en-us/library/cc249749(PROT.10).aspx" target="_blank"&gt;&lt;strong&gt;3.2.1.4.2.2 ICertRequestD2::GetCAProperty (Opnum 7)&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Это была первая часть использования CryptoAPI в PowerShell. В следующих частях мы рассмотрим другие интересные методы интерфейса &lt;strong&gt;ICertAdmin2&lt;/strong&gt;.&lt;/p&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=1cec0947-9113-4de2-bf48-809a09849f4c"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,1cec0947-9113-4de2-bf48-809a09849f4c.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
      <category>PowerShell / CryptoAPI</category>
    </item>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=9099b393-27a4-45c1-a9e2-ca39067035de</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,9099b393-27a4-45c1-a9e2-ca39067035de.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,9099b393-27a4-45c1-a9e2-ca39067035de.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=9099b393-27a4-45c1-a9e2-ca39067035de</wfw:commentRss>
      <title>Start/Stop-CertificationAuthority</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,9099b393-27a4-45c1-a9e2-ca39067035de.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,9099b393-27a4-45c1-a9e2-ca39067035de.aspx</link>
      <pubDate>Thu, 15 Oct 2009 16:55:57 GMT</pubDate>
      <description>&lt;div&gt;&lt;P&gt;Ещё небольшое дополнение к &lt;STRONG&gt;Certificate Management Pack&lt;/STRONG&gt;, который я сейчас пишу. Данный код позволяет запускать и останавливать службу &lt;STRONG&gt;Certification Authority&lt;/STRONG&gt; на сервере. Поскольку я для решения этой задачи использую WMI, то ремотинг будет обеспечен. Следует учесть, что все команды по управлению службой CA будут расположены за конвейером после команды &lt;A href="http://www.sysadmins.lv/PermaLink,guid,947401b2-312a-4129-860b-4296dfe46cb2.aspx"&gt;Get-CertificationAuthority&lt;/A&gt;. Это было сделано в рамках удобства и стандартизации. Когда мы хотим что-то настроить в CA, то сначала должны указать его имя/объект. Поскольку у нас уже есть готовое решение для этого, то почему бы его и не использовать? Код на самом деле очень простой и в нём разберётся даже новичок:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: #008000"&gt;#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;####################################################################&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Start-Stop CA.ps1&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Version 1.0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Starts and stops Certification Authority service on specified CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Requires Get-CertificationAuthority cmdlet:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; http://www.sysadmins.lv/PermaLink,guid,947401b2-312a-4129-860b-4296dfe46cb2.aspx&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Usage:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Get-CertificationAuthority "CAName" | Stop-CertificationAuthority&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; stops CA service on CA named CAName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Get-CertificationAuthority | Start-CertificationAuthority&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; starts all Enterprise CAs in current forest&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; Vadims Podans (c) 2009&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt; http://www.sysadmins.lv/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
#&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;####################################################################&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;function&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0"&gt;Start-CertificationAuthority&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) {
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;process&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; {
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$status&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;gwmi&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Win32_Service&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-STYLE: italic; COLOR: #5f9ea0"&gt;-ComputerName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.Computer &lt;/SPAN&gt;&lt;SPAN style="FONT-STYLE: italic; COLOR: #5f9ea0"&gt;-Filter&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Name = 'CertSvc'&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;).StartService()
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$status&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.ReturnValue &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;-eq&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) {
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;Write-Host&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.CAName &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Certificate&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Services&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;successfully&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;started&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;on&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.Computer &lt;/SPAN&gt;&lt;SPAN style="FONT-STYLE: italic; COLOR: #5f9ea0"&gt;-ForegroundColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Green&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
        } &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; {
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;Write-Warning&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Unable to start $($CA.CAName) certificate services&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
        }
    }
}

&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;function&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0"&gt;Stop-CertificationAuthority&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) {
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;process&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; {
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$status&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;gwmi&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Win32_Service&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-STYLE: italic; COLOR: #5f9ea0"&gt;-ComputerName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.Computer &lt;/SPAN&gt;&lt;SPAN style="FONT-STYLE: italic; COLOR: #5f9ea0"&gt;-Filter&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Name = 'CertSvc'&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;).StopService()
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$status&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.ReturnValue &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;-eq&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) {
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;Write-Host&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.CAName &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Certificate&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Services&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;successfully&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;stopped&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;on&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.Computer &lt;/SPAN&gt;&lt;SPAN style="FONT-STYLE: italic; COLOR: #5f9ea0"&gt;-ForegroundColor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Green&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
        } &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; {
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;Write-Warning&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Unable to stop $($CA.CAName) certificate services&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
        }
    }
}&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Можно сказать, что выносить данные команды в отдельные функции излишне, ведь это можно и самому дописать в свой скрипт. Но можно и не сказать так, ведь представьте, насколько удобно, когда нужная функция у вас уже есть под рукой, и её не надо писать с нуля.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;Update:&lt;/FONT&gt;&lt;/STRONG&gt; хочу ещё раз отметить на одну из частых ошибок, которые допускают при написании скриптов в PowerShell. Вы можете просто использовать переменные в двойных кавычках и при использовании этой строки в неё будет подставляться содержимое переменной. Но этого не будет, если вы используете свойство объекта, который хранится в этой переменной, поскольку переменные экспандятся только 1 раз. Этого достаточно для простой переменной, но недостаточно для извлечения содержимого свойста объекта в этой переменной. Ведь сначала нужно извлечь содержимое переменной, а потом прочитать содержимое указанного свойства. Чтобы экспандить такие вещи, переменные в двойных кавычках следует заключать в подвыражение &lt;STRONG&gt;$()&lt;/STRONG&gt;.&lt;/P&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=9099b393-27a4-45c1-a9e2-ca39067035de"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,9099b393-27a4-45c1-a9e2-ca39067035de.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
    </item>
    <item>
      <trackback:ping>http://www.sysadmins.lv/Trackback.aspx?guid=947401b2-312a-4129-860b-4296dfe46cb2</trackback:ping>
      <pingback:server>http://www.sysadmins.lv/pingback.aspx</pingback:server>
      <pingback:target>http://www.sysadmins.lv/PermaLink,guid,947401b2-312a-4129-860b-4296dfe46cb2.aspx</pingback:target>
      <dc:creator>Camelot</dc:creator>
      <wfw:comment>http://www.sysadmins.lv/CommentView,guid,947401b2-312a-4129-860b-4296dfe46cb2.aspx</wfw:comment>
      <wfw:commentRss>http://www.sysadmins.lv/SyndicationService.asmx/GetEntryCommentsRss?guid=947401b2-312a-4129-860b-4296dfe46cb2</wfw:commentRss>
      <title>Get-CertificationAuthority</title>
      <guid isPermaLink="false">http://www.sysadmins.lv/PermaLink,guid,947401b2-312a-4129-860b-4296dfe46cb2.aspx</guid>
      <link>http://www.sysadmins.lv/PermaLink,guid,947401b2-312a-4129-860b-4296dfe46cb2.aspx</link>
      <pubDate>Tue, 06 Oct 2009 18:15:39 GMT</pubDate>
      <description>&lt;div&gt;&lt;P&gt;А знаете ли вы как можно легко получить список всех Enterprise CA в текущем домене? А в текущем лесу? Оказывается это очень легко! &lt;STRONG&gt;ADSI&lt;/STRONG&gt; — самый лучший способ, если вы хотите пошариться в своей базе AD. Список таких CA находится по пути:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, DC=Domain, DC=COM&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Последние 2 значения уже будут отличаться в зависимости от имени домена. Чтобы получить список объектов по этому пути нужно просто создать соответствующий LDAP объект. Объект делается просто, сначала указывается тип объекта [ADSI], следом идёт префикс ссылки &lt;STRONG&gt;LDAP://&lt;/STRONG&gt; (почти как HTTP://) и после префикса уже этот путь (который называется &lt;STRONG&gt;Distinguished Name&lt;/STRONG&gt; или просто &lt;STRONG&gt;DN&lt;/STRONG&gt;):&lt;/P&gt;
&lt;DIV style="WIDTH: 925px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;[Administrator] $CA = [ADSI]"LDAP://CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, DC=co
ntoso,DC=COM"
[Administrator] $CA


distinguishedName : {CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com}
Path              : LDAP://CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, DC=contoso,DC
                    =COM
[Administrator] $CA.distinguishedName
CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;Если посмотреть этот путь в &lt;STRONG&gt;ADSIEdit.msc&lt;/STRONG&gt;, то мы увидим, что это контейнер. А раз это контейнер, то нам нужно в него заглянуть. Здесь, к сожалению, нельзя сделать &lt;FONT color=#0000ff&gt;dir $CA.distinguishedName&lt;/FONT&gt;, а так хочется. Чтобы посмотреть содержимое нужно использовать свойство &lt;STRONG&gt;Children&lt;/STRONG&gt; (ворненк, дети отаке!):&lt;/P&gt;
&lt;DIV style="WIDTH: 925px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;[Administrator] $ca.Children


distinguishedName : {CN=contoso-DC2-CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=co
                    ntoso,DC=com}
Path              : LDAP://CN=contoso-DC2-CA,CN=Enrollment Services,CN=Public Key Services, CN=Services, CN=Configurati
                    on, DC=contoso,DC=COM

distinguishedName : {CN=Contoso CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contos
                    o,DC=com}
Path              : LDAP://CN=Contoso CA,CN=Enrollment Services,CN=Public Key Services, CN=Services, CN=Configuration,
                    DC=contoso,DC=COM



[Administrator]&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;Уже отсюда невооружённым глазом видны имена CA. Собственно, можно показать только имя самого CA и компьютера, на котором работает этот CA:&lt;/P&gt;
&lt;DIV style="WIDTH: 925px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;[Administrator] $ca.Children | ft Name, DNSHostName

Name                                                        DNSHostName
----                                                        -----------
{contoso-DC2-CA}                                            {dc2.contoso.com}
{Contoso CA}                                                {DC1.contoso.com}


[Administrator]&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;Здесь есть один важный нюанс. Если получить этот LDAP объект в PowerShell 1.0, то он будет содержать только Distinguished Name, а свойство Children будет отсутствовать в нём. Для этого нужно воспользоваться свойством PSBase, в котором уже будет &lt;STRONG&gt;Children&lt;/STRONG&gt;. Командой &lt;STRONG&gt;Select&lt;/STRONG&gt; можете выводить на экран и другие свойства, какие вы захотите:&lt;/P&gt;
&lt;DIV style="WIDTH: 925px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;PS C:\&amp;gt; $ca.children


MemberType          : Method
OverloadDefinitions :
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               :
Name                : children
IsInstance          : True



PS C:\&amp;gt; $ca.psbase.children

distinguishedName
-----------------
{CN=contoso-DC2-CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com}
{CN=Contoso CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com}


PS C:\&amp;gt; $ca.psbase.children | select Name, DNSHostname

Name                                                        DNSHostname
----                                                        -----------
{contoso-DC2-CA}                                            {dc2.contoso.com}
{Contoso CA}                                                {DC1.contoso.com}


PS C:\&amp;gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;Поэтому для обратной совместимости между версиями лучше использовать &lt;STRONG&gt;PSBase&lt;/STRONG&gt;. В этом объекте будут содержаться не только CA вашего домена, а во всех доменах вашего леса, поскольку эта часть AD реплицируется как &lt;EM&gt;Forest naming context&lt;/EM&gt;, т.е. между всеми контроллерами в лесу. Жизнь была бы неинтересной, если в каждом новом домене приходилось бы переписывать хвост (которая определяет домен, в котором следует искать) каждый раз. Для универсальности можно пойти на военную хитрость — раздобыть FQDN текущего домена, разобрать его и воткнуть в LDAP запрос. Получить имя текущего домена можно очень просто, с использованием статического метода &lt;A href="http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectory.domain.getcurrentdomain(VS.80).aspx" target=_blank&gt;GetCurrentDomain()&lt;/A&gt; класса &lt;A href="http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectory.domain(VS.80).aspx" target=_blank&gt;System.DirectoryServices.ActiveDirectory.Domain&lt;/A&gt;. На самом деле у этого класса есть ещё куча других полезных методов, поэтому не лишним будет заглянуть по ссылке.&lt;/P&gt;
&lt;DIV style="WIDTH: 915px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;PS C:\&amp;gt; [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()


Forest                  : contoso.com
DomainControllers       : {DC1.contoso.com}
Children                : {}
DomainMode              : Windows2003Domain
Parent                  :
PdcRoleOwner            : DC1.contoso.com
RidRoleOwner            : DC1.contoso.com
InfrastructureRoleOwner : DC1.contoso.com
Name                    : contoso.com



PS C:\&amp;gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;И свойство Name будет содержать имя нашего домена. Что дальше? А дальше, вполне очевидно, что нам надо заменить все точки на строку вида &lt;STRONG&gt;", DC=&lt;/STRONG&gt;". Вот так:&lt;/P&gt;
&lt;DIV style="WIDTH: 915px"&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE style="BACKGROUND-COLOR: #000040; FONT: 9pt consolas, lucida console"&gt;&lt;FONT color=#c0c0c0&gt;&lt;SPAN&gt;&lt;P&gt;PS C:\&amp;gt; "contoso.com" -replace "\.", ", DC="
contoso, DC=com&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;/DIV&gt;
&lt;P&gt;А перед первым именем эту часть можно написать ручками. В итоге универсальная часть кода получится вот такая:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: #800080"&gt;$domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; ([&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008080"&gt;System.DirectoryServices.ActiveDirectory.Domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;]::&lt;/SPAN&gt;&lt;SPAN style="COLOR: #8b4513"&gt;GetCurrentDomain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;()).Name
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;DC=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;+&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;-replace&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;'&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;\.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;'&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;, DC=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; [&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008080"&gt;ADSI&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;]&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;LDAP://CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, $domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Вот теперь у нас есть всё необходимое, чтобы написать простеньку функцию:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: #0000ff"&gt;function&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0"&gt;Get-CertificationAuthority&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; ([&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008080"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;]&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CAName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) {
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; ([&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008080"&gt;System.DirectoryServices.ActiveDirectory.Domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;]::&lt;/SPAN&gt;&lt;SPAN style="COLOR: #8b4513"&gt;GetCurrentDomain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;()).Name
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;DC=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;+&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;-replace&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;'&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;\.&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;'&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;, DC=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; [&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008080"&gt;ADSI&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;]&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;LDAP://CN=Enrollment Services, CN=Public Key Services, CN=Services, CN=Configuration, $domain&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CAs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CA&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.psBase.Children | &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;{
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$current&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;""&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; | &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;Select&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; CAName, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Computer&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$current&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.CAName &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$_&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; | &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$_&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.Name}
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$current&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.Computer &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$_&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; | &lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f9ea0; FONT-WEIGHT: bold"&gt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$_&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.DNSHostName}
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$current&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
    }
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CAName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) {&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CAs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; @(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CAs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; | ?{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$_&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.CAName &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;-eq&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CAName&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;})}
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CAs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;.Count &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;-eq&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) {&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Sorry, here is no CA that match your search&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;}
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;$CAs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
}&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Если выполнить эту функцию без аргументов, то она вернёт все CA в лесу. Но можно указать и какой-то один для каких-то других целей.&lt;/P&gt;&lt;img width="0" height="0" src="http://www.sysadmins.lv/aggbug.ashx?id=947401b2-312a-4129-860b-4296dfe46cb2"/&gt;&lt;br/&gt;&lt;hr/&gt;PowerShell Powered - http://www.sysadmins.lv&lt;/div&gt;</description>
      <comments>http://www.sysadmins.lv/CommentView,guid,947401b2-312a-4129-860b-4296dfe46cb2.aspx</comments>
      <category>PowerShell</category>
      <category>PowerShell / Certificate Authority</category>
    </item>
  </channel>
</rss>