用于检查 URL 状态的 PowerShell 脚本
Posted
技术标签:
【中文标题】用于检查 URL 状态的 PowerShell 脚本【英文标题】:PowerShell script to check the status of a URL 【发布时间】:2013-12-14 02:03:08 【问题描述】:Similar to this question here 我正在尝试监控一组网站链接是否启动并运行或没有响应。我在 Internet 上找到了相同的 PowerShell 脚本。
但是,我需要检查更具体的链接,而不是直接的网站链接,例如:
http://mypage.global/Chemical/
http://maypage2:9080/portal/site/hotpot/
当我尝试检查这些链接的状态时,我得到以下输出:
URL StatusCode StatusDescription ResponseLength TimeTaken
http://mypage.global/Chemical/ 0
http://maypage2:9080/portal/site/hotpot/ 0
以上链接需要我连接到***,但我可以从浏览器访问这些链接。
Invoke-WebRequest -Uri https://***.com/questions/20259251/powershell-script-to-check-the-status-of-a-url
的输出:
PS C:\Users\682126> Invoke-WebRequest -Uri https://***.com/questions/20259251/powershell-script-to-check-the-status-of-a-url
The term 'Invoke-WebRequest' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:18
+ Invoke-WebRequest <<<< -Uri https://***.com/questions/20259251/powershell-script-to-check-the-status-of-a-url > tmp.txt
+ CategoryInfo : ObjectNotFound: (Invoke-WebRequest:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
$PSVersionTable
Name Value
---- -----
CLRVersion 2.0.50727.5472
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions 1.0, 2.0
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
【问题讨论】:
究竟是什么给了你这样的输出? 如果你这样做会发生什么?:Invoke-WebRequest -Uri http://mypage.global/Chemical/
Invoke-WebRequest 仅适用于 PowerShell 3。您要么必须升级到 PowerShell 3,要么找到其他方式来处理请求。
@Dangph 升级是不可能的,因为我没有管理员权限......还有什么其他方法可以实现?
【参考方案1】:
我最近设置了一个执行此操作的脚本。
正如 David Brabant 指出的那样,您可以使用 System.Net.WebRequest
类来执行 HTTP 请求。
要检查它是否可操作,您应该使用以下示例代码:
# First we create the request.
$HTTP_Request = [System.Net.WebRequest]::Create('http://google.com')
# We then get a response from the site.
$HTTP_Response = $HTTP_Request.GetResponse()
# We then get the HTTP code as an integer.
$HTTP_Status = [int]$HTTP_Response.StatusCode
If ($HTTP_Status -eq 200)
Write-Host "Site is OK!"
Else
Write-Host "The Site may be down, please check!"
# Finally, we clean up the http request by closing it.
If ($HTTP_Response -eq $null)
Else $HTTP_Response.Close()
【讨论】:
谢谢,完成了这项工作。但是,如果我要显示每个 URL 的响应时间,当 URL 启动时,我如何获得该值? 要显示响应时间,您可以使用(Measure-Command HTTP REQUEST CODE HERE).TotalSeconds
包装执行 Web 请求的代码部分
你也可以设置 $HTTP_Request.Method="HEAD" 这只会给你没有正文的标题部分,因为没有发送正文会更快
只是检查:我们应该在最后一行关闭什么,$HTTP_Response
或 $HTTP_Request
?
$HTTP_Request
,类型为System.Net.HttpWebRequest
,没有成员close()
【参考方案2】:
对于拥有 PowerShell 3 或更高版本(即 Windows Server 2012+ 或带有 the Windows Management Framework 4.0 update 的 Windows Server 2008 R2)的用户,您可以执行此单行操作,而不是调用 System.Net.WebRequest
:
$statusCode = wget http://***.com/questions/20259251/ | % $_.StatusCode
【讨论】:
可能值得强调的是wget
是 Invoke-WebRequest
的别名(curl
和 iwr
也是如此),我发现值得学习本地名称以防您需要 Google东西。
继续 Ray 的评论,我也不妨指出 %
是 ForEach-Object
的别名。字符$
指定一个变量。 _
,当跟随$
时,是$PSItem
的别名;这是一个自动变量 (man about_Automatic_Variables
),它包含管道对象中的当前对象。这将我们带到“管道”|
(man about_Pipelines
) 并允许将上一个命令的输出用作下一个命令的输入。所以完整的翻译是$variable = Invoke-WebRequest http://***.com/questions/20259251/ | ForEach-Object $PSItem.StatusCode
最后,.
是检索对象属性 (man about_Properties
) 的快捷方式。所以实际的完整翻译是$variable = Invoke-WebRequest $url | ForEach-Object $PSItem | Select-Object -Property StatusCode
这实际上是下载文件非常糟糕。
另见此帖:petri.com/testing-uris-urls-powershell 建议使用以下命令:invoke-webrequest http://***.com/questions/20259251/ -DisableKeepAlive -UseBasicParsing -Method head
【参考方案3】:
你可以试试这个:
function Get-UrlStatusCode([string] $Url)
try
(Invoke-WebRequest -Uri $Url -UseBasicParsing -DisableKeepAlive).StatusCode
catch [Net.WebException]
[int]$_.Exception.Response.StatusCode
$statusCode = Get-UrlStatusCode 'httpstat.us/500'
【讨论】:
添加-Method head
对我来说效果更好,它更快并且避免下载... (Invoke-WebRequest -Uri $Url -UseBasicParsing -DisableKeepAlive -Method head).StatusCode
在这里使用 https://www.petri.com/testing-uris-urls-powershell 和 on SO here
这对我有帮助,但请注意它在 powershell 7 中已损坏,因为抛出的异常与 powershell 5 不同,因此指定它意味着未捕获异常并将返回 0。删除 [Net. WebException] 规范使其适用于 5 和 7【参考方案4】:
$request = [System.Net.WebRequest]::Create('http://***.com/questions/20259251/powershell-script-to-check-the-status-of-a-url')
$response = $request.GetResponse()
$response.StatusCode
$response.Close()
【讨论】:
上述代码中,哪个参数指定链接是否可操作? 定义“可操作”。【参考方案5】:您必须将 Windows PowerShell 更新到最低版本 4.0,以下脚本才能正常工作。
[array]$SiteLinks = "http://mypage.global/Chemical/test.html"
"http://maypage2:9080/portal/site/hotpot/test.json"
foreach($url in $SiteLinks)
try
Write-host "Verifying $url" -ForegroundColor Yellow
$checkConnection = Invoke-WebRequest -Uri $url
if ($checkConnection.StatusCode -eq 200)
Write-Host "Connection Verified!" -ForegroundColor Green
catch [System.Net.WebException]
$exceptionMessage = $Error[0].Exception
if ($exceptionMessage -match "503")
Write-Host "Server Unavaiable" -ForegroundColor Red
elseif ($exceptionMessage -match "404")
Write-Host "Page Not found" -ForegroundColor Red
【讨论】:
【参考方案6】:以下是我用于基本 Web URL 测试的 PowerShell 代码。它包括接受无效证书和获取有关证书检查结果的详细信息的能力。
$CertificateValidatorClass = @'
using System;
using System.Collections.Concurrent;
using System.Net;
using System.Security.Cryptography;
using System.Text;
namespace CertificateValidation
public class CertificateValidationResult
public string Subject get; internal set;
public string Thumbprint get; internal set;
public DateTime Expiration get; internal set;
public DateTime ValidationTime get; internal set;
public bool IsValid get; internal set;
public bool Accepted get; internal set;
public string Message get; internal set;
public CertificateValidationResult()
ValidationTime = DateTime.UtcNow;
public static class CertificateValidator
private static ConcurrentStack<CertificateValidationResult> certificateValidationResults = new ConcurrentStack<CertificateValidationResult>();
public static CertificateValidationResult[] CertificateValidationResults
get
return certificateValidationResults.ToArray();
public static CertificateValidationResult LastCertificateValidationResult
get
CertificateValidationResult lastCertificateValidationResult = null;
certificateValidationResults.TryPeek(out lastCertificateValidationResult);
return lastCertificateValidationResult;
public static bool ServicePointManager_ServerCertificateValidationCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
StringBuilder certificateValidationMessage = new StringBuilder();
bool allowCertificate = true;
if (sslPolicyErrors != System.Net.Security.SslPolicyErrors.None)
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch) == System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch)
certificateValidationMessage.AppendFormat("The remote certificate name does not match.\r\n", certificate.Subject);
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) == System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors)
certificateValidationMessage.AppendLine("The certificate chain has the following errors:");
foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus chainStatus in chain.ChainStatus)
certificateValidationMessage.AppendFormat("\t0", chainStatus.StatusInformation);
if (chainStatus.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.Revoked)
allowCertificate = false;
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateNotAvailable) == System.Net.Security.SslPolicyErrors.RemoteCertificateNotAvailable)
certificateValidationMessage.AppendLine("The remote certificate was not available.");
allowCertificate = false;
System.Console.WriteLine();
else
certificateValidationMessage.AppendLine("The remote certificate is valid.");
CertificateValidationResult certificateValidationResult = new CertificateValidationResult
Subject = certificate.Subject,
Thumbprint = certificate.GetCertHashString(),
Expiration = DateTime.Parse(certificate.GetExpirationDateString()),
IsValid = (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None),
Accepted = allowCertificate,
Message = certificateValidationMessage.ToString()
;
certificateValidationResults.Push(certificateValidationResult);
return allowCertificate;
public static void SetDebugCertificateValidation()
ServicePointManager.ServerCertificateValidationCallback = ServicePointManager_ServerCertificateValidationCallback;
public static void SetDefaultCertificateValidation()
ServicePointManager.ServerCertificateValidationCallback = null;
public static void ClearCertificateValidationResults()
certificateValidationResults.Clear();
'@
function Set-CertificateValidationMode
<#
.SYNOPSIS
Sets the certificate validation mode.
.DESCRIPTION
Set the certificate validation mode to one of three modes with the following behaviors:
Default -- Performs the .NET default validation of certificates. Certificates are not checked for revocation and will be rejected if invalid.
CheckRevocationList -- Cerftificate Revocation Lists are checked and certificate will be rejected if revoked or invalid.
Debug -- Certificate Revocation Lists are checked and revocation will result in rejection. Invalid certificates will be accepted. Certificate validation
information is logged and can be retrieved from the certificate handler.
.EXAMPLE
Set-CertificateValidationMode Debug
.PARAMETER Mode
The mode for certificate validation.
#>
[CmdletBinding(SupportsShouldProcess = $false)]
param
(
[Parameter()]
[ValidateSet('Default', 'CheckRevocationList', 'Debug')]
[string] $Mode
)
begin
$isValidatorClassLoaded = (([System.AppDomain]::CurrentDomain.GetAssemblies() | ? $_.GlobalAssemblyCache -eq $false ) | ? $_.DefinedTypes.FullName -contains 'CertificateValidation.CertificateValidator' ) -ne $null
if ($isValidatorClassLoaded -eq $false)
Add-Type -TypeDefinition $CertificateValidatorClass
process
switch ($Mode)
'Debug'
[System.Net.ServicePointManager]::CheckCertificateRevocationList = $true
[CertificateValidation.CertificateValidator]::SetDebugCertificateValidation()
'CheckRevocationList'
[System.Net.ServicePointManager]::CheckCertificateRevocationList = $true
[CertificateValidation.CertificateValidator]::SetDefaultCertificateValidation()
'Default'
[System.Net.ServicePointManager]::CheckCertificateRevocationList = $false
[CertificateValidation.CertificateValidator]::SetDefaultCertificateValidation()
function Clear-CertificateValidationResults
<#
.SYNOPSIS
Clears the collection of certificate validation results.
.DESCRIPTION
Clears the collection of certificate validation results.
.EXAMPLE
Get-CertificateValidationResults
#>
[CmdletBinding(SupportsShouldProcess = $false)]
param()
begin
$isValidatorClassLoaded = (([System.AppDomain]::CurrentDomain.GetAssemblies() | ? $_.GlobalAssemblyCache -eq $false ) | ? $_.DefinedTypes.FullName -contains 'CertificateValidation.CertificateValidator' ) -ne $null
if ($isValidatorClassLoaded -eq $false)
Add-Type -TypeDefinition $CertificateValidatorClass
process
[CertificateValidation.CertificateValidator]::ClearCertificateValidationResults()
Sleep -Milliseconds 20
function Get-CertificateValidationResults
<#
.SYNOPSIS
Gets the certificate validation results for all operations performed in the PowerShell session since the Debug cerificate validation mode was enabled.
.DESCRIPTION
Gets the certificate validation results for all operations performed in the PowerShell session since the Debug certificate validation mode was enabled in reverse chronological order.
.EXAMPLE
Get-CertificateValidationResults
#>
[CmdletBinding(SupportsShouldProcess = $false)]
param()
begin
$isValidatorClassLoaded = (([System.AppDomain]::CurrentDomain.GetAssemblies() | ? $_.GlobalAssemblyCache -eq $false ) | ? $_.DefinedTypes.FullName -contains 'CertificateValidation.CertificateValidator' ) -ne $null
if ($isValidatorClassLoaded -eq $false)
Add-Type -TypeDefinition $CertificateValidatorClass
process
return [CertificateValidation.CertificateValidator]::CertificateValidationResults
function Test-WebUrl
<#
.SYNOPSIS
Tests and reports information about the provided web URL.
.DESCRIPTION
Tests a web URL and reports the time taken to get and process the request and response, the HTTP status, and the error message if an error occurred.
.EXAMPLE
Test-WebUrl 'http://websitetotest.com/'
.EXAMPLE
'https://websitetotest.com/' | Test-WebUrl
.PARAMETER HostName
The Hostname to add to the back connection hostnames list.
.PARAMETER UseDefaultCredentials
If present the default Windows credential will be used to attempt to authenticate to the URL; otherwise, no credentials will be presented.
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[Uri] $Url,
[Parameter()]
[Microsoft.PowerShell.Commands.WebRequestMethod] $Method = 'Get',
[Parameter()]
[switch] $UseDefaultCredentials
)
process
[bool] $succeeded = $false
[string] $statusCode = $null
[string] $statusDescription = $null
[string] $message = $null
[int] $bytesReceived = 0
[Timespan] $timeTaken = [Timespan]::Zero
$timeTaken = Measure-Command `
try
[Microsoft.PowerShell.Commands.HtmlWebResponseObject] $response = Invoke-WebRequest -UseDefaultCredentials:$UseDefaultCredentials -Method $Method -Uri $Url
$succeeded = $true
$statusCode = $response.StatusCode.ToString('D')
$statusDescription = $response.StatusDescription
$bytesReceived = $response.RawContent.Length
Write-Verbose "$($Url.ToString()): $($statusCode) $($statusDescription) $($message)"
catch [System.Net.WebException]
$message = $Error[0].Exception.Message
[System.Net.HttpWebResponse] $exceptionResponse = $Error[0].Exception.GetBaseException().Response
if ($exceptionResponse -ne $null)
$statusCode = $exceptionResponse.StatusCode.ToString('D')
$statusDescription = $exceptionResponse.StatusDescription
$bytesReceived = $exceptionResponse.ContentLength
if ($statusCode -in '401', '403', '404')
$succeeded = $true
else
Write-Warning "$($Url.ToString()): $($message)"
return [PSCustomObject] @ Url = $Url; Succeeded = $succeeded; BytesReceived = $bytesReceived; TimeTaken = $timeTaken.TotalMilliseconds; StatusCode = $statusCode; StatusDescription = $statusDescription; Message = $message;
Set-CertificateValidationMode Debug
Clear-CertificateValidationResults
Write-Host 'Testing web sites:'
'https://expired.badssl.com/', 'https://wrong.host.badssl.com/', 'https://self-signed.badssl.com/', 'https://untrusted-root.badssl.com/', 'https://revoked.badssl.com/', 'https://pinning-test.badssl.com/', 'https://sha1-intermediate.badssl.com/' | Test-WebUrl | ft -AutoSize
Write-Host 'Certificate validation results (most recent first):'
Get-CertificateValidationResults | ft -AutoSize
【讨论】:
【参考方案7】:对于 powershell (7) 核心,这是有效的:
curl -I gourav.io
输出:
HTTP/1.1 308 Permanent Redirect
Date: Tue, 13 Apr 2021 20:29:43 GMT
Content-Type: text/plain
Connection: keep-alive
Location: https://gourav.io/
Refresh: 0;url=https://gourav.io/
server: Vercel
x-vercel-id: bom1::zfh9m-1618345783130-62d01e38e332
或
Invoke-WebRequest https://gourav.io
输出:
StatusCode : 200
StatusDescription : OK
Content : <!DOCTYPE html><html lang="en-US"><head><script async=""
src="https://www.googletagmanager.com/gtag/js?id=G-JF3BSQ1LL2"></script><script>
window.dataLayer = window.dataLayer || [];
…
RawContent : HTTP/1.1 200 OK
...
...
【讨论】:
【参考方案8】:我使用它并且工作,(如果链接可用,则返回“Ok”)但如果链接不工作,它会显示错误的红色字母。如何删除此 sn-p 上的错误报告?
$DownloadLink = "https://www.tightvnc.com/download/2.8.59/tightvnc-2.8.59-gpl-setup-bit.msi"
$NetAvailable = (Invoke-WebRequest -Uri $DownloadLink -UseBasicParsing -DisableKeepAlive -Method Head).StatusDescription
$NetAvailable = OK
If ($NetAvailable -eq "OK") Write-Host "Attempting Download";wget -O "$Destination\$FileName" "$DownloadLink"
Else "";Write-Warning "Could NOT Download, Manually Copy $ProgramName to $Destination BEFORE Proceeding!";"";PAUSE
但是如果链接不起作用会给我一个错误,然后转到“Else” 它有效,我只想摆脱错误字母。
【讨论】:
如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review以上是关于用于检查 URL 状态的 PowerShell 脚本的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Powershell 中自动执行 Telnet 端口检查?
powershell 用于检查更新的Powershell脚本
powershell 检查SharePoint管理中心Web应用程序池状态