Powershell 处理AD用户证书

Powershell 处理AD用户证书,powershell,x509certificate,pki,Powershell,X509certificate,Pki,我是Powershell中的一个不速之客,实际问题是我对如何搜索各种属性有点迷茫,很难找到符合我需要的示例 说到这里,我需要的是通过Active Directory搜索从特定的证书颁发机构颁发的即将过期的用户S/MIME证书 我已经: $Mail = user@example.com $allProfileCerts = Get-ADUser -Server example.com:3268 -Filter {EmailAddress -eq $Mail} -Properties Certifi

我是Powershell中的一个不速之客,实际问题是我对如何搜索各种属性有点迷茫,很难找到符合我需要的示例

说到这里,我需要的是通过Active Directory搜索从特定的证书颁发机构颁发的即将过期的用户S/MIME证书

我已经:

$Mail = user@example.com
$allProfileCerts = Get-ADUser -Server example.com:3268 -Filter {EmailAddress -eq $Mail} -Properties Certificates  | select Certificates
结果是:

       Handle Issuer     Subject                                                                                                             
       ------ ------     -------                                                                                                             
1625625266096 CN=<CA1>   E=test.user@example.com, CN=Test User, OU=Normal, OU=Users, OU=EXAMPLE, ...
1625625265968 CN=<CA2>   E=test.user@example.com, CN=Test User, O=Example Company, ...    
1625625271728 CN=<CA1>   CN=Test User, OU=Normal, OU=Users, OU=EXAMPLE, ...
结果提供了更多细节(编辑以删除PII):

然后如何访问“NotAfter”字段?我尝试了
$oneCert.“NotAfter”
$oneCert[“NotAfter”]
$oneCert |%NotAfter
$oneCert |选择-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
}

我将根据
ObjectId
值进行筛选:

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

此示例依赖于
EnhancedKeyUsageList
中OID的属性枚举,因此它仅适用于PowerShell 4.0或更新版本

我将根据
ObjectId
值进行筛选:

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

此示例依赖于
EnhancedKeyUsageList
中OID的属性枚举,因此它仅适用于PowerShell 4.0或更高版本。通常,您可以使用
Where Object
过滤管道,使用
-eq
过滤列表。在这种情况下,类似于:

$adUser.Certificates | Where-Object {
    $_.EnhancedKeyUsageList.oid.Value -eq "1.3.6.1.5.5.7.3.4"
}
将为您提供EKU列表中包含
“1.3.6.1.5.5.7.3.4”
的所有用户证书

请注意,当Powershell(4.0及更高版本)看到这样一个表达式
$object.Property.ChildProperty.SomeData
时,它会获取所有
属性
值,对于所有这些属性,它会获取所有
SomeData
值。这节省了相当多的打字时间。在传统的命令式语言中,需要嵌套循环,而在Powershell中根本不需要任何循环

知道了这一点,
$\uz.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 $_
}

通常,您可以使用
Where Object
过滤管道,使用
-eq
过滤列表。在这种情况下,类似于:

$adUser.Certificates | Where-Object {
    $_.EnhancedKeyUsageList.oid.Value -eq "1.3.6.1.5.5.7.3.4"
}
将为您提供EKU列表中包含
“1.3.6.1.5.5.7.3.4”
的所有用户证书

请注意,当Powershell(4.0及更高版本)看到这样一个表达式
$object.Property.ChildProperty.SomeData
时,它会获取所有
属性
值,对于所有这些属性,它会获取所有
SomeData
值。这节省了相当多的打字时间。在传统的命令式语言中,需要嵌套循环,而在Powershell中根本不需要任何循环

知道了这一点,
$\uz.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 $_
}

您是否尝试过引用
$oneCert.EnhancedKeyUsageList
?PowerShell在
X509Certificate2
的类型数据中添加了一个
ScriptProperty
,因此您不必手动解析它。感谢大家提供了有用的答案,事实证明我上面描述的内容与我在测试中所做的不完全一样:/I添加了| fl-f*以查看所有属性,我刚刚意识到它返回了一个字符串,不是我可以操作的对象:)您是否尝试过引用
$oneCert.EnhancedKeyUsageList
?PowerShell在
X509Certificate2
的类型数据中添加了一个
ScriptProperty
,因此您不必手动解析它。感谢大家提供了有用的答案,事实证明我上面描述的内容与我在测试中所做的不完全一样:/I添加了| fl-f*以查看所有属性,我刚刚意识到它返回了一个字符串,不是一个我可以操纵的物体:)谢谢你详细的回答,这帮了我很大的忙!作为记录,AD提供了X509Certificate对象,您需要将其强制转换为X509Certificate2,以使任何筛选器都能工作。另外,过滤器应该是这样的:{$\uz.EnhancedKeyUsageList.FriendlyName-eq“Secure Email”}。感谢您的反馈!我确信按OID过滤也是可能的,但按名称过滤当然要小得多。OID和名称都可以,但它是“ObjectID”,而不是“OID”,而“ObjectID.value”不起作用-“ObjectID”起作用。如果有人稍后读到,请稍作澄清:-)好的:)我无法正确测试此问题,因为我在系统上找不到任何证书,它的
EnhancedKeyUsageList
,我不知道为什么。感谢详细的回答,这帮了大忙!作为记录,AD提供了X509Certificate对象,您需要将其强制转换为X509Certificate2,以使任何筛选器都能工作。另外,过滤器应该是这样的:{$\uz.EnhancedKeyUsageList.FriendlyName-eq“Secure Email”}。感谢您的反馈!我确信按OID过滤也是可能的,但按名称过滤当然要小得多。OID和名称都可以,但它是“ObjectID”,而不是“OID”,而“ObjectID.value”不起作用-“ObjectID”起作用。如果有人稍后读到,请稍作澄清:-)好的:)我无法正确测试这一点,因为我在我的系统上找不到任何证书,它的
EnhancedKeyUsageList
,我不知道为什么。