PowerShell证书过期时间解析报错:无法识别有效DateTime格式
问题:PowerShell解析证书过期日期时触发DateTime格式错误
报错信息
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
问题原因
脚本中通过GetExpirationDateString()获取的证书过期日期格式为11/17/2024(月/日/年),但代码中使用了不匹配的'dd/MM/yyyy HH:mm:ss'格式字符串进行解析,导致格式识别失败。
原脚本代码
$minCertAge = 80 $timeoutMs = 10000 $sites = @( "hbc.com/namespace/health", "abcxs.com/namespace/health", "abcads.com/namespace/health" ) # Disable certificate validation [Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} foreach ($site in $sites) { Write-Host Check $site -f Green $req = [Net.HttpWebRequest]::Create($site) $req.Timeout = $timeoutMs try {$req.GetResponse() |Out-Null} catch {Write-Host URL check error $site`: $_ -f Red} $expDate = $req.ServicePoint.Certificate.GetExpirationDateString() Write-Host $expDate Write-Host "above expdate return in format 11/17/2024" write-host "---------------------------------" $certExpDate = [datetime]::ParseExact($expDate, 'dd/MM/yyyy HH:mm:ss', $null) write-host "Errors out with the above line" [int]$certExpiresIn = ($certExpDate - $(get-date)).Days $certName = $req.ServicePoint.Certificate.GetName() $certThumbprint = $req.ServicePoint.Certificate.GetCertHashString() $certEffectiveDate = $req.ServicePoint.Certificate.GetEffectiveDateString() $certIssuer = $req.ServicePoint.Certificate.GetIssuerName() if ($certExpiresIn -gt $minCertAge) {Write-Host The $site certificate expires in $certExpiresIn days [$certExpDate] -f Green} else { $message= "The $site certificate expires in $certExpiresIn days" $messagetitle= "Renew certificate" Write-Host $message [$certExpDate]. Details:`n`nCert name: $certName`Cert thumbprint: $certThumbprint`nCert effective date: $certEffectiveDate`nCert issuer: $certIssuer -f Red } write-host "________________" `n }
解决方案
最优修复:直接获取原生DateTime属性
避免字符串解析的麻烦,直接调用GetExpirationDate()获取DateTime类型的过期日期,同时GetEffectiveDate()也替换为原生属性:
$minCertAge = 80 $timeoutMs = 10000 $sites = @( "hbc.com/namespace/health", "abcxs.com/namespace/health", "abcads.com/namespace/health" ) # Disable certificate validation [Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} foreach ($site in $sites) { Write-Host Check $site -f Green $req = [Net.HttpWebRequest]::Create($site) $req.Timeout = $timeoutMs try { $req.GetResponse() | Out-Null } catch { Write-Host URL check error $site`: $_ -f Red } # 直接获取DateTime类型的过期日期,无需字符串解析 $certExpDate = $req.ServicePoint.Certificate.GetExpirationDate() [int]$certExpiresIn = ($certExpDate - (Get-Date)).Days $certName = $req.ServicePoint.Certificate.GetName() $certThumbprint = $req.ServicePoint.Certificate.GetCertHashString() # 同样替换为原生DateTime属性 $certEffectiveDate = $req.ServicePoint.Certificate.GetEffectiveDate() $certIssuer = $req.ServicePoint.Certificate.GetIssuerName() if ($certExpiresIn -gt $minCertAge) { Write-Host "The $site certificate expires in $certExpiresIn days [$certExpDate]" -f Green } else { $message = "The $site certificate expires in $certExpiresIn days" Write-Host "$message [$certExpDate]. Details:`n`nCert name: $certName`nCert thumbprint: $certThumbprint`nCert effective date: $certEffectiveDate`nCert issuer: $certIssuer" -f Red } Write-Host "________________`n" }
备选修复:修正格式字符串匹配
如果坚持使用字符串解析,将格式字符串改为匹配的MM/dd/yyyy:
$expDate = $req.ServicePoint.Certificate.GetExpirationDateString() $certExpDate = [datetime]::ParseExact($expDate, 'MM/dd/yyyy', $null)
或者使用Parse自动识别格式(依赖系统区域设置,可靠性略低):
$certExpDate = [datetime]::Parse($expDate)
内容的提问来源于stack exchange,提问作者user804401
相关产品推荐
相关产品推荐

