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

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

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

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

نمایش بیشتر
3 087
مشترکین
-124 ساعت
-67 روز
-830 روز
آرشیو پست ها
👋 Привет, админы! Сегодня расскажу про один неприятный и коварный момент, с которым столкнулся буквально на днях - невозможность запустить скрипт PowerShell из планировщика задач, хотя руками он работает идеально. 🧩 Суть: Есть скрипт .ps1, который делает бэкап и отправляет отчёт по почте. Запускаешь вручную — всё отлично. Но через Task Scheduler - тишина, никакой ошибки, ничего не происходит. 🔍 Что помогло выяснить причину: 1. В Action указывал не сам скрипт, а запуск powershell.exe с аргументами:

   -ExecutionPolicy Bypass -File "C:\Scripts\Backup.ps1"
   
2. Обязательно указал "Start in" (рабочую папку), иначе относительные пути внутри скрипта не работали. 3. Заменил powershell.exe на powershell.exe -NoProfile, чтобы избежать подвисаний из-за пользовательского профиля. 4. В General поставил галочку "Run with highest privileges" - без этого не было доступа к сетевым путям и не выполнялись некоторые команды. 💡В итоге: Task Scheduler штука капризная, особенно с PowerShell. Поэтому всегда логируйте выход скрипта в файл, добавляйте Start-Transcript и Stop-Transcript, и не забывайте про -NoProfile. 📌 Полный пример команды в задаче:

Program/script: powershell.exe  
Add arguments: -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Backup.ps1"  
Start in: C:\Scripts
💬 А у вас бывали такие странности с планировщиком задач? Как отлаживаете такие случаи? 👉 @win_sysadmin

👋 Привет, админы! Попался мне на днях любопытный случай: один из пользователей жаловался, что после входа в систему медленно прогружается рабочий стол, хотя железо бодрое и диск в порядке. 🔍 Начал копать — и довольно быстро нашёл виновника: в автозагрузке сидела куча мусора, но особенно отличился один Group Policy скрипт, который пытался смонтировать сетевой ресурс, которого уже не существует. 📌 Чтобы быстро проверить, какие групповые политики срабатывают при входе, и сколько времени они занимают, запустил на клиенте:

Get-WinEvent -LogName Microsoft-Windows-GroupPolicy/Operational | 
Where-Object { $_.Id -eq 4016 -or $_.Id -eq 5312 } | 
Select-Object TimeCreated, Id, Message | Sort-Object TimeCreated -Descending
🕵️ ID 4016 — начало применения политики, 🕵️ ID 5312 — завершение. Так можно выловить тормоза и даже понять, какой GPO затягивает загрузку. В моем случае один скрипт отрабатывал почти 90 секунд — удалил его, и всё полетело. 💬 А вы анализируете Group Policy лог? Или предпочитаете сторонние утилиты типа PolicyReporter, AGPM и т.п.? Делитесь своим опытом! 👉 @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
👉 @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

👋 Привет, админы! Продолжая тему 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 из виду. Один сбой может стоить кучи нервов. 👉 @win_sysadmin

👋 Привет, админы! 🔥 Делюсь скриптом, который создаёт и настраивает 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, но ты можешь добавлять туда любые параметры: фаервол, автологон, аудит и т.д. 👉 @win_sysadmin

👋 Привет, админы! Сегодня тема, которая не раз спасала мою нервную систему в пятницу вечером, это мгновенное восстановление объектов в Active Directory. Бывало такое: случайно удалили не ту учетку, группу или, не дай бог, целую OU? Лезть в бэкапы (Veeam/WSB) ради одного объекта - это долго, муторно, да и простой для пользователя. Решаем проблему красиво. Суть: Многие забывают, что начиная с Server 2008 R2 в AD есть «Корзина» (AD Recycle Bin), но по умолчанию она выключена! Если она не активна, удаленный объект улетает в небытие (Tombstone), теряя атрибуты и членство в группах. Как проверить и включить: Запускаем PowerShell от админа. Проверяем статус:

Get-ADOptionalFeature -Filter {Name -like "Recycle Bin Feature"} | Select-Object Name, EnabledScopes

Если в EnabledScopes пусто, значит, корзина выключена. Включаем (учтите, действие необратимое, отключить потом нельзя, но оно и не нужно):

Enable-ADOptionalFeature 'Recycle Bin Feature' -Scope ForestOrConfigurationSet -Target 'yourdomain.com'

Как восстановить удаленное: Допустим, снесли пользователя ivanov. Не нужно никаких сторонних утилит, одна строка вернет его со всеми группами и правами:

Get-ADObject -Filter 'Name -like "*ivanov*"' -IncludeDeletedObjects | Restore-ADObject

💡 Совет: В новых версиях Windows Server (2012+) есть GUI для этого в Active Directory Administrative Center, но консоль грузится вечность. PowerShell отрабатывает за секунды. Проверьте прямо сейчас, включена ли у вас корзина, чтобы потом не кусать локти. 🛠️ #activedirectory #powershell #recovery #лайфхак 👉 @win_sysadmin

👋 Привет, админы! Однажды словил интересный баг с 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, всё взлетело без ошибок. 👉 @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 с ежедневным запуском. 👉 @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 %. 👉 @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

erid: 2W5zFHub416 Освойте UserGate и повысьте уровень защиты своей ИТ-инфраструктуры! Бесплатный онлайн-курс поможет вам шаг
erid: 2W5zFHub416 Освойте UserGate и повысьте уровень защиты своей ИТ-инфраструктуры! Бесплатный онлайн-курс поможет вам шаг за шагом освоить внедрение и настройку UserGate — без лишней теории, с упором на практику. В программе курса: ✅ Настройка сетевых зон, NAT, VPN, кластеров, фильтрации на уровне приложений и правил межсетевого экрана ✅ Интеграция с LDAP и Active Directory, фильтрация контента, системы обнаружения вторжений и обратный прокси ✅ Пошаговые видеоуроки, практические упражнения и итоговое тестирование По завершении курса Вы получите: ⭐ именной сертификат 📕 PDF-инструкции 📋 чек-листы и готовые конфигурации, которые помогут в дальнейшей работе Пройдите курс в удобное время — запись уже доступна. Реклама. ООО "ИНФРАТЕХ". ИНН 5024197250.

👋 Привет, админы! Недавно столкнулся с интересным кейсом: один из файловых серверов начал сигнализировать о недостатке свободного пространства. При проверке выяснилось, что причиной стали старые логи 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 раз в сутки, чтобы не «догонять» проблему вручную. 👉 @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 "Достаточно места — пропускаю действия."
  }
  
Не забывайте тестировать на тестовых окружениях перед тем, как развертывать на продакшне. 👉 @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