Arhn - архитектура программирования

Обработка пользовательских сертификатов AD

Я совсем новичок в Powershell, и проблема в том, что я немного не понимаю, как искать различные свойства, и мне трудно найти примеры, соответствующие моим потребностям.

С учетом сказанного мне нужно выполнить поиск в Active Directory, чтобы найти пользовательские сертификаты S/MIME, срок действия которых истекает, выданные определенным центром сертификации.

Что у меня уже есть:

$Mail = [email protected]
$allProfileCerts = Get-ADUser -Server example.com:3268 -Filter {EmailAddress -eq $Mail} -Properties Certificates  | select Certificates

Результат:

       Handle Issuer     Subject                                                                                                             
       ------ ------     -------                                                                                                             
1625625266096 CN=<CA1>   [email protected], CN=Test User, OU=Normal, OU=Users, OU=EXAMPLE, ...
1625625265968 CN=<CA2>   [email protected], CN=Test User, O=Example Company, ...    
1625625271728 CN=<CA1>   CN=Test User, OU=Normal, OU=Users, OU=EXAMPLE, ...

Я подумал, что следующим шагом может быть:

$allProfileCerts.Certificates | foreach {New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $_}

Результаты содержат более подробную информацию (отредактировано для удаления PII):

EnhancedKeyUsageList     : {Secure Email (1.3.6.1.5.5.7.3.4)}
DnsNameList              : {Test User}
SendAsTrustedIssuer      : False
EnrollmentPolicyEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
EnrollmentServerEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
PolicyId                 : 
Archived                 : False
Extensions               : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid...}
FriendlyName             : 
IssuerName               : System.Security.Cryptography.X509Certificates.X500DistinguishedName
NotAfter                 : 29/05/2021 10:47:00
NotBefore                : 11/12/2018 09:47:00
HasPrivateKey            : False
PrivateKey               : 
PublicKey                : System.Security.Cryptography.X509Certificates.PublicKey
RawData                  : {48, 130, 8, 51...}
SerialNumber             : <snip>
SubjectName              : System.Security.Cryptography.X509Certificates.X500DistinguishedName
SignatureAlgorithm       : System.Security.Cryptography.Oid
Thumbprint               : <snip>
Version                  : 3
Handle                   : 1625625266096
Issuer                   : <ISSUER1>
Subject                  : <subject>

EnhancedKeyUsageList     : {Secure Email (1.3.6.1.5.5.7.3.4)}
DnsNameList              : {Test User}
SendAsTrustedIssuer      : False
EnrollmentPolicyEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
EnrollmentServerEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
PolicyId                 : 
Archived                 : False
Extensions               : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid...}
FriendlyName             : 
IssuerName               : System.Security.Cryptography.X509Certificates.X500DistinguishedName
NotAfter                 : 30/08/2020 14:00:00
NotBefore                : 30/08/2018 02:00:00
HasPrivateKey            : False
PrivateKey               : 
PublicKey                : System.Security.Cryptography.X509Certificates.PublicKey
RawData                  : {48, 130, 5, 127...}
SerialNumber             : <snip>
SubjectName              : System.Security.Cryptography.X509Certificates.X500DistinguishedName
SignatureAlgorithm       : System.Security.Cryptography.Oid
Thumbprint               : <snip>
Version                  : 3
Handle                   : 1625625265968
Issuer                   : <ISSUER2>
Subject                  : <subject>

EnhancedKeyUsageList     : {Encrypting File System (1.3.6.1.4.1.311.10.3.4)}
DnsNameList              : {Test User}
SendAsTrustedIssuer      : False
EnrollmentPolicyEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
EnrollmentServerEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
PolicyId                 : 
Archived                 : False
Extensions               : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid, System.Security.Cryptography.Oid...}
FriendlyName             : 
IssuerName               : System.Security.Cryptography.X509Certificates.X500DistinguishedName
NotAfter                 : 09/04/2020 15:57:37
NotBefore                : 22/10/2017 15:57:37
HasPrivateKey            : False
PrivateKey               : 
PublicKey                : System.Security.Cryptography.X509Certificates.PublicKey
RawData                  : {48, 130, 8, 4...}
SerialNumber             : <snip>
SubjectName              : System.Security.Cryptography.X509Certificates.X500DistinguishedName
SignatureAlgorithm       : System.Security.Cryptography.Oid
Thumbprint               : <snip>
Version                  : 3
Handle                   : 1625625271728
Issuer                   : <ISSUER1>
Subject                  : <subject>

Я также понял, что могу легко фильтровать по дате, используя Where-Object NotAfter... (поправьте меня, если я ошибаюсь в этом :)), но ради любви к миру я не могу понять, как фильтровать EnhancedKeyUsageList : {Secure Email (1.3.6.1.5.5.7.3.4)}. Я думаю, что это массив (в любом данном сертификате может быть более одного EKU), но как я могу фильтровать по элементам массива?

Бонусный вопрос: если у меня есть:

$oneCert = $allProfileCerts.Certificates | foreach {New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $_} | Where-Object SerialNumber -Match "<SN>"

Как мне тогда получить доступ к полю «NotAfter»? Пробовал $oneCert."NotAfter", $oneCert["NotAfter"], $oneCert | % NotAfter, $oneCert | select -expandproperty "NotAfter" - не работает :/

РЕДАКТИРОВАТЬ: код, который работает, на основе предложения @tomalak:

Get-ADUser -Server $Server -Filter {EmailAddress -eq $Mail} -Property Certificates |
    ForEach-Object {
        # ...we have "user" objects here
        Write-Host $_

        $_.Certificates | 
            foreach {New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $_} |
            Where-Object {
                $_.EnhancedKeyUsageList.FriendlyName -eq "Secure Email"
            }
    } |
    ForEach-Object {
    # ...we have "certificate" objects here
    Write-Host $_.Issuer
}

  • Вы пробовали ссылаться на $oneCert.EnhancedKeyUsageList? PowerShell добавляет ScriptProperty к данным типа для X509Certificate2, поэтому вам не нужно анализировать их вручную. 18.03.2019
  • Спасибо всем за полезные ответы, оказывается, то, что я описал выше, не совсем то, что я делал в своих тестах :/ Я добавил | fl -f * чтобы увидеть все свойства, и я только сейчас понял, что он возвращает строку, а не объект, которым я могу манипулировать :) 19.03.2019

Ответы:


1

Как правило, вы можете использовать Where-Object для фильтрации конвейера и -eq для фильтрации списков. В этом случае что-то вроде:

$adUser.Certificates | Where-Object {
    $_.EnhancedKeyUsageList.oid.Value -eq "1.3.6.1.5.5.7.3.4"
}

предоставит вам все сертификаты пользователя, у которых есть "1.3.6.1.5.5.7.3.4" в их списке EKU.

Обратите внимание, что когда Powershell (4.0 и более поздние версии) видит такое выражение $object.Property.ChildProperty.SomeData, он извлекает все Property значений, для всех из них он извлекает все ChildProperty значений и для всех < em>их он извлекает все SomeData значений. Это экономит довольно много времени. В традиционном императивном языке для этого вам понадобятся вложенные циклы, в Powershell вам вообще не нужны никакие циклы.

Зная это, $_.EnhancedKeyUsageList.oid.Value -eq "1.3.6.1.5.5.7.3.4" становится возможным, потому что -eq не является вашим традиционным оператором «равенства»: он берет список значений и фильтрует их, то есть:

1,2,3 -eq 3  # produces 3
1,3,3 -eq 3  # produces 3,3

Вы могли бы пойти так далеко, как

Get-ADUser -Property Certificates | Where-Object {
    $_.Certificates.EnhancedKeyUsageList.oid.Value -eq "1.3.6.1.5.5.7.3.4"
}

чтобы получить всех пользователей AD, имеющих соответствующий сертификат, за один раз.

Поскольку вы хотите отфильтровать два свойства на сертификат, я бы порекомендовал некоторые варианты

$minValid = (Get-Date).AddMonths(6)

Get-ADUser -Property Certificates -PipelineVariable user | ForEach-Object {
    # ...we have "user" objects here
    Write-Host $_

    $_.Certificates | Where-Object {
        $_.EnhancedKeyUsageList.oid.Value -eq "1.3.6.1.5.5.7.3.4" -and $_.NotAfter -lt $minValid
    }
} | ForEach-Object {
    # ...we have "certificate" objects here
    Write-Host $_
}
18.03.2019
  • Спасибо за подробный ответ, очень помогло! Для справки, AD предоставляет объект X509Certificate, который необходимо преобразовать в X509Certificate2 для работы любых фильтров. Кроме того, фильтр должен выглядеть так: { $_.EnhancedKeyUsageList.FriendlyName -eq Secure Email}. 19.03.2019
  • Спасибо за ответ! Я уверен, что фильтрация по OID также возможна, но фильтрация по имени, конечно, намного менее громоздка. 19.03.2019
  • И oid, и name в порядке, afaik, но это ObjectID, а не OID, и objectid.value не работает - работает objectid. Просто небольшие уточнения, если кто-то прочитает это позже :-) 19.03.2019
  • Хорошо :) Я не смог проверить это должным образом, потому что не смог найти в своей системе ни одного сертификата, в котором было бы что-то в его EnhancedKeyUsageList, я не знаю, почему. 19.03.2019

  • 2

    Я бы отфильтровал значение ObjectId:

    $certificates |Where-Object {$_.EnhancedKeyUsageList.ObjectId -like '1.3.6.1.5.5.7.3.2'}
    

    Этот пример основан на перечислении свойств OID в EnhancedKeyUsageList, поэтому он будет работать только в PowerShell 4.0 или новее.

    18.03.2019
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..