在Powershell中检索证书信息有问题吗



我正试图构建一个仪表板来检索我们所有服务器上的证书信息,但我在处理powershell对象时遇到了困难。我相信这就是物体在循环内外传递的方式。我的代码有3次迭代。

在第一种情况下,检索所有证书,但每个对象上的FriendlyName都被清空:

$serverCert = $null
$servers=get-adcomputer -filter { ( OperatingSystem -like '*server*') -AND ( Name -notlike '*-DT0094' ) } | sort Name
foreach ( $server in $servers ) { 
$ServerName=$server.Name
$ServerName="$ServerName.DOMAINSUFFIX"
$serverCert += Invoke-Command -ComputerName $ServerName -Scriptblock { 
return $(Get-ChildItem Cert:LocalMachineMy)
}
}
$serverCert | Select-Object PSComputerName, Thumbprint, FriendlyName, NotAfter, @{N="Template";E={($_.Extensions | ?{$_.oid.Friendlyname -match "Certificate Template Information"}).Format(0) -replace "(.+)?=(.+)((.+)?", '$2'}}, @{N="IssuedBy";E={($_.IssuerName.Name -split ',*..=')[1]}}, @{N="Subject";E={($_.Subject -split ',*..=')[1]}} | Sort Thumbprint | Format-Table -Wrap

在这次迭代中,扩展如下所示:

PS C:WINDOWS> $serverCert[0] | Select-Object -Property Extensions
Extensions
----------
{System.Security.Cryptography.Oid, System.Security.Cryptography.Oid}

在第二个例子中,我通过显式地将FriendlyName作为一个名为"Description"的新属性传递来解决这个问题。。。不幸的是,现在模板没有显示:

$serverCert = $null
$servers=get-adcomputer -filter { ( OperatingSystem -like '*server*') -AND ( Name -notlike '*-DT0094' ) } | sort Name
foreach ( $server in $servers ) { 
$ServerName=$server.Name
$ServerName="$ServerName.DOMAINSUFFIX"
$serverCert += Invoke-Command -ComputerName $ServerName -Scriptblock { 
return $(Get-ChildItem Cert:LocalMachineMy | Select-Object *, @{N="Description";E={$_.FriendlyName}})
}
}
$serverCert | Select-Object PSComputerName, Thumbprint, Description, NotAfter, @{N="Template";E={($_.Extensions | ?{$_.oid.Friendlyname -match "Certificate Template Information"}).Format(0) -replace "(.+)?=(.+)((.+)?", '$2'}}, @{N="IssuedBy";E={($_.IssuerName.Name -split ',*..=')[1]}}, @{N="Subject";E={($_.Subject -split ',*..=')[1]}} | Sort Thumbprint | Format-Table -Wrap

在这次迭代中,扩展是这样完成的,我无法获得要显示的模板名称:

PS C:WINDOWS> $serverCert[0] | Select-Object -Property Extensions
Extensions
----------
{System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension, System.Security.Cryptography.X509Certificates.X509KeyUsageExtension}

现在是第三个。这一次,我尝试将模板信息作为类似"描述"的属性向前传递。问题是,模板信息没有清晰地传递出来;显示的不是友好名称,而是其他信息。

$serverCert = $null
$servers=get-adcomputer -filter { ( OperatingSystem -like '*server*') -AND ( Name -notlike '*-DT0094' ) } | sort Name
foreach ( $server in $servers ) { 
$ServerName=$server.Name
$ServerName="$ServerName.DOMAINSUFFIX"
$serverCert += Invoke-Command -ComputerName $ServerName -Scriptblock { 
return $(Get-ChildItem Cert:LocalMachineMy | Select-Object *, @{N="Description";E={$_.FriendlyName}}, @{N="Template";E={($_.Extensions | ?{$_.oid.Friendlyname -match "Certificate Template Information"}).Format(0) -replace "(.+)?=(.+)((.+)?", '$2'}})
}
}
$serverCert | Select-Object PSComputerName, Thumbprint, Description, NotAfter, Template, @{N="IssuedBy";E={($_.IssuerName.Name -split ',*..=')[1]}}, @{N="Subject";E={($_.Subject -split ',*..=')[1]}} | Sort Thumbprint | Format-Table -Wrap

一些证书的模板信息(我无法关联模板、操作系统版本……任何内容(如下:

模板=1.3.6.1.4.1.311.21.8.16245382.12313948.10571683.3565079.1665071.100.15924968.15384388,主要版本号=100,次要版本号=4

我被难住了。我在powershell中仍然感觉很舒服,但我对对象操作的理解还不够好,不知道如何解决这个问题。感谢您的帮助!

我认为在第一次迭代中没有返回FriendlyName与使用-ComputerName参数时PowerShell反序列化数据的方式有关。

在第一次迭代中,尝试更改这一行:

return $(Get-ChildItem Cert:LocalMachineMy)

至:

return $(Get-ChildItem Cert:LocalMachineMy | Select-Object *)

为了说明这个问题,运行这三个命令,您希望它们都包含相同的对象属性。请注意,FriendlyName仅包含在前两个命令的输出中:

Invoke-Command -ScriptBlock { gci Cert:LocalMachineMy } | Select-Object FriendlyName
Invoke-Command -ScriptBlock { gci Cert:LocalMachineMy | Select-Object * }  -ComputerName . | Select-Object FriendlyName
Invoke-Command -ScriptBlock { gci Cert:LocalMachineMy }  -ComputerName . | Select-Object FriendlyName

编辑:我可以这样做:

Function Get-Cert-Info($ComputerName) {
Invoke-Command -Computer $ComputerName -ScriptBlock {
$certs = Get-ChildItem cert:localmachinemy
foreach($cert in $certs) {
[pscustomobject]@{
ComputerName = $env:COMPUTERNAME
Thumbprint = $cert.Thumbprint
Description = $cert.FriendlyName
TemplateName = $(
$Template = $cert.Extensions | Where-Object { $_.oid.FriendlyName -match "Certificate Template Information" }
if($Template) { 
($Template.Format(0) -split "(")[0] -replace "Template=", ""
}
)
SAN=$(
try {
$cert.Extensions | Where-Object {$_.Oid.FriendlyName -eq "subject alternative name"} | ForEach {
$SANString = "{0}" -f $_.Format(0)
$SANS = $SANString -split ','
foreach($SAN in $SANS) {
($SAN -split "=")[1]
}
}  
} catch {
"n/a"
}
)
IssuedBy=$(($cert.IssuerName.Name -split ',')[0] -replace 'CN=', '')
Subject=$(($cert.Subject -split ',')[0] -replace 'CN=', '')
NotAfter=$cert.NotAfter       
}  
}
}
}
$servers=get-adcomputer -filter { ( OperatingSystem -like '*server*') -AND ( Name -notlike '*-DT0094' ) } | sort Name
foreach ( $server in $servers ) { 
Get-Cert-Info -ComputerName $server.Name
}

我找到了一种获取模板名称的方法,但查找会失败,所以当我获得ID:时,我做了类似于替换的事情

# Get all certificates from all servers
clear-host
$serverCert = $null
ipconfig /flushdns
$servers=get-adcomputer -filter { OperatingSystem -like '*server*' } | sort Name
foreach ( $server in $servers ) { 
$ServerName=$server.Name
$ServerName="$ServerName.DOMAINSUFFIX"
$serverCert += Invoke-Command -ComputerName $ServerName -Scriptblock { 
return $(Get-ChildItem Cert:LocalMachineMy | Select-Object *, @{N="Description";E={$_.FriendlyName}}, @{N="TemplateName";E={($_.Extensions | ?{$_.oid.Friendlyname -match "Certificate Template Information"}).Format(0) -replace "(.+)?=(.+)((.+)?", '$2' -replace 'Template=', '' -replace '1.3.6.1.4.1.311.21.8.16245382.12313948.10571683.3565079.1665071.100.15924968.15384388.*', 'SCCM Client Certificate' -replace '1.3.6.1.4.1.311.21.8.16245382.12313948.10571683.3565079.1665071.100.9941395.14900143.*','IIS Web Servers' -replace '1.3.6.1.4.1.311.21.8.16245382.12313948.10571683.3565079.1665071.100.1979823.4984146.*','WSUS Web Server Certificate'}})
}
}
$serverCert | Select-Object PSComputerName, Thumbprint, Description, NotAfter, TemplateName, @{N="IssuedBy";E={($_.IssuerName.Name -split ',*..=')[1]}}, @{N="Subject";E={($_.Subject -split ',*..=')[1]}} | Sort NotAfter, PSComputerName | Format-Table -Wrap

最新更新