Загрузка данных
#requires -version 2.0
<#
.SYNOPSIS
Проверка отключения протокола SMB v1 (клиент и сервер).
.DESCRIPTION
Клиентская сторона (исходящие):
- Драйвер mrxsmb10: Start = 4 (Disabled) или отсутствует
- ИЛИ LanmanWorkstation\Smb1 = 0
Любое из условий = PASS.
Серверная сторона (входящие):
- LanmanServer\SMB1 = 0
- На Windows 10+ параметр может отсутствовать (отключён по умолчанию).
- На Windows 7 отсутствие параметра = FAIL (включён по умолчанию).
Обе стороны должны дать PASS для общего PASS.
Включает случайную задержку 1-30 минут для новых машин.
#>
# ============================================================
# CONFIGURATION
# ============================================================
$ResultDirectory = "\\192.168.6.7\report\smbv1\"
$ComputerName = $env:COMPUTERNAME
$MarkerFile = Join-Path $ResultDirectory ($env:COMPUTERNAME + ".txt")
# ============================================================
# INITIALIZATION
# ============================================================
$ErrorActionPreference = "SilentlyContinue"
# ============================================================
# 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 "SMB v1 DISABLE AUDIT"
Write-Host "============================================================"
Write-Host ""
Write-Host "Computer: $ComputerName"
Write-Host ""
Write-Host "Audit already completed."
Write-Host "Marker file:"
Write-Host $ExistingMarker.Fullname
Write-Host ""
Write-Host "No action required."
Write-Host "============================================================"
exit 0
}
# ============================================================
# RANDOM DELAY (1-30 минут, только для новых машин)
# ============================================================
$MinDelaySeconds = 60
$MaxDelaySeconds = 60
$Random = New-Object System.Random
$Delay = $Random.Next($MinDelaySeconds, $MaxDelaySeconds)
Write-Host "Waiting $Delay seconds before audit (load balancing)..."
Start-Sleep -Seconds $Delay
# ============================================================
# VARIABLES
# ============================================================
$Results = New-Object System.Collections.ArrayList
$FailCount = 0
$WarnCount = 0
$PassCount = 0
$script:IsWin7 = $false
$script:PatchesOk = $false
# ============================================================
# 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 = ""
$Separator = $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
}
}
# ============================================================
# OS & PATCH CHECK
# ============================================================
function Test-OSandPatches {
$OS = Get-WmiObject Win32_OperatingSystem
$OSCaption = $OS.Caption
$OSVersion = $OS.Version
if ($OSVersion -like "6.1*") {
$script:IsWin7 = $true
}
else {
$script:IsWin7 = $false
}
if ($script:IsWin7) {
$CutoffDate = [datetime]"2017-05-01"
try {
$HotFixes = Get-HotFix -ErrorAction Stop |
Sort-Object InstalledOn -Descending
$LatestHotFix = $HotFixes | Select-Object -First 1
if ($null -ne $LatestHotFix -and $null -ne $LatestHotFix.InstalledOn) {
$PatchDate = [datetime]$LatestHotFix.InstalledOn
if ($PatchDate -ge $CutoffDate) {
$script:PatchesOk = $true
Add-Result -Status "PASS" -Name "OS & Patches" `
-Details "Windows 7. Последнее обновление: $($LatestHotFix.HotFixID) от $($LatestHotFix.InstalledOn). Патчи от 2017+ установлены."
}
else {
$script:PatchesOk = $false
Add-Result -Status "FAIL" -Name "OS & Patches" `
-Details "Windows 7. Последнее обновление: $($LatestHotFix.HotFixID) от $($LatestHotFix.InstalledOn). Патчи до мая 2017 — требуется установка обновлений."
}
}
else {
$script:PatchesOk = $false
Add-Result -Status "FAIL" -Name "OS & Patches" `
-Details "Windows 7. Не удалось определить дату последнего обновления."
}
}
catch {
$script:PatchesOk = $false
Add-Result -Status "FAIL" -Name "OS & Patches" `
-Details "Windows 7. Не удалось получить список обновлений."
}
}
else {
$script:PatchesOk = $true
Add-Result -Status "PASS" -Name "OS & Patches" `
-Details "$OSCaption (версия $OSVersion). Проверка патчей не требуется."
}
}
# ============================================================
# CLIENT SIDE CHECK
# ============================================================
function Test-Smb1ClientSide {
# 1. Проверяем драйвер mrxsmb10
$DriverPath = "HKLM:\SYSTEM\CurrentControlSet\Services\mrxsmb10"
$DriverStart = Get-RegistryValueSafe -Path $DriverPath -Name "Start"
$DriverDisabled = $false
if ($null -eq $DriverStart) {
$DriverDisabled = $true
Add-Result -Status "PASS" -Name "Client mrxsmb10" `
-Details "Драйвер mrxsmb10 отсутствует. Исходящие SMB v1 невозможны."
}
elseif ([int]$DriverStart -eq 4) {
$DriverDisabled = $true
Add-Result -Status "PASS" -Name "Client mrxsmb10" `
-Details "Start = 4 (Disabled). Драйвер отключён. Исходящие SMB v1 невозможны."
}
elseif ([int]$DriverStart -eq 2) {
Add-Result -Status "FAIL" -Name "Client mrxsmb10" `
-Details "Start = 2 (Automatic). Драйвер включён — исходящие SMB v1 активны."
}
elseif ([int]$DriverStart -eq 3) {
Add-Result -Status "FAIL" -Name "Client mrxsmb10" `
-Details "Start = 3 (Manual). Драйвер доступен — исходящие SMB v1 могут быть активированы."
}
else {
Add-Result -Status "FAIL" -Name "Client mrxsmb10" `
-Details "Start = $DriverStart. Не удалось определить состояние — считается уязвимым."
}
# 2. Проверяем параметр Smb1 в LanmanWorkstation
$ClientPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters"
$Smb1Value = Get-RegistryValueSafe -Path $ClientPath -Name "Smb1"
if ($DriverDisabled) {
# Драйвер уже отключил клиентскую сторону.
# Параметр Smb1 не критичен, но проверяем для полноты картины.
if ($null -eq $Smb1Value) {
Add-Result -Status "PASS" -Name "Client Smb1" `
-Details "Параметр отсутствует. Драйвер mrxsmb10 уже отключён — исходящие SMB v1 невозможны."
}
elseif ([int]$Smb1Value -eq 0) {
Add-Result -Status "PASS" -Name "Client Smb1" `
-Details "Значение = 0. Дополнительно отключено и через параметр."
}
else {
Add-Result -Status "PASS" -Name "Client Smb1" `
-Details "Значение = $Smb1Value, но драйвер mrxsmb10 отключён — исходящие SMB v1 невозможны."
}
}
else {
# Драйвер активен — параметр Smb1 критичен
if ($null -eq $Smb1Value) {
if ($script:IsWin7) {
if ($script:PatchesOk) {
Add-Result -Status "FAIL" -Name "Client Smb1" `
-Details "Параметр отсутствует, драйвер активен. Патчи есть — нужно создать Smb1 = 0 или отключить драйвер."
}
else {
Add-Result -Status "FAIL" -Name "Client Smb1" `
-Details "Параметр отсутствует, драйвер активен. Патчей до 2017 нет — ключ Smb1 не отработает. Нужно отключить драйвер mrxsmb10."
}
}
else {
Add-Result -Status "FAIL" -Name "Client Smb1" `
-Details "Параметр отсутствует, драйвер активен. На данной ОС нужно создать Smb1 = 0 или отключить драйвер."
}
}
elseif ([int]$Smb1Value -eq 0) {
Add-Result -Status "PASS" -Name "Client Smb1" `
-Details "Значение = 0. SMB v1 на клиенте отключён через параметр."
}
else {
Add-Result -Status "FAIL" -Name "Client Smb1" `
-Details "Значение = $Smb1Value. SMB v1 на клиенте включён."
}
}
}
# ============================================================
# SERVER SIDE CHECK
# ============================================================
function Test-Smb1ServerSide {
$ServerPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
$SMB1Value = Get-RegistryValueSafe -Path $ServerPath -Name "SMB1"
if ($null -eq $SMB1Value) {
# Параметр отсутствует
if ($script:IsWin7) {
# Windows 7: параметр по умолчанию отсутствует = SMB v1 включён
Add-Result -Status "FAIL" -Name "Server SMB1" `
-Details "Параметр отсутствует. На Windows 7 SMB v1 на сервере включён по умолчанию. Нужно создать SMB1 = 0."
}
else {
# Windows 10+: SMB v1 на сервере отключён по умолчанию (начиная с 1709)
Add-Result -Status "PASS" -Name "Server SMB1" `
-Details "Параметр отсутствует. На данной версии ОС SMB v1 на сервере отключён по умолчанию."
}
}
elseif ([int]$SMB1Value -eq 0) {
Add-Result -Status "PASS" -Name "Server SMB1" `
-Details "Значение = 0. SMB v1 на сервере отключён."
}
else {
Add-Result -Status "FAIL" -Name "Server SMB1" `
-Details "Значение = $SMB1Value. SMB v1 на сервере включён."
}
}
# ============================================================
# 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
$OSArchitecture = $OS.OSArchitecture
if ([string]::IsNullOrEmpty($OSArchitecture)) {
if ([IntPtr]::Size -eq 8) {
$OSArchitecture = "64-bit"
}
else {
$OSArchitecture = "32-bit"
}
}
# ============================================================
# REPORT HEADER
# ============================================================
[void]$Results.Add("============================================================")
[void]$Results.Add("SMB v1 DISABLE AUDIT")
[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("Architecture : $OSArchitecture")
[void]$Results.Add("User : $CurrentUser")
[void]$Results.Add("Date : $DateTime")
# ============================================================
# 0. OS & PATCH PREREQUISITE CHECK
# ============================================================
Add-Section "0. OS & PATCH PREREQUISITE CHECK"
Test-OSandPatches
# ============================================================
# 1. CLIENT SIDE (исходящие SMB v1)
# ============================================================
Add-Section "1. CLIENT SIDE (исходящие SMB v1)"
Test-Smb1ClientSide
# ============================================================
# 2. SERVER SIDE (входящие SMB v1)
# ============================================================
Add-Section "2. SERVER SIDE (входящие SMB v1)"
Test-Smb1ServerSide
# ============================================================
# 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("SMB v1 полностью отключён (клиент и сервер).")
}
elseif ($FailCount -eq 0) {
$OverallStatus = "PASS WITH WARNINGS"
[void]$Results.Add("RESULT: PASS WITH WARNINGS")
[void]$Results.Add("Критических нарушений не обнаружено, но присутствуют предупреждения.")
}
else {
$OverallStatus = "FAIL"
[void]$Results.Add("RESULT: FAIL")
[void]$Results.Add("SMB v1 включён на клиенте и/или сервере. Требуется отключение.")
}
# ============================================================
# PREPARE OUTPUT
# ============================================================
$Header = ""
$Header = $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 RESULT / MARKER
# ============================================================
$ComputerResultFile = Join-Path `
$ResultDirectory `
($ComputerName + ".txt")
$ResultSavedToNetwork = $false
try {
$Output | Out-File `
-FilePath $ComputerResultFile `
-Encoding UTF8 `
-Force
$ResultSavedToNetwork = $true
}
catch {
$LocalLogDirectory = "C:\smb_v1_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(" ", "_")
try {
Rename-Item `
-Path $ComputerResultFile `
-NewName (
$ComputerName + "_" +
$StatusForFileName + ".txt"
) `
-Force
$MarkerFile = Join-Path $ResultDirectory ($ComputerName + "_" + $StatusForFileName + ".txt")
}
catch {
$MarkerFile = $null
}
}
# ============================================================
# CONSOLE OUTPUT
# ============================================================
Write-Host ""
Write-Host "============================================================"
Write-Host "SMB v1 DISABLE AUDIT"
Write-Host "============================================================"
Write-Host ""
foreach ($Line in $Results) {
Write-Host $Line
}
Write-Host ""
Write-Host "============================================================"
Write-Host "Computer result:"
Write-Host $MarkerFile
Write-Host ""
Write-Host "Overall status:"
Write-Host $OverallStatus
Write-Host "============================================================"