Files
scripts/fix-nic-powersave.ps1

96 lines
5.0 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# fix-nic-powersave.ps1 - отключение энергосбережения сетевой карты (EEE / Green Ethernet / PnP power).
# TrueGamers: лечит link-флапы с периодом ~5 с (PC20 .120, PC06 .106 и другие машины зала).
# Запуск от Администратора: powershell -ExecutionPolicy Bypass -File fix-nic-powersave.ps1
#
# 21.09.2026: заменяет fix-realtek-eee.ps1. Тот работал только с Realtek, а в клубе шесть разных
# OUI (18:C0:4D, 10:7C:61, 30:56:0F, D8:5E:D3, 9C:6B:00, 08:BF:B8) — на остальных машинах он
# просто выходил с "адаптеры не найдены".
#
# ВАЖНО: Wake-on-LAN НЕ трогаем. Клуб будит машины по сети, а метрика "порт на 10 Мбит = машина
# выключена" построена ровно на том, что карта держит линк для WoL (см. decisions/2026-09-15-
# truegamers-false-bad-cable-verdict). Поэтому ключи WakeOnMagicPacket / S5WakeOnLan /
# WolShutdownLinkSpeed остаются как есть.
#
# ВНИМАНИЕ: применение кратко роняет линк (2-5 с, адаптер переинициализируется) —
# только на машине, за которой сейчас никто не играет.
#Requires -RunAsAdministrator
# Ключи реестра, а не подписи в UI: имена свойств локализованы, ключи — нет.
$keywords = @(
'*EEE', # стандартный ключ Energy Efficient Ethernet
'EnableEee', # Realtek
'AdvancedEEE', # Realtek
'EnableGreenEthernet', # Realtek Green Ethernet
'GigaLite', # Realtek Gigabit Lite
'EEELinkAdvertisement', # анонс EEE при автосогласовании
'AutoDisableGigabit', # авто-понижение скорости при простое
'PowerSavingMode', # общий режим энергосбережения
'ULPMode', # Ultra Low Power (Intel/Killer)
'EnableDynamicPowerGating',
'AutoPowerSaveModeEnabled'
)
$nics = Get-NetAdapter -Physical -ErrorAction SilentlyContinue |
Where-Object { $_.Virtual -ne $true }
if (-not $nics) {
Write-Host "Физические сетевые адаптеры не найдены."
exit 1
}
foreach ($nic in $nics) {
Write-Host ("=" * 60)
Write-Host ("Адаптер: " + $nic.Name + " | " + $nic.InterfaceDescription + " | " + $nic.Status + " | " + $nic.LinkSpeed)
# 1) Галка "Разрешить отключение этого устройства для экономии энергии"
try {
Disable-NetAdapterPowerManagement -Name $nic.Name -NoRestart -ErrorAction Stop
Write-Host "[OK] PnP-энергосбережение адаптера отключено"
} catch {
Write-Host ("[WARN] Disable-NetAdapterPowerManagement: " + $_.Exception.Message)
}
# 2) Свойства драйвера
$touched = $false
foreach ($kw in $keywords) {
$cur = Get-NetAdapterAdvancedProperty -Name $nic.Name -RegistryKeyword $kw -ErrorAction SilentlyContinue
if (-not $cur) { continue }
$before = $cur.DisplayValue
if ($cur.RegistryValue -contains '0' -or $before -eq 'Disabled') {
Write-Host ("[..] " + $kw + " уже выключен")
continue
}
try {
Set-NetAdapterAdvancedProperty -Name $nic.Name -RegistryKeyword $kw -RegistryValue 0 -NoRestart -ErrorAction Stop
Write-Host ("[OK] " + $kw + ": '" + $before + "' -> Disabled")
$touched = $true
} catch {
Write-Host ("[WARN] " + $kw + " не удалось выставить: " + $_.Exception.Message)
}
}
# -NoRestart выше копит изменения, чтобы адаптер дёрнулся ОДИН раз, а не после каждого ключа
if ($touched) {
Write-Host "[..] перезапуск адаптера (линк моргнёт на пару секунд)"
try {
Restart-NetAdapter -Name $nic.Name -ErrorAction Stop
} catch {
Write-Host ("[WARN] Restart-NetAdapter: " + $_.Exception.Message)
}
}
}
Write-Host ("=" * 60)
Write-Host "Итог через 8 секунд:"
Start-Sleep -Seconds 8
Get-NetAdapter -Physical | Where-Object { $_.Virtual -ne $true } | ForEach-Object {
$vals = @()
foreach ($kw in $keywords) {
$p = Get-NetAdapterAdvancedProperty -Name $_.Name -RegistryKeyword $kw -ErrorAction SilentlyContinue
if ($p) { $vals += ($kw + "=" + $p.DisplayValue) }
}
$wol = Get-NetAdapterAdvancedProperty -Name $_.Name -RegistryKeyword 'WakeOnMagicPacket' -ErrorAction SilentlyContinue
Write-Host ($_.Name + " | " + $_.Status + " | " + $_.LinkSpeed + " | " + ($vals -join ", ") +
" | WoL=" + $(if ($wol) { $wol.DisplayValue } else { 'n/a' }))
}