Windows 服务器巡检

本文详细介绍如何利用 PowerShell 采集 Windows 环境、资源使用率、服务进程、event日志、安全配置等信息,以便作为巡检报告或健康诊断的参考依据。

巡检脚本

  • 由于篇幅问题,本文仅展示 scripts 目录下的部分指标脚本,更多请 联系我们

wins_check.ps1

  • 主巡检文件:wins_check.ps1

注1:请根据需要调整参数:$portList(需要监控的端口清单)、$serviceList(需要监控的服务清单)

注2:如下脚本已兼容测试:Windows 10/2012+、PowerShell 4.0+

# Windows巡检,支持 Windows 10/2012+
$host.ui.RawUI.WindowTitle = "Windows巡检.v20260425.余"

# 加载所有脚本
$modulePath = Join-Path $PSScriptRoot "scripts"
Get-ChildItem "$modulePath/*.ps1" -Recurse | ForEach-Object { . $_.FullName }

# 创建日志目录
$localpath = ".\logs"
$localip = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.InterfaceAlias -notlike 'Loopback*' -and $_.InterfaceAlias -notlike '*vEthernet*'}).IPAddress | Select-Object -First 1
if (-not $localip) { $localip = "127.0.0.1" }
$logDir = "$localpath\$localip"
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory $logDir -Force | Out-Null }

# 配置检查清单
$portList = @(80,443,1433,3389,10000)
$serviceList = @("W32Time","wuauserv","BITS","EventLog","WinDefend","W3SVC","MSSQLSERVER","SQLSERVERAGENT","OSearch16","SPSearchHostController","SPAdminV4","SPTimerV4","SPTraceV4","WACSM")

# 导出CSV格式
function Export-CheckData {
    param($Data, $Path)
    if ($Data) { $Data | Export-Csv $Path -Encoding UTF8 -NoTypeInformation -Force }
}

# 巡检开始
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "  主机: $env:COMPUTERNAME ($localip)" -ForegroundColor Cyan
Write-Host "  时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan

Write-Host "[01/12] 开始采集 System 信息..." -ForegroundColor Green
Export-CheckData (Get-SystemInfo) (Join-Path $logDir "1.system_info.csv")

Write-Host "[02/12] 开始采集 CPU 信息..." -ForegroundColor Green
Export-CheckData (Get-CPUInfo) (Join-Path $logDir "2.cpu_info.csv")

Write-Host "[03/12] 开始采集 Disk 信息..." -ForegroundColor Green
Export-CheckData (Get-DiskInfo) (Join-Path $logDir "3.disk_info.csv")

Write-Host "[04/12] 开始采集 Network 信息..." -ForegroundColor Green
#Export-CheckData (Get-NetworkInfo) (Join-Path $logDir "4.network_info.csv")

Write-Host "[05/12] 开始采集 Windows 日志..." -ForegroundColor Green
Export-CheckData (Get-LogWindowsEvents) (Join-Path $logDir "5.log_windows_events.csv")

Write-Host "[06/12] 开始采集 服务 状态..." -ForegroundColor Green
Export-CheckData (Get-ServiceInfo -ServiceNames $serviceList) (Join-Path $logDir "6.service_info.csv")

Write-Host "[07/12] 开始采集 端口连接 信息..." -ForegroundColor Green
#Export-CheckData (Get-PortConnection -Ports $portList) (Join-Path $logDir "7.port_connection.csv")

Write-Host "[08/12] 开始采集 进程 信息..." -ForegroundColor Green
#Export-CheckData (Get-TopProcesses) (Join-Path $logDir "8.top_processes.csv")

Write-Host "[09/12] 开始采集 软件 信息..." -ForegroundColor Green
#Export-CheckData (Get-InstalledProducts) (Join-Path $logDir "9.install_products.csv")

Write-Host "[10/12] 开始采集 安全 信息..." -ForegroundColor Green
#Export-CheckData (Get-SecurityInfo) (Join-Path $logDir "10.security_info.csv")

Write-Host "[11/12] 开始采集 HotFix 日志..." -ForegroundColor Green
#Export-CheckData (Get-HotFixInfo) (Join-Path $logDir "11.hot_fix.csv")

Write-Host "[12/12] 开始采集 https 页面信息..." -ForegroundColor Green
#Export-CheckData (Get-HttpURLInfo) (Join-Path $logDir "12.http_url_info.csv")
#Export-CheckData (Get-HttpsURLInfo) (Join-Path $logDir "13.https_url_info.csv")

Start-Sleep -Seconds 5

Write-Host "========================================" -ForegroundColor Cyan
Write-Host "巡检执行完毕!`n" -ForegroundColor Green

scripts\SystemInfo.ps1

  • 采集 System 信息的脚本:scripts\SystemInfo.ps1
function Get-SystemInfo {
    try {
        $os = Get-WmiObject -Class Win32_OperatingSystem -ErrorAction Stop
        $build = (Get-ItemProperty "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion").CurrentBuild
        $ubr = (Get-ItemProperty "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion").UBR
        $winver = "$build.$ubr"
        $sysinfo = Get-WmiObject win32_computersystem
        $timezone = ((Get-WmiObject -Class win32_timezone).Caption -split '[()]')[1]
        $bios = Get-WmiObject -Class win32_bios
        $original = Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name 'portnumber'
        $latestUpdate = Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 1

        return [PSCustomObject]@{
            HostName            = $sysinfo.DNSHostName
            Domain                = $sysinfo.Domain
            OperatingSystem        = $os.Caption.Replace("Microsoft ","")
            Arch                = $os.OSArchitecture
            WinVersion            = $os.version
            UBRevision            = $winver
            InstallDate            = $os.ConvertToDateTime($os.InstallDate)
            LastUpdate            = $latestUpdate.InstalledOn
            LastUpdateKB        = $latestUpdate.HotFixID
            LastBootUp            = $os.ConvertToDateTime($os.LastBootUpTime)
            UpDays                = ((Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime).Days
            TimeZone            = $timezone
            SystemType            = $sysinfo.SystemType
            Manufacturer        = $bios.Manufacturer
            Model                = $sysinfo.Model
            BIOSName            = $bios.Name
            SerialNumber        = $bios.SerialNumber
            RDPPort                = $original.PortNumber
            PSVersion            = $PSVersionTable.PSVersion
        }
    }
    catch {
        Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
        return @()
    }
}

scripts\CPUInfo.ps1

  • 采集 CPU 信息的脚本:scripts\CPUInfo.ps1
function Get-CPUInfo {
    try {
        $cpu = Get-WmiObject -Class Win32_Processor -ErrorAction Stop | Select-Object -First 1
        $cpuCount = Get-CimInstance -ClassName Win32_Processor | Measure-Object | Select-Object -ExpandProperty Count
        $numOfCore = (Get-WmiObject -Class Win32_Processor).NumberOfCores
        $coreCount = (Get-CimInstance -ClassName Win32_Processor).NumberOfLogicalProcessors | Measure-Object -Sum | Select-Object -ExpandProperty Sum
        $memory = Get-WmiObject -Class Win32_ComputerSystem -ErrorAction Stop
        $totalMemGB = [math]::Round($memory.TotalPhysicalMemory / 1GB, 2)
        $os = Get-WmiObject -Class Win32_OperatingSystem -ErrorAction Stop
        $freeMemGB = [math]::Round($os.FreePhysicalMemory / 1MB, 2)
        $usedMemGB = [math]::Round($totalMemGB - $freeMemGB, 2)

        # 2次采集间隔5秒,避免瞬时指标不准确
        $cpuAvg1 = (Get-Counter -Counter "\Processor(_Total)\% Processor Time").CounterSamples[0].CookedValue
        Start-Sleep -Seconds 3
        $cpuAvg2 = (Get-Counter -Counter "\Processor(_Total)\% Processor Time").CounterSamples[0].CookedValue
        $cpuAvg = [math]::Round(($cpuAvg1 + $cpuAvg2) / 2, 2)

        $DiskQueue = Get-Counter -Counter "\PhysicalDisk(_Total)\Current Disk Queue Length" -ErrorAction Stop
        $DiskQueueLength = [math]::Round($DiskQueue.CounterSamples.CookedValue, 2)

        return [PSCustomObject]@{
            CPU                = $cpu.Name
            Counts            = $cpuCount
            LogicalCores    = $coreCount
            CPU_Usage_Pct    = $cpuAvg
            Mem_Total_GB    = $totalMemGB
            Mem_Used_GB        = $usedMemGB
            Mem_Free_GB        = $freeMemGB
            Mem_Usage_Pct    = [math]::Round(($usedMemGB / $totalMemGB) * 100, 2)
            DiskQueueLength    = $DiskQueueLength
        }
    }
    catch {
        Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
        return @()
    }
}

scripts\DiskInfo.ps1

  • 采集 Disk 信息的脚本:scripts\DiskInfo.ps1
function Get-DiskInfo {
    try {
        $disks = Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" -ErrorAction Stop

        return $disks | ForEach-Object {
            [PSCustomObject]@{
                DriveID   = $_.DeviceID
                DriveType = $_.FileSystem
                Total_GB  = [math]::Round($_.Size / 1GB, 2)
                Used_GB   = [math]::Round(($_.Size - $_.FreeSpace) / 1GB, 2)
                Free_GB   = [math]::Round($_.FreeSpace / 1GB, 2)
                Usage_Pct = [math]::Round((($_.Size - $_.FreeSpace) / $_.Size) * 100, 2)
            }
        }
    }
    catch {
        Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
        return @()
    }
}

scripts\LogWindowsEvents.ps1

  • 采集 event事件日志 信息的脚本:scripts\LogWindowsEvents.ps1
function Get-LogWindowsEvents {
    $endTime = Get-Date
    $startTime = $endTime.AddDays(-7)        #.最近7天

    # 1.处理 Application 和 System 日志
    $logNames = "Application", "System"
    $result = [PSCustomObject]@{
        login_succ_count = 0
        login_fail_count = 0
        login_cred_count = 0
        login_spec_count = 0
        app_warn_count = 0
        app_errr_count = 0
        sys_warn_count = 0
        sys_errr_count = 0
        tot_warn_count = 0
        tot_errr_count = 0
        check_time = $endTime
    }

    foreach ($logName in $logNames) {
        try {
            # PowerShell 4.0 兼容方式:使用 Get-WinEvent
            $events = Get-WinEvent -LogName $logName -ErrorAction Stop | Where-Object {
                $_.TimeCreated -ge $startTime -and $_.TimeCreated -le $endTime
            }

            foreach ($event in $events) {
                # Windows 标准级别:2=错误, 3=警告
                $level = $event.Level
                if ($level -eq 2) {
                    if ($logName -eq "Application") { $result.app_errr_count++ }
                    if ($logName -eq "System")      { $result.sys_errr_count++ }
                }
                elseif ($level -eq 3) {
                    if ($logName -eq "Application") { $result.app_warn_count++ }
                    if ($logName -eq "System")      { $result.sys_warn_count++ }
                }
            }
        }
        catch {
            Write-Host "Error reading $logName : $($_.Exception.Message)" -ForegroundColor Red
            return @()
        }
    }

    $result.tot_errr_count = $result.app_errr_count + $result.sys_errr_count
    $result.tot_warn_count = $result.app_warn_count + $result.sys_warn_count

    # 2.处理 Security 日志, 4624/4625/4648/4672 对应 登录成功/登录失败/使用显式凭据登录/特殊权限登录
    try {
        $targetEventIds = 4624, 4625, 4648, 4672
        $events = Get-WinEvent -FilterHashtable @{
            LogName   = "Security"
            Id        = $targetEventIds
            StartTime = $startTime
            EndTime   = $endTime
        } -ErrorAction SilentlyContinue

        if ($events) {
            foreach ($event in $events) {
                switch ($event.Id) {
                    4624 { $result.login_succ_count++ }
                    4625 { $result.login_fail_count++ }
                    4648 { $result.login_cred_count++ }
                    4672 { $result.login_spec_count++ }
                }
            }
        }
    }
    catch {
        Write-Host "Error reading Security log: $($_.Exception.Message)" -ForegroundColor Red
    }

    return $result
}

scripts\ServiceInfo.ps1

  • 采集 Service 信息的脚本:scripts\ServiceInfo.ps1
function Get-ServiceInfo {
    param([string[]]$ServiceNames)

    try {
        $result = @()
        foreach ($svcName in $ServiceNames) {
            $svc = Get-Service -Name $svcName -ErrorAction SilentlyContinue
            if ($svc) {
                $result += [PSCustomObject]@{
                    ServiceName = $svc.Name
                    DisplayName = $svc.DisplayName
                    Status      = $svc.Status
                    StartType   = $svc.StartType
                }
            }
        }
        return $result
    }
    catch {
        Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
        return @()
    }
}

如何使用

  • 第1步,目录结构参考如下:
C:\Windows\System32>cd /d c:\windows_check

c:\windows_check>tree /F
文件夹 PATH 列表
卷序列号为 3E68-D7B4
C:.
│  wins_check.ps1                   #.主巡检文件
│
└─ scripts
        CPUInfo.ps1                 #.采集 CPU 信息
        DiskInfo.ps1                #.采集 Disk 信息
        HotFixInfo.ps1              #.采集 HotFix 信息
        HttpsURLInfo.ps1            #.采集 https域名 信息
        HttpURLInfo.ps1             #.采集 http域名 信息
        InstalledProducts.ps1       #.采集 软件 信息
        LogWindowsEvents.ps1        #.采集 Windows日志 信息
        NetworkInfo.ps1             #.采集 Network 信息
        PortConnection.ps1          #.采集 端口连接 信息
        SecurityInfo.ps1            #.采集 安全 信息
        ServiceInfo.ps1             #.采集 服务 信息
        SystemInfo.ps1              #.采集 System 信息
        TopProcesses.ps1            #.采集 进程 信息
  • 第2步,以管理员身份运行 PowerShell,然后输入 .\wins_check.ps1 即可(会自动创建 logs 存放采集到的日志文件),过程如下:

  • 第3步,由于日志文件为 csv 格式,所以可以直接用 excel 打开,效果如下:

Copyright © www.sqlfans.cn 2021 - 2026 All Right Reserved更新时间: 2026-07-27 11:33:47

results matching ""

    No results matching ""