Вспоминаем Powershell в нескольких частях. Часть 1. База из баз
Для ЛЛ: серия пометок по костылям
Конечная цель серии постов: написать свой очень маленький и очень кривой WSUS, поскольку развития WSUS больше не предвидится, но я про это писал:
Чего лишаемся в 2025 году внутри Microsoft
Часть 1. База из баз. Теория
Часть 1.1 Зачем ставить обновления на Linux и Windows и куда угодно, если в отделе работают проверенные электроником сотрудники, и все работает?
Часть 1.2 Чем плох WSUS, SCOM, прочее ПО, и факты в Ansible?
Часть 1.3 Почему Powershell, а не Python?
Часть 1.4 Прочие базовые вещи
Часть 1.5 Классы и объекты, для тех, кто пропускал школу
Часть 1.6 К теме обновлений в Windows
Часть 1.7 Как это все хранить и обрабатывать?
Часть 1.8 Давайте начинать. Мой первый класс
Часть 1.9 Немного магии, не очевидной с первого раза
Часть 1.10 Мой первый массив
Часть 1.11 Суй массив в файл. И забирай из файла
Часть 1.12 Теперь все вместе
Часть 1. База из баз. Теория
Часть 1.1 Зачем ставить обновления на Linux и Windows и куда угодно, если в отделе работают проверенные электроником сотрудники, и все работает?
Когда-то, на заре времен, выхода «второго сервис пака» просто ждали.
Windows XP вышел 25 октября 2001 и был сырым, совсем сырым.
Windows XP SP 2 вышел 6 августа 2004 года, и сделал XP популярным и рабочим на следующие лет 10. Это не считая Embedded версий, которые работали и работают и работают.
Поэтому 20 лет назад установка обновлений шла не от того, что «все работает», а от ожидания «сейчас вот это исправят, потом вон то».
Поэтому исторически тем, кто с системами давно плотно работает, вопрос «зачем» не понятен, очевидно же.
Классика последние 200 лет – не пейте из козьего копытца, не пейте из бутылочки с надписью яд -
for she had read several nice little stories about children who got burnt, and eaten up by wild beasts, and other unpleasant things, all because they would not remember the simple rules their friends had taught them: such as, that a red-hot poker will burn you if you hold it too long; and that, if you cut your finger very deeply with a knife, it usually bleeds; and she had never forgotten that, if you drink much from a bottle marked "poison," it is almost certain to disagree with you, sooner or later.”
Между тем, была и есть и другая тенденция в ИТ среде – не делать, что говорит производитель, а ждать, пока сломается, и потом делать вид, что работаешь.
Ничего не трогать, как писал другой автор –
Не выходи из комнаты, не совершай ошибку.
Зачем тебе Солнце, если ты куришь Шипку?
За дверью бессмысленно всё, особенно — возглас счастья.
Только в уборную — и сразу же возвращайся.
Эта же ситуация, с бедой с башкой, есть не только в ИТ.
Производитель говорит «меняйте масло каждые 10.000» - давайте ездить 15.000, я лучше знаю.
Производитель говорит «ставьте зимнюю резину до снега» - нет, каждый год на лысой летней резине кто-то застрянет на эстакадах и в кого то въедет.
Производитель говорит «меняйте ремень вариатора каждые 10.000» - нет, будут ездить до того момента, пока ремень не порвется.
Висят знаки «100» - давайте ездить 120.
Сказано «детям нельзя по дорогам общего пользования на спорт инвентаре» - ачотакова.
Беда с башкой «а чо такова» и «такого со мной не произойдет» - явление постоянное и международное. Например, на днях признали, что на пике Победы теперь есть плюс один памятник. На Маттерхорне такого тоже хватает.
Что же касается проверенных электроником сотрудников, то это работает исключительно в том случае, если у организации:
1 Организован закрытый контур управления системами, где физически, air gap, отключен интернет,
2 Фирма настолько маленькая, что через air gap никто не захочет перепрыгнуть. Потому что есть вирусы, сложным путем обходящие такие защиты. Например, Stuxnet.
3 Не смотря на это, в системе установлены обновления для средств контейнеризации и виртуализации, и сами средства корректно настроены. Потому что для Linux было несколько средств выхода в операционную систему хоста из виртуальной машины - Red Hat: CVE-2024-32462: flatpak: sandbox escape, Linux kernel vulnerability-CVE-2025–38236, CVE-2025-4609: Critical Sandbox Escape и так далее. К этому добавляется GhostHook и прочие неприятности.
Часть 1.2 Чем плох WSUS, SCOM, прочее ПО, и факты в Ansible?
WSUS ничем не плох, но в нем очень, для меня, неудобная отчетность. Отчетность показывает, что проблемы есть, но не показывает в удобном для меня разрезе, что установлено и почему, в том числе по остальным компонентам.
Со SCOM и прочим ПО для инвентаризации всплыла у коллег интересная проблема. Некоторое ПО (их внутренняя разработка) не вносит изменения в реестр Windows, поэтому не понятно, что обновилось, что нет. Остается смотреть версию файла, но WSUS не умеет отслеживать такие изменения, а на SCOM у них денег нет. Поскольку дело было в Windows, то пришлось идти другим путем.
Факты в Ansible всем хороши, кроме того что этот факт надо интерпретировать, и иметь какую-то базу для сверки и хранения эталонов.
Часть 1.3 Почему PowerShell, а не Python?
Особой разницы нет, но механизм другой. Я могу сделать задачу, которая выполнится на удаленном сервере, но даже для двух серверов это будет 1) удаленная 2) асинхронная задача. Это не самый удобный вариант, обрабатывать асинхронные данные на коленке, без разворачивания базы данных. Можно и на Python, просто чуть больше возни с компиляцией, подписыванием кода, и асинхронным получением данных в базу, и обработкой из базы. Все это сделать можно без проблем, но для начинающих проще, под Windows, сделать задачу на Powershell, без дополнительных компонентов.
То есть мне не надо для Powershell ставить VScode, Python, auto-py-to-exe, и убеждать параноящий антивирус «внести вот это в исключения». И сильно меньше рисков, что exe что-то сломает. И в отладке чуть проще.
Под Linux я бы вообще на RUST писал, не на Python.
Часть 1.4 Прочие базовые вещи
Я буду считать, что вы:
Прочитали хотя бы:
Школьный курс информатики – где рассказывают про типы данных и циклы
А.В.Попов. Введение в Windows PowerShell
А.В.Попов. Современный PowerShell. 2-е издание. - СПб.: БХВ-Петербург, 2025.
и парочку статей по теме – что такое командлеты, ввод-вывод и так далее.
Точно так же я буду считать, что вы как минимум запустили Powershell ISE.
Powershell ISE к сожалению не умеет работать с Git напрямую, как VScode с модулями, но можно поставить и сам Git, или можно жить (но грустно) без него, или жить по старинке с SVN.
Часть 1.5 Классы и объекты, для тех, кто пропускал школу
Даже 30 лет назад, даже Borland Turbo Pascal не говоря про Object Pascal, поддерживал не только Units, то есть внешние библиотеки, но и объекты, классы, и вот это все. С 1989, версии 5.5.
Все это было, в том числе в VBS, есть и в PowerShell
Нет никаких проблем (кроме того, что будет много букв) вызывать из PowerShell и методы Windows API, то есть графический интерфейс, и методы из Dotnet, и работать с внешними библиотеками, и обрабатывать ошибки и исключения.
Есть одно, лично мое исключение. Если вы работаете с web, и вам надо что-то обработать в Chrome или Firefox, то берите сразу Selenium. Он простой, куда проще, чем возиться с Powershell и Edge.
Часть 1.6 К теме обновлений в Windows
Что такое обновление с точки зрения статистики и "мне только посмотреть? "
Например, 2025-08 Cumulative Update for Microsoft server operating system version 24H2 for x64-based Systems (KB5063878) (26100.4946) ?
Это объект, у которого есть свойства:
Для какого продукта он предназначен: Microsoft Server Operating System
Для какой версии продукта он предназначен: 24H2 (это Windows server 2025)
Критичность: Microsoft Security Response Center (MSRC) severity: Critical
Номер: KB article numbers: 5063878
Дата выхода: 8/12/2025 (формат даты США, месяц/день/год, то есть 12 августа 2025. Это у них легаси такое, с времен церковно-учетных книг)
Язык: в данном случае не важен.
Почему продукт и версия разнесены? Потому что, и в дальнейшем это будет критично, у Microsoft с обновлениями dotnet случилась беда с версионностью. В итоге и для определения версии есть отдельная процедура, и обновления бывают для отдельных компонентов.
Нормально это унифицировали только где-то к выходу Windows Server 2022
Часть 1.7 Как это все хранить и обрабатывать?
Можно в виде битовой строки, где символы с 0 по 20 это продукт, с 20 по 40 это версия, итд.
Можно какими-то еще путями, для ускорения или компактности.
Можно сразу рисовать схему базы данных.
Или можно сделать класс с разными типами данных внутри класса, и создавать на основе этого класса – объекты, и массивы объектов, и много чего еще.
Плюсы? Легко расширять, легко просматривать. Легко хранить в виде xml
Низкий порог вхождения, если говорить простыми словами.
Часть 1.8 Давайте начинать. Мой первый класс
Пуск – выполнить - powershell ise, и вот он – стандартный интерфейс, недалеко ушедший от блокнота
Делаем File – save as - Meine erste Klasse, делаем пример, выполняем –
class Device {
[string]$Brand
}
$dev = [Device]::new()
$dev.Brand = "Fabrikam, Inc."
$dev
И оно работает!
Делаем пример, какой нам нужен
Class MeineErsteKlasse{
[string]$OS
[string]$Release
[string]$KB
[string]$KBDate}<#Для какого продукта он предназначен: Microsoft Server Operating System
Для какой версии продукта он предназначен: 24H2 (это Windows server 2025)
Номер: KB article numbers: 5063878
Дата выхода: 8/12/2025 #>$MeinErstklassigesBeispiel =[MeineErsteKlasse]::new()
$MeinErstklassigesBeispiel.OS = "Server"
$MeinErstklassigesBeispiel.Release = "24H2"
$MeinErstklassigesBeispiel.KB = "KB5063878"
$MeinErstklassigesBeispiel.KBDate = "12.08.2025"$MeinErstklassigesBeispiel | Format-Table -AutoSize
Запускаем – работает.
Часть 1.9 Немного магии, не очевидной с первого раза
Когда мы не работает со скриптом интерактивно, когда он будет исполняться неизвестно где и неизвестно как, имеет смысл хранить «нужные для работы данные» где-то рядом.
Для этого в Powershell есть переменная $PSScriptRoot, отдающая объект типа строка, то есть «откуда скрипт запустился» и командлет Get-Location, который выдает объект с кучей других свойств.
Посмотрим:
$PSScriptRoot | Get-Member
Get-Location| Get-Member
$Data1 = Get-Location
$Data1.Path
Все наглядно.
Заведем переменную «где храним скрипты» и переменную версии, просто так чтобы была (не просто так)
$PfadZurSpeicherdatenbank = $PSScriptRoot
$Skriptversion = "10"
$MeineErsteSicherungsdatei = $PfadZurSpeicherdatenbank + "\" + "nur-eine-datei.xml"
Часть 1.10 Мой первый массив
Сделаем массив. Не массив конечно, в Powershell массивы это или хеш-таблицы (@{}), или кастомные объекты, типа [PSCustomObject]@{
или System.Collections.ArrayList
создается, например, так: $myArrayList = New-Object System.Collections.ArrayList
Или вариации на тему. Почему так? Потому что массив (array) в общем смысле, это объект фиксированного размера, и операция его расширения, если вы работаете с действительно большим объемом данных, это операции «создаем новый массив размером плюс 1, копируем туда старый массив, удаляем старый массив». Это дорогие операции, когда у вас миллионы объектов размерами хотя бы пара мегабайт.
Когда у вас скрипт уровня «я еще учусь» это не влияет значимо на скорость, но помнить и знать это нужно, чтобы потом не думать «ой, почему все так тормозит».
$keinArray = @()
$keinArray += $MeinErstklassigesBeispiel
#Старая переменная больше нам не нужна, удалим ее
Remove-Variable MeinErstklassigesBeispiel
Важный момент. Powershell для экономии использует всякие извращения с Mutable и будьте аккуратны с этим, потому что вот такое поведение с непривычки вызывает оторопь:
$Data1 = @(1,2,3,4)
$Data2 = $Data1
$Data1[2] = "N"
$Data2
Часть 1.11 Суй массив в файл. И забирай из файла
Export-Clixml -Path $MeineErsteSicherungsdatei -InputObject $KeinArray
notepad $MeineErsteSicherungsdatei
$NewKeinArray = Import-Clixml -Path $MeineErsteSicherungsdatei
$NewKeinArray
Поздравляю, вы великолепны.
Часть 1.12 Теперь все вместе
Class MeineErsteKlasse{
[string]$OS
[string]$Release
[string]$KB
[string]$KBDate}<#Для какого продукта он предназначен: Microsoft Server Operating System
Для какой версии продукта он предназначен: 24H2 (это Windows server 2025)
Номер: KB article numbers: 5063878
Дата выхода: 8/12/2025 #>$MeinErstklassigesBeispiel =[MeineErsteKlasse]::new()
$MeinErstklassigesBeispiel.OS = "Server"
$MeinErstklassigesBeispiel.Release = "24H2"
$MeinErstklassigesBeispiel.KB = "KB5063878"
$MeinErstklassigesBeispiel.KBDate = "12.08.2025"$MeinErstklassigesBeispiel | Format-Table -AutoSize
$PfadZurSpeicherdatenbank = $PSScriptRoot
$Skriptversion = "10"
$MeineErsteSicherungsdatei = $PfadZurSpeicherdatenbank + "\" + "nur-eine-datei.xml"$KeinArray = @()
$KeinArray += $MeinErstklassigesBeispiel
Remove-Variable MeinErstklassigesBeispielExport-Clixml -Path $MeineErsteSicherungsdatei -InputObject $KeinArray
notepad $MeineErsteSicherungsdatei
$NewKeinArray = Import-Clixml -Path $MeineErsteSicherungsdatei
$NewKeinArray
Продолжение следует