Загрузка данных


$Server = "RUKLGDC01.pcmarus.loc"
$Stamp  = Get-Date -Format "yyyyMMdd_HHmmss"

$RemoteScriptLocal = "C:\Windows\Temp\DHCP_Audit_$Stamp.ps1"
$RemoteOutLocal    = "C:\Windows\Temp\DHCP_Audit_$Stamp.txt"
$RemoteDoneLocal   = "C:\Windows\Temp\DHCP_Audit_$Stamp.done"

$RemoteScriptUNC = "\\$Server\C$\Windows\Temp\DHCP_Audit_$Stamp.ps1"
$RemoteOutUNC    = "\\$Server\C$\Windows\Temp\DHCP_Audit_$Stamp.txt"
$RemoteDoneUNC   = "\\$Server\C$\Windows\Temp\DHCP_Audit_$Stamp.done"

$ScriptBody = @'
$ErrorActionPreference = "Continue"

& {
    Write-Output "============================================================"
    Write-Output " DHCP SERVER AUDIT"
    Write-Output "============================================================"
    Write-Output "Server: $env:COMPUTERNAME"
    Write-Output "Date:   $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"

    Write-Output "`n=== DHCP MODULE ==="
    Import-Module DhcpServer -ErrorAction Stop
    Get-Module DhcpServer |
        Select-Object Name,Version,Path |
        Format-List

    Write-Output "`n=== DHCP SERVICE ==="
    Get-Service DHCPServer |
        Select-Object Name,Status,StartType |
        Format-List

    Write-Output "`n=== DHCP BINDINGS ==="
    Get-DhcpServerv4Binding |
        Format-Table InterfaceAlias,IPAddress,BindingState -AutoSize

    Write-Output "`n=== DHCP SCOPES ==="
    $Scopes = Get-DhcpServerv4Scope

    $Scopes |
        Format-Table ScopeId,Name,State,StartRange,EndRange,SubnetMask,LeaseDuration -AutoSize

    Write-Output "`n=== SCOPE STATISTICS ==="
    $Statistics = foreach ($Scope in $Scopes) {
        Get-DhcpServerv4ScopeStatistics -ScopeId $Scope.ScopeId
    }

    $Statistics |
        Format-Table ScopeId,PercentageInUse,InUse,Free,Reserved,Pending -AutoSize

    Write-Output "`n=== SCOPES WITH UTILIZATION 85% OR MORE ==="
    $HighUsage = $Statistics |
        Where-Object {
            $_.PercentageInUse -ge 85
        }

    if ($HighUsage) {
        $HighUsage |
            Format-Table ScopeId,PercentageInUse,InUse,Free,Reserved,Pending -AutoSize
    }
    else {
        Write-Output "Scopes with utilization >= 85% were not found."
    }

    Write-Output "`n=== EXCLUSION RANGES ==="
    foreach ($Scope in $Scopes) {
        Write-Output "`nScope: $($Scope.ScopeId) / $($Scope.Name)"

        $Exclusions = Get-DhcpServerv4ExclusionRange `
            -ScopeId $Scope.ScopeId `
            -ErrorAction SilentlyContinue

        if ($Exclusions) {
            $Exclusions |
                Format-Table ScopeId,StartRange,EndRange -AutoSize
        }
        else {
            Write-Output "No exclusions configured."
        }
    }

    Write-Output "`n=== DHCP OPTIONS PER SCOPE ==="
    foreach ($Scope in $Scopes) {
        Write-Output "`nScope: $($Scope.ScopeId) / $($Scope.Name)"

        Get-DhcpServerv4OptionValue `
            -ScopeId $Scope.ScopeId `
            -ErrorAction SilentlyContinue |
        Format-Table OptionId,Name,Value -AutoSize
    }

    Write-Output "`n=== SERVER-LEVEL DHCP OPTIONS ==="
    Get-DhcpServerv4OptionValue -ErrorAction SilentlyContinue |
        Format-Table OptionId,Name,Value -AutoSize

    Write-Output "`n=== DHCP FAILOVER ==="
    $Failover = Get-DhcpServerv4Failover -ErrorAction SilentlyContinue

    if ($Failover) {
        $Failover |
            Format-List Name,PartnerServer,Mode,State,ServerRole,ScopeId
    }
    else {
        Write-Output "DHCP Failover is not configured."
    }

    Write-Output "`n=== DHCP SERVER SETTINGS ==="
    Get-DhcpServerv4Setting -ErrorAction SilentlyContinue |
        Format-List *

    Write-Output "`n=== DHCP AUDIT SETTINGS ==="
    Get-DhcpServerAuditLog -ErrorAction SilentlyContinue |
        Format-List *

    Write-Output "`n=== DHCP DATABASE SETTINGS ==="
    Get-DhcpServerDatabase -ErrorAction SilentlyContinue |
        Format-List *

    Write-Output "`n=== DHCP AUTHORIZATION IN ACTIVE DIRECTORY ==="
    Get-DhcpServerInDC -ErrorAction SilentlyContinue |
        Format-Table DnsName,IPAddress -AutoSize

    Write-Output "`n=== DISK C: ==="
    Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'" |
        Select-Object DeviceID,
            @{Name="SizeGB";Expression={[math]::Round($_.Size / 1GB,2)}},
            @{Name="FreeGB";Expression={[math]::Round($_.FreeSpace / 1GB,2)}},
            @{Name="FreePercent";Expression={[math]::Round(($_.FreeSpace / $_.Size) * 100,2)}} |
        Format-Table -AutoSize

    Write-Output "`n=== DHCP ERRORS AND WARNINGS FOR LAST 3 DAYS ==="
    $StartTime = (Get-Date).AddDays(-3)

    $DhcpLogs = Get-WinEvent -ListLog "*DHCP*" -ErrorAction SilentlyContinue |
        Where-Object {
            $_.IsEnabled -and $_.RecordCount -gt 0
        }

    foreach ($Log in $DhcpLogs) {
        Write-Output "`nLog: $($Log.LogName)"

        $Events = Get-WinEvent -FilterHashtable @{
            LogName   = $Log.LogName
            StartTime = $StartTime
        } -ErrorAction SilentlyContinue |
        Where-Object {
            $_.Level -in 1,2,3
        } |
        Select-Object -First 50 TimeCreated,Id,LevelDisplayName,Message

        if ($Events) {
            $Events | Format-List
        }
        else {
            Write-Output "No errors or warnings found."
        }
    }

    Write-Output "`n=== LATEST DHCP AUDIT LOG ==="
    $LatestAuditLog = Get-ChildItem `
        "C:\Windows\System32\dhcp\DhcpSrvLog-*.log" `
        -ErrorAction SilentlyContinue |
        Sort-Object LastWriteTime -Descending |
        Select-Object -First 1

    if ($LatestAuditLog) {
        Write-Output "File: $($LatestAuditLog.FullName)"
        Write-Output "Modified: $($LatestAuditLog.LastWriteTime)"
        Get-Content $LatestAuditLog.FullName -Tail 100
    }
    else {
        Write-Output "DHCP audit log files were not found."
    }

} 2>&1 |
    Out-String -Width 400 |
    Set-Content -LiteralPath "__OUT__" -Encoding UTF8

New-Item -ItemType File -Path "__DONE__" -Force | Out-Null
'@

$ScriptBody = $ScriptBody.Replace("__OUT__", $RemoteOutLocal)
$ScriptBody = $ScriptBody.Replace("__DONE__", $RemoteDoneLocal)

try {
    Write-Host "Копирование диагностического скрипта..." -ForegroundColor Cyan

    Set-Content `
        -LiteralPath $RemoteScriptUNC `
        -Value $ScriptBody `
        -Encoding UTF8 `
        -Force

    $CommandLine = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File `"$RemoteScriptLocal`""

    Write-Host "Запуск диагностики на $Server..." -ForegroundColor Cyan

    $ProcessClass = [wmiclass]"\\$Server\root\cimv2:Win32_Process"
    $CreateResult = $ProcessClass.Create($CommandLine)

    if ($CreateResult.ReturnValue -ne 0) {
        throw "Не удалось запустить процесс. WMI ReturnValue: $($CreateResult.ReturnValue)"
    }

    Write-Host "Процесс запущен. PID: $($CreateResult.ProcessId)" -ForegroundColor Green

    $Deadline = (Get-Date).AddMinutes(3)

    while (
        -not (Test-Path $RemoteDoneUNC) -and
        (Get-Date) -lt $Deadline
    ) {
        Start-Sleep -Seconds 2
    }

    if (-not (Test-Path $RemoteDoneUNC)) {
        throw "Диагностика не завершилась за 3 минуты."
    }

    Write-Host "`n=== РЕЗУЛЬТАТ ДИАГНОСТИКИ ===`n" -ForegroundColor Green

    Get-Content $RemoteOutUNC
}
catch {
    Write-Host "Ошибка: $($_.Exception.Message)" -ForegroundColor Red
}
finally {
    Remove-Item $RemoteScriptUNC -Force -ErrorAction SilentlyContinue
    Remove-Item $RemoteDoneUNC   -Force -ErrorAction SilentlyContinue
    Remove-Item $RemoteOutUNC    -Force -ErrorAction SilentlyContinue
}