用于检查 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

【讨论】:

可能值得强调的是 wgetInvoke-WebRequest 的别名(curliwr 也是如此),我发现值得学习本地名称以防您需要 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脚本

用于运行Python脚本的Powershell脚本

powershell 检查SharePoint管理中心Web应用程序池状态

用于检查 Active Directory 用户是不是上次登录的 Powershell 脚本

使用 Azure AZ Powershell Cmdlet 列出 Azure 安全中心策略状态