Системный Администратор Windows
3.09K subscribers
6 photos
19 links
🖥️ Windows для системных администраторов: управление, оптимизация, безопасность. Полезные советы, лайфхаки, PowerShell-скрипты, автоматизация и практические решения для работы с серверами и рабочими станциями.

Авторский канал.
Download Telegram
👋 Всем админам доброго вечера!

Бывает такое, что сервер достался “по наследству”, всё вроде работает, но внутри - куча сюрпризов. Один из самых частых - в локальных администраторах сидят учётки, о которых никто и не помнит.

🔥 Для быстрой диагностики можно прогнать вот такой скрипт:


$admins = Get-LocalGroupMember -Group "Administrators"
$admins | Select-Object Name, ObjectClass, PrincipalSource


Здесь сразу видно: это локальный пользователь, доменный, или кто-то притащен через группу. Поле PrincipalSource подскажет, откуда взялся доступ.

А если нужно найти только “подозрительных” локальных юзеров, можно сделать так:


$admins | Where-Object { $_.ObjectClass -eq 'User' -and $_.PrincipalSource -eq 'Local' }


👌 Очень полезно проверять такие вещи на серверах после изменений или перед аудитом безопасности. У меня однажды всплыл старый техаккаунт с правами админа, который никто не использовал уже несколько лет.

👉 @win_sysadmin
👍10🔥6
👋 Привет, админы!

Нашел интересную статью, делюсь!

Примеры скриптов PowerShell для системного администрирования

Темы:
Управление дисками и файлами
Настройка текущего расположения (Set-Location)
Сохранение и отзыв последних расположений (Push-Location и Pop-Location)
Работа с файлами и папками. Получение списка файлов и папок, содержащихся в папке.
Копирование файлов и папок
Создание файлов и папок
Удаление всех файлов и папок, содержащихся в папке
Подключение локальной папки как диска
Чтение текстового файла в массив
Работа с файлами, папками и разделами реестра
Перечисление файлов, папок и разделов реестра (Get-ChildItem)
Перечисление всех элементов в контейнере (-Recurse)
Фильтрация элементов по имени (-Name)
Принудительное перечисление скрытых элементов (-Force)
Сопоставление имен элементов с подстановочными знаками
Исключение элементов (-Exclude)
Смешение параметров Get-ChildItem
Работа с записями реестра. Создание списков записей реестра.
Получение одной записи реестра
Настройка одной записи реестра
Создание новых записей реестра
Переименование записей реестра
Удаление записей реестра

https://bookflow.ru/primery-skriptov-powershell-dlya-sistemnogo-administrirovaniya/


Если у вас есть свои интересные ресурсы, просьба накидать к этому посту в комменты.

👉 @win_sysadmin
👍93
👋 Привет, админы!

На днях поймал «скрытый» источник проблем: сервер вроде живой, патчи ставятся, но после обновлений часть софта ведёт себя странно. Виновник - ожидающая перезагрузка (pending reboot), про которую забыли. Решил поделиться быстрой проверкой по паре десятков машин.

🔥 Функция PowerShell, которая показывает признаки pending reboot локально или удалённо (через WinRM):


function Test-PendingReboot {
[CmdletBinding()]
param(
[string[]]$ComputerName = $env:COMPUTERNAME
)

Invoke-Command -ComputerName $ComputerName -ScriptBlock {
$cbs = Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'
$wu = Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'

$pfr = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' `
-Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue
).PendingFileRenameOperations
$pendingFile = ($pfr -is [array] -and $pfr.Count -gt 0) -or ($pfr -is [string] -and $pfr.Length -gt 0)

$rename = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName' `
-Name 'ComputerName' -ErrorAction SilentlyContinue
).ComputerName -ne
(Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName' `
-Name 'ComputerName' -ErrorAction SilentlyContinue
).ComputerName

[PSCustomObject]@{
ComputerName = $env:COMPUTERNAME
CBS = $cbs
WindowsUpdate = $wu
PendingFile = $pendingFile
Rename = $rename
Pending = $cbs -or $wu -or $pendingFile -or $rename
}
} | Sort-Object Pending -Descending, ComputerName
}


⚙️ Пример использования по списку серверов и экспорт в отчёт:


$servers = 'srv01','srv02','srv03'
Test-PendingReboot -ComputerName $servers |
Tee-Object -FilePath .\PendingReboot.csv


💡Аккуратный перезапуск только тех, у кого Pending -eq $true (сначала обязательно с -WhatIf!):


$toReboot = Test-PendingReboot -ComputerName $servers | Where-Object Pending
$toReboot.ComputerName | Restart-Computer -Force -Wait -For PowerShell -Timeout 600 -Delay 5 -WhatIf


Итог: такой мини-аудит часто спасает от «мистики» после патчей и помогает планировать окна на рестарт.

💬 А вы как отслеживаете pending reboot в проде - через Zabbix/PRTG, скриптами по расписанию или отдаёте это WSUS/Intune? Поделитесь практикой!

👉 @win_sysadmin
🔥9👍6
👋 Привет, админы!

Недавно был случай: RDP сессия вроде поднимается, но сразу выкидывает ошибку. Пользователь уверен, что "сервер умер", но на деле виновата была… сетевая политика шифрования.

Когда возникают такие проблемы, я начинаю с базовой диагностики:

1️⃣ Проверяю, что на сервере реально включен RDP:


(Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server").fDenyTSConnections


Если вернёт 1 - значит подключения запрещены. Лечим так:


Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" -Name fDenyTSConnections -Value 0


2️⃣ Проверяю, не задушил ли доступ фаервол:


Get-NetFirewallRule -DisplayGroup "Remote Desktop"


Все правила должны быть включены (Enabled : True).

3️⃣ И финальная проверка - соответствует ли клиент требуемому уровню шифрования. Иногда помогает понизить уровень на сервере:


Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name SecurityLayer -Value 1


(где 0 – без шифрования, 1 – RDP Security Layer, 2 – SSL).

🔥 Итог: в моём случае стояло 2 (SSL), а сертификат был битый. Переключил на 1, и вход сразу заработал.

💬 А у вас часто встречаются проблемы именно из-за криптополитик и сертификатов при RDP? Или в проде сразу подкручиваете свои шаблоны GPO?

👉 @win_sysadmin
👍112🔥2
👋 Привет, админы!

Накидал быстрый чек-скриптl, который опрашивает хосты/порты и показывает, когда сертификат сгорит.

Быстрый чек одного хоста


$HostName = 'site.contoso.com'
$Port = 443

$tcp = [Net.Sockets.TcpClient]::new($HostName, $Port)
$ssl = [Net.Security.SslStream]::new($tcp.GetStream(), $false, { $true })
$ssl.AuthenticateAsClient($HostName)

$cert = [Security.Cryptography.X509Certificates.X509Certificate2]::new($ssl.RemoteCertificate)
[pscustomobject]@{
Host = $HostName
Port = $Port
Subject = $cert.Subject
NotAfter = $cert.NotAfter
DaysLeft = [math]::Floor(($cert.NotAfter - (Get-Date)).TotalDays)
}

$ssl.Dispose(); $tcp.Close()


Скан нескольких целей + статус


$targets = @(
'site1.contoso.com:443',
'mail.contoso.com:993',
'rdgw.contoso.com:443'
)

$result = foreach ($t in $targets) {
$host,$port = $t.Split(':',2)
try {
$tcp = [Net.Sockets.TcpClient]::new($host,[int]$port)
$ssl = [Net.Security.SslStream]::new($tcp.GetStream(), $false, { $true })
$ssl.AuthenticateAsClient($host)

$cert = [Security.Cryptography.X509Certificates.X509Certificate2]::new($ssl.RemoteCertificate)
$days = [math]::Floor(($cert.NotAfter - (Get-Date)).TotalDays)

[pscustomobject]@{
Host = $host
Port = [int]$port
CN = $cert.GetNameInfo('SimpleName',$false)
NotAfter = $cert.NotAfter
DaysLeft = $days
Status = if ($days -le 14) { '🔥 expiring ≤14d' }
elseif ($days -le 30) { '⚠️ <30d' }
else { ' ok' }
}
}
catch {
[pscustomobject]@{
Host=$host; Port=[int]$port; CN=$null; NotAfter=$null; DaysLeft=$null
Status=" error: $($_.Exception.Message)"
}
}
finally {
if ($ssl) { $ssl.Dispose() }
if ($tcp) { $tcp.Close() }
}
}

$result | Sort-Object DaysLeft | Format-Table -AutoSize
# Для отчёта:
# $result | Export-Csv .\tls_report.csv -NoTypeInformation -Encoding UTF8


Плюс: можно крутить по расписанию в Task Scheduler и слать уведомления, если DaysLeft ≤ 30. Спасает от «неожиданных» падений продакшна.

👉 @win_sysadmin
👍91
👋 Привет, админы!

Сегодня хочу поделиться полезным набором приёмов из PowerShell, которые помогают собирать информацию о компьютерах в сети. Часто это нужно при инвентаризации, аудитах или когда приходится быстро проверить состояние сразу нескольких машин.

🔥 Пример базового скрипта для сбора информации:


$computers = "PC1","PC2","PC3"

foreach ($c in $computers) {
Write-Host "Собираю данные с $c..."
Get-WmiObject -Class Win32_ComputerSystem -ComputerName $c |
Select-Object Name, Manufacturer, Model, TotalPhysicalMemory

Get-WmiObject -Class Win32_OperatingSystem -ComputerName $c |
Select-Object Caption, Version, OSArchitecture, LastBootUpTime
}


👉 Такой скрипт выдаст:

- имя и модель ПК,
- производителя,
- объём RAM,
- версию ОС, разрядность,
- время последней загрузки.

💡 Если нужно массово собирать данные, удобнее результаты складывать в CSV:


$results = foreach ($c in $computers) {
Get-WmiObject -Class Win32_OperatingSystem -ComputerName $c |
Select-Object PSComputerName, Caption, Version, LastBootUpTime
}

$results | Export-Csv "C:\Temp\computers.csv" -NoTypeInformation -Encoding UTF8


В итоге получаем аккуратный файл с данными по всем машинам, который можно открыть в Excel и фильтровать по любым параметрам.

💬 А как вы ведёте инвентаризацию парка машин? Excel, CMDB, Intune, SCCM или свои самописные скрипты?

👉 @win_sysadmin
👍11🔥3
👋 Всем админам доброго вечера!

Сегодня поделюсь приёмом, который реально спасает, когда пользователи жалуются на «медленный интернет» или «сетевые лаги». Чаще всего виноват вовсе не провайдер, а перегруженные сетевые интерфейсы на самом сервере.

🔥 Проверить статистику адаптеров можно так:


Get-NetAdapterStatistics | Select-Object Name, ReceivedBytes, SentBytes, ReceivedErrors, OutboundErrors


Команда показывает количество принятых/отправленных байт и ошибки на интерфейсе. Если видите рост ReceivedErrors или OutboundErrors - значит, проблемы в железе, драйвере или кабеле.

А если нужно онлайн-мониторинг, можно добавить цикл:


while ($true) {
Get-NetAdapterStatistics -Name "Ethernet0" |
Select-Object Name, ReceivedErrors, OutboundErrors
Start-Sleep -Seconds 5
}


Так можно «подсматривать» за интерфейсом в реальном времени.

👉 @win_sysadmin
👍17
👋 Привет, админы!

Сегодня расскажу о небольшом, но полезном трюке для мониторинга дисков в Windows через PowerShell. Иногда места на сервере внезапно становится критически мало, и если не отследить вовремя - можно получить падение сервисов или невозможность сохранить логи.



Get-PSDrive -PSProvider FileSystem | Select-Object Name,@{n="FreeGB";e={[math]::Round($_.Free/1GB,2)}},@{n="Used%";e={[math]::Round(100-($_.Free/$_.Used+ $_.Free)*100,2)}}


Он показывает:

- Имя диска
- Свободное место (ГБ)
- Процент занятости

Можно добавить в планировщик задач и получать отчёт на почту или писать лог. А если подключить это к мониторингу (например, через Zabbix/PRTG), то сервер сам предупредит о критическом заполнении.

👉 @win_sysadmin
👍15
👋 Всем коллегам доброго здравия!

На одном файловом сервере пользователи жаловались, что диск «то пустой, то переполнен». Оказалось, дело в том, что теневые копии (Shadow Copies) занимали кучу места, а местные админы об этом забыли (такое бывает 😐).

📌 Быстро проверяем текущее использование теневых копий:


vssadmin list shadowstorage


А если хочется собрать инфу в более удобном виде через PowerShell:


Get-CimInstance -ClassName Win32_ShadowStorage |
Select-Object Volume, AllocatedSpace, UsedSpace, MaxSpace |
Format-Table -AutoSize


Так сразу видно, сколько места уже занято и какой лимит стоит. Иногда достаточно почистить старые копии или уменьшить выделенный объем.

Чтобы удалить все теневые копии на диске C:, можно использовать:


vssadmin delete shadows /for=C: /all /quiet


🚨(Будьте осторожны — после этого пользователи уже не смогут восстановить файлы из предыдущих версий!)

👉 @win_sysadmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍92🤬1
👋 Админы, всем доброго понедельника!

Сегодня напомню про недооценённый инструмент - PowerShell-диски (PSDrive). Это логические “диски” к разным хранилищам: файловая система (C:), реестр (HKCU:/HKLM:), сертификаты (Cert:) и т.д. С ними удобно навигироваться одинаково, одной логикой командлетов Location.

🧭 Базовые команды:


# Показать все доступные PSDrive
Get-PSDrive

# Отфильтровать только файловую систему
Get-PSDrive -PSProvider FileSystem

# Навигация по реестру как по папкам
Set-Location HKLM:\SOFTWARE
Push-Location .\Microsoft
Get-Location


(И да, Get-PSDrive покажет и провайдеры вроде Registry/Certificate/Environment - удобно для обзора).

🧩 Создание своих “дисков”:


# Монтируем удобный ярлык на папку
New-PSDrive -Name Tools -PSProvider FileSystem -Root "C:\Admin\Tools"

# Короткий путь к важной ветке реестра
New-PSDrive -Name CV -PSProvider Registry -Root HKLM:\Software\Microsoft\Windows\CurrentVersion


⚠️ Такие диски живут в текущей сессии. Хотите постоянно - добавьте New-PSDrive в профиль ($PROFILE).

🧹 Удаление:


Remove-PSDrive -Name Tools


Нельзя удалить диск, если вы “на нём” (сначала Set-Location в другое место).

💡 Лайфхаки из практики:

- Держите короткие алиасы на длинные ветки реестра для быстрых правок.
- Для огляда системы делайте Get-PSDrive | Format-Table Name,Provider,Root -Auto.
- В профиле храните свои стандартные монтирования для админских задач.

👉 @win_sysadmin
👍101
👋 Всем админам доброго вечера!

Продолжаю тему теневых копий в Windows - на этот раз чисто PowerShell-практика. Теневые копии (VSS) не раз спасали меня, когда нужно быстро вернуть удалённый файл без полноценного восстановления из бэкапа. Ниже - мой минималистичный «набор выживальщика»: создать снапшот, смонтировать, вытащить файл, почистить и настроить расписание.


🚀 Базовые операции VSS через PowerShell

Создать теневую копию тома C:


# PS 5.1/7+ (через CIM)
Invoke-CimMethod -ClassName Win32_ShadowCopy -MethodName Create `
-Arguments @{ Volume = 'C:\'; Context = 'ClientAccessible' } | Out-Null


Список доступных теневых копий:


Get-CimInstance Win32_ShadowCopy |
Sort-Object InstallDate -Descending |
Format-Table ID, VolumeName, InstallDate, ClientAccessible, DeviceObject -Auto


Смонтировать самую свежую копию в папку (удобно лазить по снапшоту проводником):


$sh = Get-CimInstance Win32_ShadowCopy | Sort-Object InstallDate -Desc | Select-Object -First 1
$mount = 'C:\ShadowMounts\C_latest'
New-Item -ItemType Directory -Path $mount -Force | Out-Null
$dev = ($sh.DeviceObject.TrimEnd('\')) + '\'
cmd /c "mklink /d `"$mount`" `"$dev`""
# Готово: открывайте C:\ShadowMounts\C_latest


Вытянуть конкретный файл из последней копии (без монтирования):


$path = 'C:\Data\report.xlsx' # что хотим вернуть
$sh = Get-CimInstance Win32_ShadowCopy | Sort-Object InstallDate -Desc | Select-Object -First 1
$rel = $path -replace '^[A-Za-z]:\\','' # убрать "C:\"
$src = Join-Path ( ($sh.DeviceObject.TrimEnd('\')) + '\' ) $rel
Copy-Item $src $path -Force


Удалить конкретную теневую копию:


$sh | Remove-CimInstance


🧠 Управление хранилищем теневых копий

Проверить и ограничить размер:


vssadmin list shadowstorage
vssadmin resize shadowstorage /For=C: /On=C: /MaxSize=20%


👉 Если места мало - VSS начнёт сносить самые старые копии. Планируйте «MaxSize».


Планирование ежедневного снапшота (02:00)


$cmd = 'powershell.exe'
$arg = '-NoProfile -WindowStyle Hidden -Command "Invoke-CimMethod -ClassName Win32_ShadowCopy -MethodName Create -Arguments @{Volume=''C:\'';Context=''ClientAccessible''} | Out-Null"'
$action = New-ScheduledTaskAction -Execute $cmd -Argument $arg
$trigger = New-ScheduledTaskTrigger -Daily -At 02:00
Register-ScheduledTask -TaskName 'Daily-VSS-C' -Action $action -Trigger $trigger -RunLevel Highest


На серверах с PowerShell 7 можно заменить powershell.exe на pwsh.exe.



🔒 Безопасность и мониторинг

- Рансомварь любит грохать VSS: ищите команды вроде vssadmin delete shadows /all /quiet, wmic shadowcopy delete, diskshadow.exe.
Логи: включите аудит создания процессов (Sysmon Event ID 1) и подпишите правила под эти утилиты и ключевые слова в командной строке.
- Ограничьте утилиты: на рабочих станциях, где VSS админам не нужен — AppLocker/WDAC для vssadmin.exe, wmic.exe, diskshadow.exe.
- Журналы VSS: заглядывайте в Application и Microsoft-Windows-Volume Shadow Copy/Operational при сбоях провайдера.


🧩 Типичные затыки и лайфхаки

- Доступа нет к путям снапшота — добавляйте \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopyN\ в исключения антивируса на время операций.
- Недостаточно места — расширьте shadowstorage или поменяйте диск-хранилище: /For=C: /On=D:.
- Нужны «предыдущие версии» для пользователей - ставьте Context='ClientAccessible' (или ClientAccessibleWriters для VSS-aware приложений).

👉 @win_sysadmin
👍13🔥42
👋 Всем админам доброго вечера!

Сегодня разберем автоматическое обновление групповых политик (GPO) на клиентах без необходимости ждать стандартного обновления (которое бывает раз в 90 минут + случайное отклонение до 30 минут).

🔥 Если вам нужно срочно применить новую политику, используйте:


gpupdate /force


Но что, если нужно обновить политику на всех компьютерах домена сразу? Тут поможет PowerShell:


Invoke-GPUpdate -Computer "ИмяКомпьютера" -RandomDelayInMinutes 0


А если нужно массово обновить политики на всех машинах в OU? Тогда можно так:


Get-ADComputer -Filter * -SearchBase "OU=Computers,DC=domain,DC=local" | ForEach-Object {
Invoke-GPUpdate -Computer $_.Name -RandomDelayInMinutes 0 -AsJob
}


🔹 gpupdate /force - хорош для локального применения.
🔹 Invoke-GPUpdate - удобен для удаленного обновления GPO.
🔹 Комбинация с Get-ADComputer - идеальна для массового обновления в домене.

👉 @win_sysadmin
👍17🔥3👎2
👋 Привет, админы!

Сегодня разберем одну из самых неприятных ситуаций – когда пользователи жалуются, что их учетные записи блокируются без видимых причин. Разбираешься в логах – а там Event ID 4740 с минимумом информации. Что делать?

🔥 PowerShell спасает! Вот скрипт, который поможет быстро найти источник блокировки:


$LockedUser = "user@domain.com" # Замените на нужный аккаунт
Get-WinEvent -LogName Security | Where-Object {
$_.Id -eq 4740 -and $_.Message -match $LockedUser
} | Select-Object TimeCreated, @{n="Источник";e={($_.Properties[1].Value)}}


Этот код просканирует журнал безопасности, найдет все события 4740 (блокировка учетной записи) и покажет кто именно заблокировал пользователя. Если видите странные IP-адреса или подозрительные устройства – пора разбираться!

💡 Если хотите автоматически мониторить блокировки и получать уведомления, можно настроить Scheduled Task с этим скриптом или завязать на SIEM.

👉 @win_sysadmin
👍16
👋 Привет, админы!

Сегодня разберем скрытых пожирателей ресурсов в Windows и как их быстро выявить.

Бывает, сервер вроде бы работает, но периодически подтормаживает. CPU не загружен, RAM в норме, диск не трещит, а лаги есть. В таких случаях я первым делом проверяю скрытые потребители ресурсов, которых не видно в обычном диспетчере задач.

🔥 Вот парочка полезных команд в PowerShell, которые помогут найти виновника:

1️⃣ Процессы с аномально высоким потреблением дескрипторов (например, утечки в сервисах):


Get-Process | Sort-Object -Property Handles -Descending | Select-Object -First 10


Если видите процесс с сотнями тысяч дескрипторов – это тревожный звоночек.

2️⃣ Проверка использования сети процессами (чтобы вычислить неожиданно болтливые службы):


Get-NetTCPConnection | Group-Object -Property OwningProcess | Sort-Object Count -Descending | Select-Object -First 10


Выяснит, какие процессы держат максимум соединений. Особенно полезно, если сервер внезапно грузит сеть.

3️⃣ Файлы, которые держит процесс (можно отследить, кто блокирует файлы или грузит диск):


Get-Process | Sort-Object -Property Handles -Descending | Select-Object -First 10


Это поможет найти виновника, если диск занят, но не ясно, кто именно активничает.

👉 @win_sysadmin
👍12🔥4
👋 Привет, админы!

В небольших организациях часто бывает так: компьютер списали, из домена вывели, а учетку в AD забыли удалить. Со временем таких “осиротевших” записей становится всё больше - и вот уже список объектов в AD раздувается, мешает управлению и порождает бардак.

Найти такие "забытые" объекты можно с помощью встроенного инструмента PowerShell.


📌 Скрипт ниже ищет компьютеры, которые не логинились в домен 90+ дней, сохраняет список в файл и отправляет его через SMTP:


# Настройки
$days = 90
$time = (Get-Date).AddDays(-$days)
$exportPath = "C:\Scripts\StaleComputers.csv"

# Поиск устаревших компьютеров
$computers = Get-ADComputer -Filter {LastLogonDate -lt $time -and Enabled -eq $true} -Properties LastLogonDate |
Select-Object Name, LastLogonDate, DistinguishedName

# Экспорт в CSV
$computers | Export-Csv -Path $exportPath -NoTypeInformation -Encoding UTF8

# Параметры SMTP
$smtpServer = "smtp.yourdomain.local"
$from = "report@yourdomain.local"
$to = "admin@yourdomain.local"
$subject = "Отчет: Устаревшие учетные записи компьютеров"
$body = "Во вложении список компьютеров, не входивших в домен более $days дней."

# Отправка письма
Send-MailMessage -From $from -To $to -Subject $subject -Body $body -SmtpServer $smtpServer -Attachments $exportPath


Идеально запускать такой скрипт по расписанию через Task Scheduler раз в месяц!

👉 @win_sysadmin
👍17
👋 Привет, админы!

Недавно нужно было срочно найти, кто и когда отключил службу Windows Defender на одном из серверов. В журнале событий куча мусора, стандартный просмотр через Event Viewer - то ещё удовольствие 😅

В таких случаях PowerShell - наше всё. Вот короткий и полезный скрипт, который спас меня:


Get-WinEvent -LogName "System" -FilterXPath "*[System[Provider[@Name='Service Control Manager'] and (EventID=7036)]]" |
Where-Object { $_.Message -like "*Windows Defender*" -and $_.Message -like "*stopped*" } |
Select-Object TimeCreated, Message


📌 Что делает этот скрипт:
- Фильтрует события 7036 - это смена состояния служб;
- Ищет по ключевым словам в сообщении (stopped и Windows Defender);
- Показывает, когда именно служба была остановлена.

🔥 Быстро, удобно и без GUI. Кстати, таким образом можно отслеживать отключения любых критичных сервисов.

👉 @win_sysadmin
🔥14👍6
👋 Привет, админы!

Нужно было выключить группу компьютеров в конце дня, чтобы не гоняли лишнее электричество. Ручками заходить на каждый - удовольствие ниже среднего, поэтому сразу пошёл через PowerShell.

🔥 Вот скрипт, который пробегает по списку имен и выключает их удалённо:


$computers = Get-Content "C:\Scripts\pc_list.txt"

foreach ($pc in $computers) {
try {
Write-Host "Выключаю $pc..." -ForegroundColor Yellow
Stop-Computer -ComputerName $pc -Force -ErrorAction Stop
Write-Host "$pc выключен." -ForegroundColor Green
} catch {
Write-Host "Не удалось выключить $pc: $_" -ForegroundColor Red
}
}


В файле pc_list.txt - просто список имен или IP адресов, по одному на строку.

💡 Не забудь, чтобы всё сработало, на удалённых ПК должна быть включена служба WMI и разрешён доступ через брандмауэр. И конечно, запускай от имени администратора.

👉 @win_sysadmin
👍10👎1
👋 Привет, админы!

Есть очень простой и полезный трюк, который помогает выявить подозрительные подключения к вашему Windows-серверу - особенно актуально, если сервер доступен извне.

🔥 Проверить активные входящие подключения можно командой:


Get-NetTCPConnection -State Established | Where-Object { $_.RemoteAddress -ne '127.0.0.1' } |
Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess |
Sort-Object -Property RemoteAddress


А чтобы узнать, какой процесс стоит за каждым подключением, дополним это:


Get-NetTCPConnection -State Established |
Where-Object { $_.RemoteAddress -ne '127.0.0.1' } |
ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[PSCustomObject]@{
RemoteAddress = $_.RemoteAddress
RemotePort = $_.RemotePort
LocalPort = $_.LocalPort
ProcessName = $proc.ProcessName
PID = $_.OwningProcess
}
} | Sort-Object RemoteAddress


📌 Этот способ помогает быстро выявить:
- необычные подключения к RDP или кастомным портам;
- неизвестные процессы, которые “висят” в сети;
- потенциальный бэкдор или троян.

Поставьте это на регулярный мониторинг через таск или скрипт с логом в файл.

👉 @win_sysadmin
👍14
👋 Привет, админы!

Как быстро понять, кто и когда логинился на сервер или важную машину? Особенно если подозрения на взлом или кто-то заходит в неурочное время (хотя сам так делаю, как правило ночью).

Данный PowerShell-скрипт вытащит логи входа в систему (Event ID 4624) из журнала безопасности:


Get-WinEvent -FilterHashtable @{
LogName = 'Security';
Id = 4624;
StartTime = (Get-Date).AddDays(-1)
} | ForEach-Object {
$xml = [xml]$_.ToXml()
[PSCustomObject]@{
TimeCreated = $_.TimeCreated
AccountName = $xml.Event.EventData.Data | Where-Object {$_.Name -eq "TargetUserName"} | Select-Object -ExpandProperty '#text'
IPAddress = $xml.Event.EventData.Data | Where-Object {$_.Name -eq "IpAddress"} | Select-Object -ExpandProperty '#text'
LogonType = $xml.Event.EventData.Data | Where-Object {$_.Name -eq "LogonType"} | Select-Object -ExpandProperty '#text'
}
} | Where-Object { $_.AccountName -ne "ANONYMOUS LOGON" -and $_.LogonType -eq "10" } | Sort-Object TimeCreated


📌 LogonType = 10 - это удалённый интерактивный вход (RDP).
📌 Можно заменить на 2, если нужен локальный интерактивный логон.
📌 Или убрать фильтр, чтобы увидеть всё.

Полезно для расследований, мониторинга активности админов, а ещё, если нужно зафиксировать "кто заходил ночью" 😅 (главное на себя не выйти 😂)

👉 @win_sysadmin
👍163
👋 Привет, админы!

Сегодня покажу, как быстро найти и перезапустить зависший сервис через PowerShell.

📌Бывают случаи, когда сервис вроде как "работает", статус Running, но по факту не отвечает или не выполняет свои задачи. Такое бывает с агентами резервного копирования, антивирусами и даже SQL Server.

Ниже скрипт, который мне помогает выявить такие "зомби-сервисы" и перезапустить их:


$serviceName = "Имя_сервиса"
$svc = Get-Service -Name $serviceName

if ($svc.Status -eq "Running") {
$process = Get-WmiObject Win32_Service | Where-Object { $_.Name -eq $serviceName }
if ($process.ProcessId -ne 0) {
Write-Host "Сервис запущен с PID $($process.ProcessId). Перезапускаем..."
Restart-Service -Name $serviceName -Force
} else {
Write-Host "PID не найден. Возможна проблема – проверь вручную!"
}
} else {
Write-Host "Сервис не запущен. Статус: $($svc.Status)"
}


💡 Это особенно полезно на тех серверах, где нет стороннего мониторинга, а время реагирования критично.

👉 @win_sysadmin
👍10