You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PowerShell获取Windows证书的非标准Description属性

获取Windows证书非标准Description属性的替代方案

好问题!CAPICOM确实已被微软弃用,而且在远程执行场景下限制很多。这里有几个更现代、支持远程操作的可行方案:

方案1:使用CIM/WMI远程读取(最适合远程场景)

Windows原生的Win32_Certificate WMI类直接包含Description属性,而且支持通过CIM会话远程访问目标机器的证书存储。这种方法无需额外依赖,完美适配PowerShell远程执行:

# 创建远程CIM会话(需目标机器开启WinRM服务)
$remoteSession = New-CimSession -ComputerName "TargetPCName" -Credential (Get-Credential)

# 读取远程机器本地计算机个人存储的证书及Description属性
Get-CimInstance -CimSession $remoteSession -ClassName Win32_Certificate -Filter "StoreName='My' and StoreLocation='LocalMachine'" | 
    Select-Object Subject, Description, Thumbprint

# 用完记得关闭会话
Remove-CimSession $remoteSession

注意:目标机器需要提前启用WinRM,且当前用户拥有访问远程证书存储的权限。

方案2:.NET结合P/Invoke读取底层属性

如果WMI返回的Description不够准确,你可以通过.NET调用Win32 CryptAPI,直接读取证书上下文的CERT_DESCRIPTION_PROPERTY属性,精度更高:

Add-Type @"
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;

public class CertHelper {
    private const uint CERT_DESCRIPTION_PROPERTY = 0x0000000D;

    [DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool CryptGetCertificateContextProperty(
        IntPtr pCertContext,
        uint dwPropId,
        IntPtr pvData,
        ref uint pcbData);

    public static string GetCertDescription(X509Certificate2 cert) {
        uint bufferSize = 0;
        // 先获取所需缓冲区大小
        if (!CryptGetCertificateContextProperty(cert.Handle, CERT_DESCRIPTION_PROPERTY, IntPtr.Zero, ref bufferSize)) {
            return null;
        }
        IntPtr buffer = Marshal.AllocHGlobal((int)bufferSize);
        try {
            if (CryptGetCertificateContextProperty(cert.Handle, CERT_DESCRIPTION_PROPERTY, buffer, ref bufferSize)) {
                return Marshal.PtrToStringUni(buffer);
            }
            return null;
        } finally {
            Marshal.FreeHGlobal(buffer);
        }
    }
}
"@

# 本地读取示例(可通过Invoke-Command远程执行)
Get-ChildItem Cert:\LocalMachine\My | ForEach-Object {
    [PSCustomObject]@{
        Subject = $_.Subject
        Thumbprint = $_.Thumbprint
        Description = [CertHelper]::GetCertDescription($_)
    }
}

这个方法可以直接操作证书底层上下文,拿到最准确的Description属性,而且能通过PowerShell远程会话(比如Invoke-Command)在目标机器上执行。

方案3:使用CertEnroll COM对象(CAPICOM替代者)

CertEnroll是微软官方替代CAPICOM的COM组件,至今仍被支持,也能适配远程执行场景:

# 远程执行示例(通过Invoke-Command)
Invoke-Command -ComputerName "TargetPCName" -Credential (Get-Credential) -ScriptBlock {
    $certStore = New-Object -ComObject X509Enrollment.CX509Store
    $certStore.Open(2, "MY", 0) # 2代表LocalMachine存储,0代表只读模式
    foreach ($cert in $certStore.Certificates) {
        # 13对应CERT_DESCRIPTION_PROPERTY的数值常量
        $descProp = $cert.GetProperty(13)
        [PSCustomObject]@{
            Subject = $cert.Subject
            Thumbprint = $cert.Thumbprint
            Description = if ($descProp) { $descProp.Value } else { $null }
        }
    }
    $certStore.Close()
}

内容的提问来源于stack exchange,提问作者SoldierDog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:20:12