fa
Feedback
Системный Администратор Windows

Системный Администратор Windows

رفتن به کانال در Telegram

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

نمایش بیشتر
3 097
مشترکین
+224 ساعت
-17 روز
+530 روز
آرشیو پست ها
👋 Привет, админы! Сегодня хочу поделиться полезным приёмом из практики hardening Windows — поиск старых и потенциально уязвимых локальных админов. В некоторых организациях после внедрения GPO или изменений в AD остаются локальные админы, про которых все забыли. А это — отличная лазейка для lateral movement. Особенно если это старые учетные записи с паролями, установленными вручную. 📌 Вот PowerShell-однострочник, который покажет всех локальных админов на машине:

Get-LocalGroupMember -Group "Administrators" | Select-Object Name, ObjectClass, PrincipalSource
А если нужно проверить сразу несколько машин, удобно использовать Invoke-Command:

$servers = @("SRV1", "SRV2", "SRV3")
Invoke-Command -ComputerName $servers -ScriptBlock {
    Get-LocalGroupMember -Group "Administrators" | Select-Object Name, ObjectClass, PrincipalSource
}
📍 Особенно обратите внимание на пользователей с PrincipalSource = "Local". Если такие учетки не используются по делу — удаляйте или отключайте. ✅ Регулярный аудит локальных групп — одна из простейших, но мощных мер для повышения безопасности. 💬 А вы чистите локальных админов вручную или автоматизировали? Может, делаете это через GPO или Ansible/Intune? 👉 @win_sysadmin

👋 Привет, админы! Недавно один из серверов начал ругаться на нехватку места на диске. Визуально — всё в порядке, но свободного осталось меньше 1 ГБ. Надо было срочно найти, кто пожрал диск. Делюсь простым, но мощным PowerShell-способом найти самые тяжёлые файлы: 📦 Поиск топ-10 самых больших файлов на диске:

Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue |
  Where-Object { -not $_.PSIsContainer } |
  Sort-Object Length -Descending |
  Select-Object FullName, @{Name="SizeMB";Expression={"{0:N2}" -f ($_.Length / 1MB)}} -First 10
Что делает скрипт: * Рекурсивно обходит все файлы (-Recurse) * Отбрасывает каталоги (Where-Object { -not $_.PSIsContainer }) * Сортирует по размеру * Показывает путь и размер в МБ 📍 Хочешь ограничить область поиска? Просто меняй -Path, например:

-Path "C:\Users", "D:\Temp"
⚡ Очень выручает, когда надо быстро понять, где «накапало» мусора — особенно в TEMP, профилях пользователей или логах каких-нибудь нестабильных приложений. 💬 А у тебя есть свой любимый способ находить крупные файлы в Windows? Используешь PowerShell, WinDirStat или что-то кастомное? 👉 @win_sysadmin

👋 Привет, админы! Поймал недавно одну неприятную ситуацию на проде — перестали запускаться скрипты PowerShell через Task Scheduler. Причём руками всё работает, а в планировщике — ноль реакции. Думаю, многим знакома такая картина. 🔍 В чём была проблема: Оказалось, после обновления безопасности Windows один из серверов начал блокировать запуск скриптов из-за политики исполнения (ExecutionPolicy). А в задаче стояло просто powershell.exe -File ..., без указания параметров. 🛠️ Решение простое — всегда явно указывай политику исполнения при запуске из планировщика:

powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\Backup.ps1"
И не забудь, что путь к скрипту должен быть абсолютным, иначе Task Scheduler не найдёт файл, особенно если он запускается от SYSTEM или другого сервиса без профиля. 📌 если нужно логирование — добавь вывод в файл:

powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\Backup.ps1" >> C:\Logs\backup.log 2>&1
💬 А у тебя были случаи, когда планировщик Windows молчал как партизан? Как отлавливаешь такие баги? 👉 @win_sysadmin

👋 Привет, админы! Сегодня разберём неочевидную, но важную тему: кто может изменять SPN в AD — и почему это может быть проблемой. Был у меня случай, когда обычный сервисный аккаунт внезапно “помог” и снёс SPN у пары серверов. Угадайте, сколько времени ушло на восстановление? 🙃 🔍 По умолчанию владельцем SPN является компьютер или учётка, которой принадлежит объект AD. Но если у пользователя есть права Write servicePrincipalName — он может спокойно его менять. 💡 Как проверить, кто может править SPN на конкретном объекте?

# Показываем ACL для объекта
$comp = Get-ADComputer -Identity "server01"
$acl = Get-ACL "AD:\$($comp.DistinguishedName)"
$acl.Access | Where-Object { $_.ActiveDirectoryRights -like "*WriteProperty*" -and $_.ObjectType -eq "bf9679c0-0de6-11d0-a285-00aa003049e2" }
📌 bf9679c0... — это GUID атрибута servicePrincipalName. Всё, что найдено — потенциальные редакторы SPN. ✅ Чтобы ограничить доступ, можно: * Убрать из ACL лишние делегирования (например, у сервисных аккаунтов). * Создать отдельную группу SPN-админов, у которой будет право на редактирование, и только у неё. * Мониторить изменения SPN через Security Event Log или Auditing в AD. 💬 А как ты контролируешь права на SPN? Сталкивался с ситуацией, когда “лишний” доступ ломал Kerberos или WinRM? 👉 @win_sysadmin

👋 Привет, админы! Помнишь, мы говорили про мониторинг SPN? Так вот — одно дело заметить пропажу, а другое — сразу восстановить, пока не прилетели тикеты от пользователей и не начался хаос. 🔥 Вот PowerShell-скрипт, который проверяет наличие SPN WSMAN/имя_компьютера и добавляет его обратно, если нужно:

Import-Module ActiveDirectory

$computers = Get-ADComputer -Filter * -Properties ServicePrincipalName

foreach ($comp in $computers) {
    $spn = "WSMAN/$($comp.Name)"
    
    if (-not ($comp.ServicePrincipalName -contains $spn)) {
        try {
            Write-Host "Восстанавливаю SPN для $($comp.Name)..." -ForegroundColor Yellow
            setspn -S $spn $comp.Name
        }
        catch {
            Write-Host "❌ Ошибка для $($comp.Name): $_" -ForegroundColor Red
        }
    }
}
📌 Советую запускать это от имени учётки с правами на изменение SPN в AD. Можно повесить на планировщик или встроить в CI/CD пайплайн, если сервера поднимаются автоматически. 💡 Плюс: можно логировать в файл или отправлять уведомление при каждом восстановлении — для прозрачности. 💬 А у тебя бывали случаи, когда SPN пропадал и ломал всё? Как автоматизируешь восстановление? Делись кейсами в комментах 👇 👉 @win_sysadmin

🚀 MEETUPxSPRINT OFFER для инженеров технической поддержки от YADRO Хочешь узнать, как устроена техническая поддержка в одной из ведущих технологических компаний России? Приходи на онлайн-митап от YADRO! Расскажем, покажем, ответим на любые вопросы — и дадим возможность попасть в команду всего за 3 дня! 🔥 Программа митапа: ✔️ Сервисная служба YADRO: основные ресурсы и направления Василий Бронников, Руководитель отдела техподдержки решений ✔️ Наши продукты: уникальные характеристики и возможности Андрей Антоненко, Ведущий инженер техподдержки TATLIN ✔️ Реальные кейсы: как команды решают сложные задачи Дмитрий Сафонов, Руководитель группы L1-поддержки TATLIN.UNIFIED 🔥 Что тебя ждёт: ➖ Реальные кейсы и инсайты из практики техподдержки ➖ Доклады от инженеров YADRO: продукты, процессы, особенности ➖ Живое общение с командой и ответы на вопросы о работе и технологиях 👨‍💻 А если ты задумываешься о новой работе — у тебя есть возможность быстро попасть в команду YADRO и получить оффер за 3 дня. Для этого нужно пройти короткий тест. Сделать это можно уже сейчас, а также во время или после митапа — выбирай, как тебе удобно (но заявки принимаем до 6 июля). 📌 Тест можно пройти по ссылке. ➖➖➖ 🗓 26 июня, начало в 19:00 мск, четверг 🌐 ОНЛАЙН Регистрация на мероприятие Реклама. ООО "ЭВРОНЕ.РУ". ИНН 3663057399. erid: 2VtzqxHGr6J

👋 Привет, админы! Продолжая тему SPN, сегодня расскажу, как отслеживать изменения SPN в AD. Был у меня кейс: один коллега удалил SPN у критического сервера (по ошибке, конечно 😅), и всё — WinRM лег, приложения не коннектятся. Алертов не было. Делать так — нельзя. 🔥 Вот скрипт, который можно повесить на задачу по расписанию. Он проверяет наличие SPN WSMAN/имя_компьютера и шлёт алерт, если он исчез:

$computers = Get-ADComputer -Filter * -Properties ServicePrincipalName
$missingSpn = @()

foreach ($comp in $computers) {
    $expectedSpn = "WSMAN/$($comp.Name)"
    if (-not ($comp.ServicePrincipalName -contains $expectedSpn)) {
        $missingSpn += $comp.Name
    }
}

if ($missingSpn.Count -gt 0) {
    $body = "На следующих машинах отсутствует SPN WSMAN:`n" + ($missingSpn -join "`n")
    Send-MailMessage -To "admin@domain.local" -From "spn-monitor@domain.local" `
        -Subject "❗ Отсутствует SPN WSMAN" -Body $body -SmtpServer "smtp.domain.local"
}
📌 Можно доработать — писать в лог, интегрировать с SIEM, триггерить webhook в Zabbix и т.д. Главное — не терять SPN из виду. Один сбой может стоить кучи нервов. 💬 А ты мониторишь SPN? Или больше полагаешься на ручной аудит/расследование постфактум? Поделись, как у тебя это организовано! 👉 @win_sysadmin

👋 Привет, админы! Недавно делал деплой для пачки новых серверов и по старой памяти вручную создавал нужные GPO. Потом подумал — а зачем, если всё можно автоматизировать? 💡 🔥 Делюсь скриптом, который создаёт и настраивает GPO, а потом линкует её к OU. Всё через PowerShell:

# Имя новой политики и OU
$gpoName = "WinRM Config"
$ou = "OU=Servers,DC=domain,DC=local"

# Создаём политику, если её ещё нет
if (-not (Get-GPO -Name $gpoName -ErrorAction SilentlyContinue)) {
    New-GPO -Name $gpoName
}

# Настраиваем WinRM в этой политике
$gpo = Get-GPO -Name $gpoName
Set-GPRegistryValue -Name $gpo.DisplayName -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" `
    -ValueName "AllowAutoConfig" -Type DWord -Value 1
Set-GPRegistryValue -Name $gpo.DisplayName -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" `
    -ValueName "AllowUnencryptedTraffic" -Type DWord -Value 0

# Линкуем GPO к нужному OU
New-GPLink -Name $gpoName -Target $ou -Enforced $false
📌 Под капотом это обычная настройка через Set-GPRegistryValue, но ты можешь добавлять туда любые параметры — фаервол, автологон, аудит и т.д. 💬 А ты автоматизируешь управление GPO? Может, используешь AGPM или предпочитаешь работать через GUI? Делись опытом! 👉 @win_sysadmin

Вебинар Используй ЕССМ по полной! 🗓 20.06.2025 🕒 14:00 по МСК 1) Будь в курсе! - события: источники, правила генерации - ав
Вебинар Используй ЕССМ по полной! 🗓 20.06.2025 🕒 14:00 по МСК 1) Будь в курсе! - события: источники, правила генерации - аварии: правила генерации и закрытия, корреляция событий, каналы уведомлений 2) Управляй! - язык шаблонов Jinja2 и его основные конструкции - написание шаблонов конфигурации для автоматизации типовых задач администратора 3) Инициализируй! - реализация механизма ZTP - как достать коммутатор из коробки и автоматически настроить его 👉 Регистрация  Ведущий вебинара: Алексей Листаров — инженер с многолетним опытом работы в крупном операторе связи. Сертифицированный преподаватель нашего авторизованного центра Академии Eltex. #eltex #eltexcm #webinar #вебинар #naice #eccm @eltexcm #реклама О рекламодателе

👋 Привет, админы! Сегодня словил интересный баг с WinRM на новых машинах в домене. После настройки через GPO и попытки подключения по PowerShell Remoting — облом:
WinRM cannot process the request. The following error occurred while using Kerberos authentication: Cannot find the computer X. Verify that the computer exists on the network and that the name provided is spelled correctly.
Хотя DNS работает, ping проходит, GPO с настройками WinRM прилетела. Где собака зарыта? 🐶 🔍 Проблема оказалась в отсутствии регистрации SPN для машины в AD. Без него Kerberos просто не может авторизовать подключение. Решается вот так:

setspn -S WSMAN/имя_компьютера имя_компьютера
Если машин много — автоматизируем через PowerShell:

$computers = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name
foreach ($comp in $computers) {
    setspn -S "WSMAN/$comp" $comp
}
⚠️ Конечно, нужны права на запись SPN (обычно у админа домена). После регистрации SPN — всё взлетело без ошибок. 💬 А у тебя были проблемы с WinRM или Kerberos? Как настраиваешь remoting — вручную, через DSC, GPO или Ansible? 👉 @win_sysadmin

👋 Привет, админы! Из жизни. На продакшн-сервере внезапно упал веб-сервис — выяснилось, что SSL-сертификат истёк в 00:01, а пользователи начали получать ошибки подключения. Пришлось оперативно проверять все сертификаты. 🔥 Для быстрой диагностики я написал PowerShell-скрипт, который подключается к списку серверов, собирает все сертификаты и рассчитывает, сколько дней осталось до их истечения:

$servers = @("web01","web02","web03")
$results = foreach($server in $servers) {
    Write-Verbose "Проверяю сертификаты на $server"
    Get-ChildItem -Path "\\$server\C$\Windows\System32\certsrv\CertEnroll" -Recurse -Include *.cer,*.pfx |
    ForEach-Object {
        try {
            $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($_.FullName)
            [PSCustomObject]@{
                Server   = $server
                Subject  = $cert.Subject
                NotAfter = $cert.NotAfter
                DaysLeft = ($cert.NotAfter - (Get-Date)).Days
            }
        } catch {
            Write-Warning "Не удалось загрузить сертификат из $($_.FullName) на $server"
        }
    }
}
$results | Sort-Object DaysLeft | Format-Table -AutoSize
Этот скрипт выводит таблицу с оставшимися днями жизни (DaysLeft) каждого сертификата, упорядоченную по возрастанию. Те, у которых DaysLeft≈0 или отрицательно, сразу бросаются в глаза. В реальной инфраструктуре я добавил отправку результата по e-mail через Send-MailMessage и запланировал задачу в Task Scheduler с ежедневным запуском. 💬 А как вы мониторите сроки действия сертификатов в своих средах? Пишете ли свои PowerShell-модули, используете встроенные возможности SCOM/Ansible или сторонние решения? Делитесь в комментариях! 👉 @win_sysadmin

👋 Привет, админы! На этой неделе у меня случился любопытный кейс: в нашем кластере файловых серверов неожиданно начал быстро расти объём используемого пространства на диске C:, и в итоге свободного места осталось менее 5 %. Из-за этого падали бэкапы и тормозили пользовательские шаринги. 🔥 Чтобы оперативно собрать информацию о свободном месте на всех серверах и получить наглядный отчёт, я использовал такой PowerShell-скрипт:

# Список серверов можно вынести в текстовый файл или переменную
$servers = @('FS01','FS02','FS03')

# Сбор информации о дисках
$result = foreach ($s in $servers) {
    Get-PSDrive -PSProvider FileSystem -ComputerName $s |
    Select-Object @{Name='Server';Expression={$s}},
                  Name,
                  @{Name='Free(GB)';Expression={[math]::Round($_.Free/1GB,2)}},
                  @{Name='Used(%)';Expression={[math]::Round((($_.Used)/($_.Free + $_.Used))*100,1)}} 
}

# Сохраняем в CSV для дальнейшего анализа
$result | Export-Csv -Path C:\Reports\DiskSpaceReport.csv -NoTypeInformation -Encoding UTF8

# Или выводим сразу в виде таблицы в консоли
$result | Format-Table -AutoSize
Этот скрипт помогает мгновенно увидеть, на каких серверах и дисках критически мало места. Я настроил его запуск раз в час через Task Scheduler и добавил оповещение по почте, если Used(%) превышает 90 %. 💬 А как вы мониторите заполнение дисков? Держите подобные задачи в Zabbix/PRTG, или предпочитаете чистый PowerShell + планировщик? Делитесь своими лайфхаками! 👉 @win_sysadmin

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

# Список серверов в текстовом файле (по одному в строке)
$servers = Get-Content -Path "C:\scripts\servers.txt"

# Формируем результаты
$report = foreach ($server in $servers) {
    Try {
        Invoke-Command -ComputerName $server -ScriptBlock {
            Get-LocalGroupMember -Group "Administrators" |
                Select-Object @{Name='Server';Expression={$env:COMPUTERNAME}},
                              Name, ObjectClass
        } -ErrorAction Stop
    }
    Catch {
        [PSCustomObject]@{
            Server      = $server
            Name        = '<не удалось получить данные>'
            ObjectClass = 'Error'
        }
    }
}

# Сохраняем в CSV и открываем
$csvPath = "C:\reports\AdminsAudit_$(Get-Date -Format yyyy-MM-dd).csv"
$report | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
Invoke-Item $csvPath
🛠 Что делает скрипт: ◾️Берёт список серверов из файла servers.txt ◾️Через Invoke-Command собирает членов локальной группы Administrators на каждом хосте ◾️Обрабатывает ошибки (например, недоступный сервер) ◾️Экспортирует итоговый отчёт в CSV с датой в имени Этот подход легко расширить — добавить уведомление по почте через Send-MailMessage или интеграцию с Teams/Slack, а также запускать по расписанию в Task Scheduler или Azure Automation. 💬 А как вы проводите аудит локальных администраторов? Есть ли у вас готовые решения или сторонние инструменты? Поделитесь в комментариях! 👉 @win_sysadmin

👋 Привет, админы! Вспоминаю случай, когда утром в понедельник один из наших веб-сервисов внезапно перестал отвечать — выяснилось, что сертификат SSL на фронт-енд прокси истёк. Это напомнило, как легко потерять доступ к важным системам из-за банального администрирования сертификатов. 🔥 Чтобы автоматизировать проверку сроков действия сертификатов в Windows, можно использовать PowerShell. Вот базовый скрипт, который ищет в хранилище LocalMachine\My сертификаты, у которых осталось менее 30 дней до истечения, и отправляет уведомление на почту:

# Порог в днях до истечения
$threshold = 30

# Получаем все сертификаты, у которых осталось <= $threshold дней
$certs = Get-ChildItem Cert:\LocalMachine\My |
    Where-Object { ($_.NotAfter - (Get-Date)).Days -le $threshold }

if ($certs) {
    # Формируем тело письма
    $body = $certs | ForEach-Object {
        "Сертификат: $($_.Subject) ― истекает через $((($_.NotAfter) - (Get-Date)).Days) дней, дата истечения: $($_.NotAfter)"
    } -join "`n"

    # Отправляем письмо
    Send-MailMessage `
        -From "monitor@domain.local" `
        -To "admin@domain.local" `
        -Subject "Внимание: сертификаты SSL скоро истекут" `
        -Body $body `
        -SmtpServer "mail.domain.local"
}
Этот хук можно запускать ежедневно по расписанию через Task Scheduler или превратить в задачу Azure Automation / Runbook. Также рекомендую добавить логирование в файл и интеграцию с вашим мониторингом (Zabbix, PRTG, SCOM), чтобы видеть историю предупреждений. 💬 А вы как контролируете сроки действия сертификатов? Может, используете специальные модули (PSPKI, Posh-ACME) или облачные сервисы? Делитесь идеями и скриптами в комментариях! 👉 @win_sysadmin

👋 Привет, админы! Недавно столкнулся с интересным кейсом: один из файловых серверов начал сигнализировать о недостатке свободного пространства. При проверке выяснилось, что причиной стали старые логи IIS и системные файлы, которые копились неделями. Для нас, админов, важно держать «мусор» под контролем, чтобы не проснуться однажды с дискoм, полностью забитым «ненужными» данными. 🔥 В таких случаях мне помогает небольшой PowerShell-скрипт для автоматической очистки логов старше заданного числа дней. Вот что я настроил:

# Путь до папки с логами (пример для IIS)
$LogPath = "C:\inetpub\logs\LogFiles"

# Возраст файлов (в днях), после которого файлы подлежат удалению
$DaysThreshold = 30

# Получаем все файлы в папке и вложенных каталогах старше $DaysThreshold
$OldLogs = Get-ChildItem -Path $LogPath -Recurse -File |
           Where-Object { ($_.LastWriteTime -lt (Get-Date).AddDays(-$DaysThreshold)) }

# Если есть файлы для удаления, выводим их и удаляем
if ($OldLogs) {
    Write-Host "Найдены логи старше $DaysThreshold дней:`n" -ForegroundColor Yellow
    $OldLogs | Select-Object FullName, LastWriteTime | Format-Table -AutoSize

    # Удаляем найденные файлы
    $OldLogs | Remove-Item -Force -Verbose
    Write-Host "`nОчистка завершена." -ForegroundColor Green
} else {
    Write-Host "Файлы старше $DaysThreshold дней не найдены." -ForegroundColor Green
}
Основные моменты: 1. Гибкая настройка пути: в переменной $LogPath можно указать любую директорию – например, логи SQL Server (C:\Program Files\Microsoft SQL Server\MSSQLxx.MSSQLSERVER\MSSQL\Log) или системные временные папки (C:\Windows\Temp). 2. Параметр возраста: переменная $DaysThreshold задаёт, сколько дней «жить» файлам, прежде чем они удалятся. Можно настроить, например, на 7 дней для критических логов или на 90 дней для менее важных. 3. Рекурсивный обход: флаг -Recurse позволяет удалять не только файлы в корне, но и во вложенных папках (удобно, если логи разбиты по датам или подпапкам). 4. Безопасность: перед удалением скрипт выводит список удаляемых файлов. Если сомневаетесь — закомментируйте строку Remove-Item и сначала просто отследите, какие файлы будут выбраны. 💬 Я запланировал выполнение этого скрипта через Task Scheduler каждую неделю в воскресенье в полночь. В результате освободилось несколько десятков гигабайт и администраторы перестали получать тревожные письма о заполненном разделе C:. А как вы справляетесь с накоплением логов на серверах? Может, используете какие-то централизованные решения (SIEM, Splunk, ELK) для ретеншена и ротации? Делитесь своими приёмами в комментариях! 👉 @win_sysadmin

👋 Привет, админы! Если не ошибаюсь, осенью 21 года в одном из наших дата-центров после планового обновления клиентских машин начали массово падать сеансы RDP — пользователи жаловались, что после ввода пароля сессия сразу же разрывается. Оказалось, во время апдейта поставился неполностью совместимый патч безопасности, который конфликтовал с включённым на компьютерах аудиторией учетных политик. 🔥 Чтобы быстро отследить все последние установленные обновления на целевой группе машин и при необходимости откатить проблемный патч, я использовал вот такой PowerShell-скрипт:

# Получаем список компьютеров из текстового файла
$computers = Get-Content -Path "C:\Scripts\computers.txt"

# Словарь для хранения списка установленных обновлений
$updateReport = @()

foreach ($computer in $computers) {
    try {
        # Получаем установленные обновления за последние 7 дней
        $recentUpdates = Get-HotFix -ComputerName $computer |
                         Where-Object { $_.InstalledOn -ge (Get-Date).AddDays(-7) }

        foreach ($upd in $recentUpdates) {
            $updateReport += [PSCustomObject]@{
                Computer   = $computer
                KBArticle   = $upd.HotFixID
                InstalledOn = $upd.InstalledOn
            }
        }
    }
    catch {
        Write-Warning "Не удалось получить обновления с сервера $computer: $_"
    }
}

# Сохраняем отчёт в CSV
$csvPath = "C:\Scripts\RecentUpdatesReport.csv"
$updateReport | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8

Write-Host "Отчет сохранен в $csvPath"
С помощью этого отчёта мы быстро определили, что именно на всех проблемных ПК установился KB5005565. Чтобы откатить его удалённо, использовал команду:

Invoke-Command -ComputerName (Get-Content "C:\Scripts\computers.txt") -ScriptBlock {
    wusa /uninstall /kb:5005565 /quiet /norestart
}
После перезапуска машин RDP-сессии вернулись в норму. Плюс я добавил правило на WSUS, чтобы этот конкретный патч не раздавался снова до выяснения причины конфликта. 💬 А у вас были подобные случаи, когда обновление “ломало” корпоративные политики или приложения? Какими методами вы собираете информацию об установленных патчах и откатываете проблемные? Делитесь своим опытом в комментах! 👉 @win_sysadmin

👋 Привет, админы! Недавно столкнулся с кейсом: один из файловых серверов неожиданно перестал принимать события — логи просто «забились» до предела, из-за чего служба безопасности не могла записывать критичные события входа. Оказалось, что журналы событий выросли до 10 ГБ и система больше не записывала новые записи. 🔥 Чтобы предотвратить подобные ситуации, я собрал небольшой скрипт для автоматического архивации и очистки журналов событий, когда их размер превышает заданный порог. Вот пример, который запустил на сервере:

# Порог в мегабайтах
$logSizeThresholdMB = 1024

# Папка для архивации
$archivePath = "D:\EventLogArchives"
if (-not (Test-Path $archivePath)) {
    New-Item -Path $archivePath -ItemType Directory | Out-Null
}

# Функция для проверки и архивации логов
function Archive-And-Clear-EventLog {
    param (
        [string]$LogName
    )
    # Определяем текущий размер лога
    $logInfo = wevtutil gl $LogName
    $fileSizeLine = ($logInfo | Where-Object { $_ -match "fileSize" })
    $sizeBytes = [int64]($fileSizeLine -replace "[^0-9]", "")
    $sizeMB = [math]::Round($sizeBytes / 1MB, 2)

    if ($sizeMB -ge $logSizeThresholdMB) {
        $timestamp = (Get-Date).ToString("yyyyMMdd_HHmmss")
        $archiveFile = Join-Path $archivePath "$LogName`_$timestamp.evtx"

        # Экспортируем текущий журнал
        wevtutil epl $LogName $archiveFile
        Write-Host "Архивировал лог $LogName (размер $sizeMB MB) в $archiveFile"

        # Очищаем журнал
        wevtutil cl $LogName
        Write-Host "Очищен лог $LogName"
    } else {
        Write-Host "Лог $LogName в пределах нормы: $sizeMB MB"
    }
}

# Получаем все журналы, которые хотим контролировать (пример: System и Security)
$logsToCheck = @("System", "Security")
foreach ($log in $logsToCheck) {
    Archive-And-Clear-EventLog -LogName $log
}
Этот скрипт проверяет размер каждого указанного журнала, экспортирует его в папку архива, если размер больше 1 ГБ, и очищает файл. Я поставил его в Task Scheduler с частотой 1 раз в сутки, чтобы не «догонять» проблему вручную. 💬 А какие у вас есть практики по управлению журналами событий? Используете стандартные утилиты wevtutil/Get-WinEvent или доверяете решениям наподобие SCOM/Elastic Stack? Делитесь в комментах! 👉 @win_sysadmin

👋 Привет, админы! Недавно столкнулся с ситуацией: на одном из серверов системный диск практически «забился» под завязку, а штатные чистилки мусора не помогали — свободного места оставалось критически мало. Оказалось, что куча старых файлов обновлений, временных логов и упаковок пакетов Windows Update съели не меньше 20 ГБ! 🔥 Чтобы оперативно и централизованно освободить место на C:, я использовал PowerShell-скрипт для сброса компонентов Windows Update и удаления временных файлов.

# 1. Остановим службы обновлений
Write-Host "Останавливаю службы Windows Update..." -ForegroundColor Cyan
Stop-Service -Name wuauserv -Force
Stop-Service -Name bits -Force
Stop-Service -Name cryptsvc -Force

# 2. Переименуем папки SoftwareDistribution и Catroot2 (чтобы сбросить кеш)
$sd = "C:\Windows\SoftwareDistribution"
$cr2 = "C:\Windows\System32\catroot2"
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
Write-Host "Переименовываю SoftwareDistribution и Catroot2..." -ForegroundColor Cyan
Rename-Item -Path $sd -NewName "SoftwareDistribution_$timestamp" -Force
Rename-Item -Path $cr2 -NewName "catroot2_$timestamp" -Force

# 3. Запустим службы обратно
Write-Host "Запускаю службы Windows Update..." -ForegroundColor Cyan
Start-Service -Name wuauserv
Start-Service -Name bits
Start-Service -Name cryptsvc

# 4. Удаляем временные файлы пользователя и систему temp
Write-Host "Удаляю временные файлы..." -ForegroundColor Cyan
Get-ChildItem "C:\Windows\Temp" -Recurse -Force | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
Get-ChildItem "$env:TEMP" -Recurse -Force | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue

# 5. Очищаем папку Prefetch (если нужно)
Write-Host "Очищаю Prefetch (опционально)..." -ForegroundColor Cyan
Get-ChildItem "C:\Windows\Prefetch" -Recurse -Force | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue

# 6. Запускаем анализ и дефрагментацию (для HDD/SDD команда отличается)
Write-Host "Запускаю оптимизацию диска (для HDD)..." -ForegroundColor Cyan
Optimize-Volume -DriveLetter C -ReTrim -Verbose

Write-Host "Готово! Освобождено место и сброшен кеш Windows Update." -ForegroundColor Green
🔍 Что делает скрипт: 1. Останавливает службы wuauserv, bits и cryptsvc, чтобы освободить доступ к файлам обновлений. 2. Переименовывает папки SoftwareDistribution и catroot2 — таким образом Windows создаёт новые «чистые» папки при следующем запуске службы обновлений. 3. Перезапускает службы, чтобы система могла продолжить получать обновления. 4. Удаляет старые временные файлы из C:\Windows\Temp и из переменной %TEMP% текущего пользователя. 5. (Опционально) Очищает папку Prefetch — пригодится, если вы хотите сбросить предзагрузку приложений (иногда помогает ускорить старт служб). 6. Запускает командлет Optimize-Volume с параметром –ReTrim (важно для SSD, если нужно, или дефрагментацию для HDD), что в итоге дополнительно освобождает свободное пространство и приводит метаданные диска в порядок. 💡 Лайфхак: * Если вы работаете со множеством серверов, оберните этот скрипт в экспорт модуля или сохраните в виде .ps1, а затем запускайте его через Scheduled Task по расписанию раз в неделю/месяц. * Можно добавить проверку свободного места перед выполнением очистки, чтобы скрипт запускался, только когда доступно меньше, скажем, 10 ГБ:

  $freeGB = [math]::Round((Get-PSDrive -Name C).Free / 1GB, 2)
  if ($freeGB -lt 10) {
      # выполняем очистку
  } else {
      Write-Host "Достаточно места — пропускаю действия."
  }
  
* Не забывайте тестировать на тестовых окружениях перед тем, как развертывать на продакшне. 💬 А как вы решаете проблему нехватки места на C:? Используете ли свои скрипты или предпочитаете готовые инструменты вроде CCleaner, TreeSize, WinDirStat, а может, связку PowerShell + SCCM/MDT? Делитесь в комментах своими рецептами! 👉 @win_sysadmin

👋 Привет, админы! Сегодня расскажу про полезный трюк для тех, кто автоматизирует установку софта через PowerShell. Недавно столкнулся с задачей: массово обновить VLC на нескольких десятках машин. Обычные MSI-пакеты — это круто, но что делать с .exe-инсталляторами, у которых свои ключи для тихой установки? 🔥 Вот лайфхак — используем PowerShell и Start-Process с нужными аргументами:

Start-Process -FilePath "vlc-setup.exe" -ArgumentList "/S" -Wait
* /S — стандартный ключ для тихой установки (silent install). * -Wait — PowerShell дождётся завершения установки. * Можно запускать это в цикле по списку машин через Invoke-Command или PsExec. 💡 А какой софт чаще всего автоматизируете на своём парке машин? Есть любимые утилиты или хитрые ключи для silent-установки? Поделитесь опытом — уверен, найдётся немало интересных решений! 👉 @win_sysadmin

👋 Привет, админы! Недавно столкнулся с задачей — нужно было массово поменять пароли локальных администраторов на паре десятков серверов. Ручками это делать — тот ещё ад, да и не очень безопасно. Решил автоматизировать процесс через PowerShell. 🔥 Вот скрипт, который меня выручил:

$servers = @("Server01", "Server02", "Server03") # список серверов
$newPass = ConvertTo-SecureString "Новый_Сложный_Пароль!" -AsPlainText -Force

foreach ($srv in $servers) {
    Invoke-Command -ComputerName $srv -ScriptBlock {
        param($pass)
        $user = [ADSI]"WinNT://./Administrator,User"
        $user.SetPassword($pass)
    } -ArgumentList $newPass
}
⚡️ Важно: убедись, что у тебя есть права на все машины и открыт WinRM! Итог — все админы с новыми паролями, никаких лишних телодвижений. Если хочется более гибко — можно расширить скрипт, добавить логирование или рандомизацию паролей. 💬 А у тебя были кейсы массовой смены паролей? Как автоматизируешь такие вещи? Делись опытом! 👉 @win_sysadmin

Системный Администратор Windows - آمار و تحلیل کانال تلگرام @win_sysadmin