PowerShell函数返回后数据类型变更引发比较错误的原因咨询
问题现象
在Get-IssuedCertificates函数内部执行$certificateFromIssuer.NotAfter -lt $today可正常比较,但将该函数返回的证书对象传递给DeleteExpiredCertificates函数后,执行比较时出现以下错误:
Cannot compare "@{NotAfter=8/28/2025 5:25:53 PM}" to "8/29/2024 2:56:25 PM" because the objects are not the same type or the object "@{NotAfter=8/28/2025 5:25:53 PM}" does not implement "IComparable"
同时在DeleteExpiredCertificates中直接使用$expiredCertificates.NotAfter返回空值,必须通过$expiredCertificates | Select-Object -Property NotAfter才能获取属性值。
原因分析
Select-Object误用导致类型错误
Select-Object -Property NotAfter不会直接返回NotAfter的DateTime值,而是生成一个包含NotAfter属性的自定义PSObject。这个对象无法与Get-Date返回的DateTime类型变量$today进行比较,因此触发类型不匹配错误。数组对象的成员访问逻辑问题
当Get-IssuedCertificates返回多个证书对象时,$expiredCertificates是一个数组。直接访问$expiredCertificates.NotAfter会返回所有证书的NotAfter值组成的数组,但未遍历数组直接使用会导致逻辑不符合预期;若返回单个证书对象,代码未处理数组/单个对象的差异,也会导致直接访问时出现异常。
解决方案
- 遍历传入的证书对象(无论单个还是多个),逐个判断是否过期
- 直接访问证书对象的
.NotAfter属性,避免使用Select-Object生成自定义对象 - 确保比较的是DateTime类型的值,而非包装后的对象
修正后的完整代码
function Get-IssuedCertificates { param ( [Parameter(Mandatory = $true)] $issuer ) $certificates = Get-ChildItem -Path Cert:\CurrentUser\My $certificatesFromIssuer = $certificates | Where-Object { $_.Issuer -like "*$issuer*" } if ($certificatesFromIssuer) { return ,$certificatesFromIssuer # 强制返回数组,确保单个证书时也保持数组结构 } else { Write-Output "No certificates found from issuer: $issuer" return @() } } function DeleteExpiredCertificates { param ( [Parameter(Mandatory = $false)] [System.Security.Cryptography.X509Certificates.X509Certificate2[]]$expiredCertificates ) $today = Get-Date # 遍历每个证书对象,逐个判断 foreach ($cert in $expiredCertificates) { if ($cert.NotAfter -lt $today) { Write-Host "Certificate expired on: $($cert.NotAfter)" # 这里可以添加删除证书的逻辑,比如: # $cert | Remove-Item -Force } } } # 调用函数 DeleteExpiredCertificates -expiredCertificates (Get-IssuedCertificates -issuer Dexter)
关键修改说明
- 在
DeleteExpiredCertificates的参数中指定类型[System.Security.Cryptography.X509Certificates.X509Certificate2[]],确保传入的是证书对象数组 - 使用
foreach遍历每个证书,直接访问$cert.NotAfter获取DateTime类型值,与$today进行合法比较 - 移除了错误的
Select-Object调用,避免生成无法比较的自定义对象
内容的提问来源于stack exchange,提问作者foreverNoob

