在Powershell中检索证书信息有麻烦吗?

时间:2018-07-10 18:58:36

标签: 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:\LocalMachine\My)
    }
}
$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:\LocalMachine\My | 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:\LocalMachine\My | 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感到满意,但是我对对象操作的理解不够深刻,无法知道如何解决此问题。任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:1)

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

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

return $(Get-ChildItem Cert:\LocalMachine\My)

收件人:

return $(Get-ChildItem Cert:\LocalMachine\My | Select-Object *)

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

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

编辑:这就是我的做法:

Function Get-Cert-Info($ComputerName) {
  Invoke-Command -Computer $ComputerName -ScriptBlock {
    $certs = Get-ChildItem cert:\localmachine\my

    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
}

答案 1 :(得分:0)

虽然我找到了一种获取模板名称的方法,但是查找会失败,所以当我获得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:\LocalMachine\My | 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