You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell服务器巡检脚本遇无响应服务器挂起问题求助

解决PowerShell巡检脚本遇无响应服务器挂起的问题

你的PowerShell服务器巡检脚本在遇到无响应/冻结的服务器时会挂起,无法继续执行。需要实现超时机制跳过故障服务器,或者通过预Ping过滤不可达机器,同时希望保持脚本简洁,对-AsJob的使用有困惑。


核心解决方案

1. 预Ping过滤无响应服务器

在执行巡检前先对目标服务器做快速Ping测试,只保留能响应的机器,直接过滤掉完全不可达的服务器,减少后续卡住的概率:

# 预Ping测试,只保留能响应的Windows服务器
$reachableWinServers = $winservers | Where-Object {
    Test-Connection -ComputerName $_ -Count 1 -Quiet -ErrorAction SilentlyContinue
}

2. 给Invoke-Command设置超时

无需使用复杂的-AsJob,直接用Invoke-Command自带的-TimeoutSec参数指定超时时间(比如30秒),到时间后自动终止对该服务器的执行并继续下一台:

Invoke-Command -ComputerName $reachableWinServers -ScriptBlock $scriptblock -HideComputerName -ErrorAction SilentlyContinue -TimeoutSec 30

修正后的完整脚本

同时修复了原脚本中的语法错误(如未闭合的引号、未定义的变量),优化了输出格式:

Import-Module ActiveDirectory

# 修正引号闭合问题,筛选AD中的服务器
$allservers = Get-ADComputer -Filter * -SearchBase "xxxxx" -Properties OperatingSystem | 
    Where-Object {
        $_.DistinguishedName -NotLike '*OU=NEC*' -and $_.DistinguishedName -NotLike '*OU=GPO_Testing*'
    }

$winservers = ($allservers | Where-Object {$_.OperatingSystem -like "Windows Server*"}).Name
$notwinservers = $allservers | Where-Object {$_.OperatingSystem -notlike "Windows Server*"}

# 预Ping过滤可达的Windows服务器
$reachableWinServers = $winservers | Where-Object {
    Test-Connection -ComputerName $_ -Count 1 -Quiet -ErrorAction SilentlyContinue
}

$scriptblock = {
    # 获取服务器名称
    $serverName = $env:COMPUTERNAME

    # 服务器状态(本地测试更准确)
    $status = 'Up'
    try {
        $null = Get-CimInstance -Class Win32_OperatingSystem -ErrorAction Stop
    }
    catch {
        $status = 'Down'
    }

    # 操作系统安装日期
    $buildDate = (Get-CimInstance -Class Win32_OperatingSystem -ErrorAction SilentlyContinue).InstallDate

    # 证书信息处理
    $certs = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { -Not $_.PSIsContainer } | Sort-Object -Property NotBefore
    $certcount = $certs.Count
    $certname = $certs.FriendlyName -join ', '

    # 最后重启时间
    $reboot = (Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction SilentlyContinue).LastBootUpTime

    # Trellix更新时间
    $TrellixDate = try {
        [datetime](Get-ItemProperty 'C:\Program Files\Common Files\McAfee\Engine\AMCoreUpdater\amupdate.dat').LastWriteTime.DateTime
    }
    catch {
        'n/a'
    }

    # 操作系统信息
    $os = (Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue).OperatingSystem

    # 磁盘信息
    $diskInfo = Get-CimInstance -Class Win32_LogicalDisk -Filter 'DriveType = 3' -ErrorAction SilentlyContinue

    # SQL版本(修正原脚本变量错误)
    $sqlver = 'n/a'
    if (Test-Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server' -ErrorAction SilentlyContinue) {
        $sqlInstances = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server').InstalledInstances
        $sqlVersions = foreach ($instance in $sqlInstances) {
            $instancePath = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL').$instance
            (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$instancePath\Setup").Version
        }
        $sqlver = $sqlVersions -join ', '
    }

    # IIS版本
    $IIS = 'n/a'
    if (Get-Service -Name W3SVC -ErrorAction SilentlyContinue) {
        $IIS = (Get-ItemProperty -PATH 'HKLM:\SOFTWARE\Microsoft\InetStp\').VERSIONSTRING
    }

    # 生成输出对象(处理多磁盘/多证书的对应问题)
    for ($i = 0; $i -lt [System.Math]::Max($certs.Count, $diskInfo.Count); $i++) {
        $disk = $diskInfo[$i]
        $cert = $certs[$i]

        [PSCustomObject]@{
            ServerName           = $serverName
            Status               = $status
            OperatingSystem      = $os ?? 'n/a'
            BuildDate            = if ($buildDate) { '{0:u}' -f $buildDate } else { 'n/a' }
            LastReboot           = if ($reboot) { '{0:u}' -f $reboot } else { 'n/a' }
            CertName             = if ($cert) { $cert.FriendlyName } else { 'n/a' }
            CertCreated          = if ($cert) { $cert.NotBefore } else { 'n/a' }
            CertExpiration       = if ($cert) { $cert.NotAfter } else { 'n/a' }
            CertCount            = $certcount
            TrellixLastUpdate    = $TrellixDate
            SQLVersion           = $sqlver
            IISVersion           = $IIS
            DiskLabel            = if ($disk) { $disk.DeviceID } else { 'n/a' }
            Freespace            = if ($disk) { '{0:N2} Gb' -f ($disk.FreeSpace / 1GB) } else { 'n/a' }
            DiskSize             = if ($disk) { '{0:N2} Gb' -f ($disk.Size / 1GB) } else { 'n/a' }
            PercentFree          = if ($disk) { '{0:P0}' -f ($disk.FreeSpace / $disk.Size) } else { 'n/a' }
        }
    }
}

# 执行巡检,设置30秒超时
Invoke-Command -ComputerName $reachableWinServers -ScriptBlock $scriptblock -HideComputerName -ErrorAction SilentlyContinue -TimeoutSec 30 |
    Select-Object * -ExcludeProperty RunspaceId, PSComputerName, PSShowComputerName |
    Export-Csv "e:\activetasks\server_checks\DailyMissionReport_$((Get-Date).ToString('dd-MM-yyyy')).csv" -NoTypeInformation

# 处理非Windows服务器
foreach ($nonwin in $notwinservers) {
    $status = if (Test-Connection -ComputerName $nonwin.Name -Count 1 -Quiet -ErrorAction SilentlyContinue) { 'Up' } else { 'Down' }

    [PSCustomObject]@{
        ServerName           = $nonwin.Name
        Status               = $status 
        OperatingSystem      = "Linux or Other"
        BuildDate            = "n/a"
        LastReboot           = "n/a"
        CertName             = "n/a"
        CertCreated          = "n/a"
        CertExpiration       = "n/a"
        CertCount            = "n/a"
        TrellixLastUpdate    = "n/a"
        SQLVersion           = "n/a"
        IISVersion           = "n/a"
        DiskLabel            = "n/a"
        Freespace            = "n/a"
        DiskSize             = "n/a"
        PercentFree          = "n/a"
    } |
    Export-Csv "e:\activetasks\server_checks\DailyMissionReport_$((Get-Date).ToString('dd-MM-yyyy')).csv" -NoTypeInformation -Append
}

内容的提问来源于stack exchange,提问作者BobSnarley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:58:12