Powershell使用HttpClient获取API证书过期时间的方案咨询
PowerShell获取API站点证书信息的可行方案
你之前使用[Net.HttpWebRequest]返回null的核心原因除该类已被官方标记过时外,还因为仅创建了请求对象未实际发起连接,ServicePoint未完成TLS握手自然无法获取证书。以下是两种稳定可用的实现方案:
方案1:基于TLS握手直接提取证书(推荐)
该方案无需发送完整HTTP请求,仅通过TLS握手即可获取证书信息,性能更高,尤其适合批量查询多个站点的证书过期时间。
# 配置参数 $timeoutMs = 10000 $sites = @("https://testsite1.com/", "https://testsite2.com/") foreach ($site in $sites) { # 自动解析域名与端口 $uri = [Uri]$site $domain = $uri.Host $port = $uri.Port try { $tcpClient = New-Object System.Net.Sockets.TcpClient $connectTask = $tcpClient.ConnectAsync($domain, $port) # 超时判断 if (-not $connectTask.Wait($timeoutMs)) { Write-Host "连接 $domain 超时" -ForegroundColor Red continue } # 建立TLS流,回调忽略所有证书校验错误(确保过期/自签名证书也能正常获取) $sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream(), $false, { $true }) $authenticateTask = $sslStream.AuthenticateAsClientAsync($domain) if (-not $authenticateTask.Wait($timeoutMs)) { Write-Host "$domain TLS握手超时" -ForegroundColor Red $sslStream.Dispose() $tcpClient.Dispose() continue } # 提取证书信息 $cert = $sslStream.RemoteCertificate $certExpDate = [DateTime]$cert.GetExpirationDateString() $remainingDays = [Math]::Round(($certExpDate - [DateTime]::Now).TotalDays, 2) Write-Host "站点地址:$site" -ForegroundColor Green Write-Host "证书到期时间:$certExpDate" Write-Host "剩余有效天数:$remainingDays 天`n" # 释放资源 $sslStream.Dispose() $tcpClient.Dispose() } catch { Write-Host "处理 $site 异常:$_" -ForegroundColor Red } }
方案优势:
- 仅做TLS握手,查询效率远高于HTTP请求方案
- 内置超时逻辑,避免脚本长时间卡住
- 忽略证书校验错误,不会因为证书过期、自签名、域名不匹配等问题中断查询
方案2:基于HttpClient实现
如果你当前的脚本已经在使用HttpClient做其他接口请求,可以用该方案复用HTTP能力。
# 初始化HttpClient配置 $receivedCert = $null $handler = [System.Net.Http.HttpClientHandler]::new() # 自定义校验回调,捕获证书并忽略所有校验错误 $handler.ServerCertificateCustomValidationCallback = { param($sender, $cert, $chain, $sslErrors) $script:receivedCert = $cert return $true } $client = [System.Net.Http.HttpClient]::new($handler) $client.Timeout = [TimeSpan]::FromMilliseconds(10000) $sites = @("https://testsite1.com/") foreach ($site in $sites) { try { # 发起HEAD请求,减少不必要的流量消耗 $request = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Head, $site) $response = $client.SendAsync($request).Result $certExpDate = $receivedCert.GetExpirationDateString() $remainingDays = [Math]::Round(([DateTime]$certExpDate - [DateTime]::Now).TotalDays, 2) Write-Host "站点地址:$site" -ForegroundColor Green Write-Host "证书到期时间:$certExpDate" Write-Host "剩余有效天数:$remainingDays 天`n" } catch { Write-Host "处理 $site 异常:$_" -ForegroundColor Red } }
方案注意点:
- 需要发起完整HTTP请求,性能低于TLS握手方案
- 适合已有HttpClient使用逻辑的场景复用
内容的提问来源于stack exchange,提问作者ChawleeJay
相关产品推荐
相关产品推荐

