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


```powershell
#requires -version 2.0

<#
.SYNOPSIS
    Проверка отключения / включенности IPv6 на рабочей станции.

.DESCRIPTION
    Скрипт проверяет:
      - Параметр реестра DisabledComponents (системный уровень IPv6)
      - Состояние привязки компонента IPv6 на активных сетевых адаптерах
    
    Формат summary:
        COMPUTER01 - PASS (IPv6 отключен)
        COMPUTER02 - FAIL (IPv6 активен / включен)
#>

# ============================================================
# CONFIGURATION
# ============================================================

# Общая сетевая папка для сохранения отчетов (замените на свой путь)
$ResultDirectory = "\\10.68.16.120\report\ipv6_check"

# Общий файл со сводкой
$SummaryFile = Join-Path$ResultDirectory "summary.txt"

# Имя компьютера
$ComputerName =$env:COMPUTERNAME

# ============================================================
# MARKER CHECK
# ============================================================

# Если отчет уже существует, аудит повторно не запускаем
$ExistingMarker = Get-ChildItem `
    -Path $ResultDirectory `
    -Filter ($ComputerName + "_*.txt") `
    -ErrorAction SilentlyContinue |
    Select-Object -First 1

if ($null -ne $ExistingMarker) {

    Write-Host ""
    Write-Host "============================================================"
    Write-Host "IPV6 COMPLIANCE AUDIT"
    Write-Host "============================================================"
    Write-Host ""
    Write-Host "Computer: $ComputerName"
    Write-Host ""
    Write-Host "Audit already completed."
    Write-Host "Marker file: $($ExistingMarker.FullName)"
    Write-Host ""
    Write-Host "No action required."
    Write-Host "============================================================"

    exit 0
}

# ============================================================
# INITIALIZATION
# ============================================================

$Results = New-Object System.Collections.ArrayList

$FailCount = 0
$WarnCount = 0
$PassCount = 0

# ============================================================
# FUNCTIONS
# ============================================================

function Add-Result {
    param(
        [string]$Status,
        [string]$Name,
        [string]$Details
    )

    $Line = "[{0}] {1}: {2}" -f $Status, $Name, $Details
    [void]$Results.Add($Line)

    switch ($Status) {
        "PASS" { $script:PassCount++ }
        "FAIL" { $script:FailCount++ }
        "WARN" { $script:WarnCount++ }
    }
}

function Add-Section {
    param(
        [string]$Title
    )

    $Separator = "".PadLeft(60, "-")
    [void]$Results.Add("")
    [void]$Results.Add($Separator)
    [void]$Results.Add($Title)
    [void]$Results.Add($Separator)
}

function Get-RegistryValueSafe {
    param(
        [string]$Path,
        [string]$Name
    )

    try {
        $Property = Get-ItemProperty `
            -Path $Path `
            -Name $Name `
            -ErrorAction Stop

        return $Property.$Name
    }
    catch {
        return $null
    }
}

# ============================================================
# SYSTEM INFORMATION
# ============================================================

$OS = Get-WmiObject Win32_OperatingSystem
$ComputerSystem = Get-WmiObject Win32_ComputerSystem$DateTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

$OSCaption =$OS.Caption
$OSVersion =$OS.Version
$OSBuild =$OS.BuildNumber
$Domain =$ComputerSystem.Domain
$CurrentUser = $env:USERDOMAIN + "\" + $env:USERNAME

[void]$Results.Add("============================================================")
[void]$Results.Add("DOMAIN SECURITY AUDIT: IPV6 CONFIGURATION")
[void]$Results.Add("============================================================")
[void]$Results.Add("")
[void]$Results.Add("Computer : $ComputerName")
[void]$Results.Add("Domain   : $Domain")
[void]$Results.Add("OS       : $OSCaption")
[void]$Results.Add("Version  : $OSVersion")
[void]$Results.Add("Build    : $OSBuild")
[void]$Results.Add("User     : $CurrentUser")
[void]$Results.Add("Date     : $DateTime")

# ============================================================
# 1. REGISTRY: DisabledComponents
# ============================================================

Add-Section "1. IPV6 REGISTRY SETTINGS (DisabledComponents)"

$Tcpip6Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
$DisabledComponents = Get-RegistryValueSafe -Path$Tcpip6Path -Name "DisabledComponents"

# 0xff (255) — полное отключение стека IPv6 на всех интерфейсах
if ($null -eq$DisabledComponents) {
    Add-Result `
        -Status "FAIL" `
        -Name "Tcpip6 Parameters" `
        -Details "Параметр DisabledComponents отсутствует. Стек IPv6 активен по умолчанию (Default)."
}
elseif ([int]$DisabledComponents -eq 255 -or [int]$DisabledComponents -eq 0xFF) {
    Add-Result `
        -Status "PASS" `
        -Name "Tcpip6 Parameters" `
        -Details "DisabledComponents = 0xFF (255). Все компоненты IPv6 отключены на уровне ОС."
}
elseif ([int]$DisabledComponents -eq 0) {
    Add-Result `
        -Status "FAIL" `
        -Name "Tcpip6 Parameters" `
        -Details "DisabledComponents = 0. IPv6 полностью включен."
}
else {
    # Промежуточные значения (например, 0x20 предпочтение IPv4, отключение на туннелях и т.д.)
    Add-Result `
        -Status "WARN" `
        -Name "Tcpip6 Parameters" `
        -Details "DisabledComponents = $DisabledComponents. IPv6 частично ограничен, но не отключен полностью."
}

# ============================================================
# 2. NETWORK ADAPTERS BINDING
# ============================================================

Add-Section "2. ADAPTER IPV6 BINDING AUDIT"

# Попытка проверить через NetAdapterBinding (PowerShell 3.0+), 
# с откатом на анализ WMI IPAddress для полной обратной совместимости с PS 2.0
$AdapterIPv6Enabled =$false

if (Get-Command "Get-NetAdapterBinding" -ErrorAction SilentlyContinue) {
    try {
        $Bindings = Get-NetAdapterBinding -ComponentID "ms_tcpip6" -ErrorAction Stop

        foreach ($Binding in$Bindings) {
            if ($Binding.Enabled -eq$true) {
                Add-Result `
                    -Status "FAIL" `
                    -Name "Adapter $($Binding.Name)" `
                    -Details "Привязка ms_tcpip6 (IPv6) ВКЛЮЧЕНА."
                $AdapterIPv6Enabled = $true
            }
            else {
                Add-Result `
                    -Status "PASS" `
                    -Name "Adapter $($Binding.Name)" `
                    -Details "Привязка ms_tcpip6 (IPv6) ОТКЛЮЧЕНА."
            }
        }
    }
    catch {
        $AdapterIPv6Enabled =$null
    }
}

# Резервная WMI-проверка (если PowerShell 2.0 или командлет NetAdapter недоступен)
if ($null -eq $AdapterIPv6Enabled) {$Adapters = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "IPEnabled=True"

    if ($null -eq$Adapters) {
        Add-Result `
            -Status "WARN" `
            -Name "Network Adapters" `
            -Details "Активные сетевые адаптеры с IPEnabled=True не обнаружены."
    }
    else {
        foreach ($Adapter in $Adapters) {
            $HasIPv6 = $false
            if ($Adapter.IPAddress) {
                foreach ($IP in $Adapter.IPAddress) {
                    if ($IP -match ":") {
                        $HasIPv6 = $true
                        break
                    }
                }
            }

            if ($HasIPv6) {
                Add-Result `
                    -Status "FAIL" `
                    -Name "Adapter Index $($Adapter.Index)" `
                    -Details "$($Adapter.Description) имеет назначенный IPv6 адрес: $($Adapter.IPAddress -join ', ')"
                $AdapterIPv6Enabled =$true
            }
            else {
                Add-Result `
                    -Status "PASS" `
                    -Name "Adapter Index $($Adapter.Index)" `
                    -Details "$($Adapter.Description) не имеет активных IPv6 адресов."
            }
        }
    }
}

# ============================================================
# FINAL RESULT
# ============================================================

Add-Section "FINAL RESULT"

[void]$Results.Add("PASS : $PassCount")
[void]$Results.Add("WARN : $WarnCount")
[void]$Results.Add("FAIL : $FailCount")
[void]$Results.Add("")

if ($FailCount -eq 0 -and $WarnCount -eq 0) {
    $OverallStatus = "PASS"
    [void]$Results.Add("RESULT: PASS")
    [void]$Results.Add("IPv6 полностью отключен на данном хосте.")
}
elseif ($FailCount -eq 0) {
    $OverallStatus = "PASS WITH WARNINGS"
    [void]$Results.Add("RESULT: PASS WITH WARNINGS")
    [void]$Results.Add("IPv6 частично отключен либо требует внимания администратора.")
}
else {
    $OverallStatus = "FAIL"
    [void]$Results.Add("RESULT: FAIL")
    [void]$Results.Add("IPv6 активен (включен в реестре или привязан к сетевым интерфейсам).")
}

# ============================================================
# PREPARE DETAILED RESULT
# ============================================================

$Header = "".PadLeft(70, "=")
$Output = New-Object System.Collections.ArrayList

[void]$Output.Add("")
[void]$Output.Add($Header)
[void]$Output.Add("COMPUTER: $ComputerName")
[void]$Output.Add("DATE: $DateTime")
[void]$Output.Add($Header)

foreach ($Line in $Results) {
    [void]$Output.Add($Line)
}

[void]$Output.Add($Header)
[void]$Output.Add("END OF AUDIT: $ComputerName")
[void]$Output.Add($Header)
[void]$Output.Add("")

# ============================================================
# WRITE DETAILED COMPUTER FILE / MARKER FILE
# ============================================================

$ComputerResultFile = Join-Path $ResultDirectory ($ComputerName + ".txt")
$ResultSavedToNetwork = $false

try {
    $Output | Out-File `
        -FilePath $ComputerResultFile `
        -Encoding UTF8 `
        -Force

    $ResultSavedToNetwork =$true
}
catch {
    $LocalLogDirectory = "C:\ipv6_check"

    if (-not (Test-Path $LocalLogDirectory)) {
        New-Item `
            -Path $LocalLogDirectory `
            -ItemType Directory `
            -Force | Out-Null
    }

    $LocalResult = Join-Path $LocalLogDirectory ($ComputerName + ".txt")

    $Output | Out-File `
        -FilePath $LocalResult `
        -Encoding UTF8 `
        -Force
}

# ============================================================
# RENAME NETWORK RESULT TO STATUS FILE
# ============================================================

if ($ResultSavedToNetwork) {
    $StatusForFileName =$OverallStatus.Replace(" ", "_")
    $FinalResultFile = Join-Path$ResultDirectory ($ComputerName + "_" + $StatusForFileName + ".txt")

    try {
        Rename-Item `
            -Path $ComputerResultFile `
            -NewName ($ComputerName + "_" + $StatusForFileName + ".txt") `
            -Force
    }
    catch {
        # Если переименование не удалось, файл останется маркером при следующем запуске без статуса в имени
    }
}

# ============================================================
# WRITE SUMMARY
# ============================================================

try {
    $SummaryLine = "{0} - {1}" -f $ComputerName, $OverallStatus

    Add-Content `
        -Path $SummaryFile `
        -Value $SummaryLine `
        -Encoding UTF8
}
catch {
    # Сетевой файл занят другим процессом или недоступен
}

# ============================================================
# CONSOLE OUTPUT
# ============================================================

Write-Host ""
Write-Host "============================================================"
Write-Host "IPV6 AUDIT CONSOLE REPORT"
Write-Host "============================================================"
Write-Host ""

foreach ($Line in$Results) {
    Write-Host $Line
}

Write-Host ""
Write-Host "============================================================"
Write-Host "Computer result: $ComputerResultFile"
Write-Host "Overall status:  $OverallStatus"
Write-Host "============================================================"
```