Скрипт інвентаризації парку перед переходом на Windows 11

Знімає з комп’ютера версію системи (за номером збірки, а не за назвою в реєстрі — вона бреше), процесор, пам’ять, диск, прошивку, TPM і Secure Boot. Ставить вердикт і дописує рядок у спільний CSV, який відкривається в Excel. Перевірений на Windows 11 Pro 26200.

Скрипт

Нічого не змінює — тільки читає і пише рядок у ваш CSV.

Get-Win11Readiness.ps1
# Інвентаризація парку перед міграцією на Windows 11.
# Збирає з комп’ютера все, що потрібно для рішення «оновлювати / міняти / ESU»
# і дописує рядок у спільний CSV.
#
# Запуск на одному комп’ютері:
#   .\Get-Win11Readiness.ps1
# Запуск із записом у мережеву теку (наприклад, зі скрипта входу):
#   .\Get-Win11Readiness.ps1 -CsvPath "\\SERVER\inv\win11-readiness.csv"
#
# ВАЖЛИВО: TPM і Secure Boot читаються тільки з правами адміністратора.
# Без них скрипт напише «потрібні права», а не «немає» — це різні речі.

param(
    [string] $CsvPath
)

$ErrorActionPreference = 'SilentlyContinue'

# --- Версія Windows -----------------------------------------------------
# ProductName в реєстрі не оновлювали: на Windows 11 він досі каже
# «Windows 10 Pro». Єдиний надійний спосіб — номер збірки: 22000 і вище
# це Windows 11.
$cv = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'
$build = [int]$cv.CurrentBuild
$osName = if ($build -ge 22000) { 'Windows 11' } else { 'Windows 10' }
$edition = ($cv.EditionID)
$display = $cv.DisplayVersion

# --- Залізо -------------------------------------------------------------
$cs   = Get-CimInstance Win32_ComputerSystem
$cpu  = Get-CimInstance Win32_Processor | Select-Object -First 1
$disk = Get-Disk | Where-Object { $_.IsSystem } | Select-Object -First 1
if (-not $disk) { $disk = Get-Disk | Select-Object -First 1 }
$sysVol = Get-Volume -DriveLetter ($env:SystemDrive.TrimEnd(':'))

$ramGb   = [math]::Round($cs.TotalPhysicalMemory / 1GB, 1)
$diskGb  = [math]::Round($sysVol.Size / 1GB)
$freeGb  = [math]::Round($sysVol.SizeRemaining / 1GB)
$uefi    = ($env:firmware_type -eq 'UEFI')
$gpt     = ($disk.PartitionStyle -eq 'GPT')

# --- TPM ----------------------------------------------------------------
$tpmVer = 'потрібні права адміністратора'
$tpmOk  = $null
$tpm = Get-CimInstance -Namespace 'root\CIMV2\Security\MicrosoftTpm' -ClassName Win32_Tpm
if ($tpm) {
    # SpecVersion виглядає як "2.0, 0, 1.38" — беремо перше число
    $tpmVer = ($tpm.SpecVersion -split ',')[0].Trim()
    $tpmOk  = ($tpmVer -like '2.*') -and $tpm.IsEnabled_InitialValue
}

# --- Secure Boot --------------------------------------------------------
$sbState = 'потрібні права адміністратора'
$sbOk = $null
try {
    $sb = Confirm-SecureBootUEFI -ErrorAction Stop
    $sbState = [string]$sb
    $sbOk = $sb
} catch { }

# --- Вердикт ------------------------------------------------------------
$blockers = @()
if ($build -lt 22000) {
    if ($ramGb -lt 4)                { $blockers += 'мало ОЗП' }
    if ($diskGb -lt 64)              { $blockers += 'малий диск' }
    if ($cpu.NumberOfCores -lt 2)    { $blockers += 'менше 2 ядер' }
    if ($cpu.MaxClockSpeed -lt 1000) { $blockers += 'частота нижче 1 ГГц' }
    if ($cpu.AddressWidth -ne 64)    { $blockers += 'не 64-розрядний' }
    if (-not $uefi)                  { $blockers += 'не UEFI' }
    if (-not $gpt)                   { $blockers += 'диск не GPT' }
    if ($tpmOk -eq $false)           { $blockers += 'TPM не 2.0 або вимкнений' }
    if ($sbOk -eq $false)            { $blockers += 'Secure Boot вимкнений' }
}

$verdict =
    if ($build -ge 22000) { 'вже Windows 11' }
    elseif ($blockers.Count -eq 0 -and $tpmOk -and $sbOk) { 'готовий до оновлення' }
    elseif ($blockers.Count -eq 0) { 'схоже готовий (TPM/Secure Boot не перевірені)' }
    else { 'потребує рішення' }

$row = [pscustomobject]@{
    Компютер      = $env:COMPUTERNAME
    Користувач    = $env:USERNAME
    ОС            = "$osName $edition $display"
    Збірка        = "$($cv.CurrentBuild).$($cv.UBR)"
    Процесор      = $cpu.Name.Trim()
    Ядер          = $cpu.NumberOfCores
    ЧастотаМГц    = $cpu.MaxClockSpeed
    ОЗП_ГБ        = $ramGb
    Диск_ГБ       = $diskGb
    Вільно_ГБ     = $freeGb
    Прошивка      = $env:firmware_type
    РозміткаДиска = $disk.PartitionStyle
    TPM           = $tpmVer
    SecureBoot    = $sbState
    Вердикт       = $verdict
    Причини       = ($blockers -join '; ')
    Дата          = (Get-Date -Format 'yyyy-MM-dd HH:mm')
}

$row | Format-List

if ($CsvPath) {
    $dir = Split-Path $CsvPath -Parent
    if ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
    # Append: кожен комп’ютер дописує свій рядок у спільний файл.
    # UTF8 з BOM — інакше Excel відкриє кирилицю як абракадабру.
    $exists = Test-Path $CsvPath
    $row | Export-Csv -Path $CsvPath -NoTypeInformation -Encoding UTF8 -Append:$exists
    Write-Host "Записано у $CsvPath" -ForegroundColor Green
}

Як запустити на весь парк

Три способи, від найпростішого.

СпосібЯкКоли підходить
Вручну .\Get-Win11Readiness.ps1 -CsvPath "\SERVER\inv\win11.csv" до 15 комп’ютерів або коли треба швидко перевірити конкретну машину
Скрипт входу покласти файл у спільну теку й додати виклик у логон-скрипт користувача парк без домену: дані назбираються самі протягом тижня
Віддалено Invoke-Command -ComputerName PC1,PC2 -FilePath .\Get-Win11Readiness.ps1 є домен і налаштований WinRM; тоді TPM і Secure Boot зчитаються повністю
Тека для CSV має бути доступна на запис усім, хто запускає скрипт. Кожен комп’ютер дописує свій рядок — файл не перезаписується.

Три речі, на яких спотикаються

Зберігайте файл у UTF-8 з BOM. Windows PowerShell 5.1 читає .ps1 без BOM як ANSI, і скрипт з українськими коментарями не запуститься. У VS Code це «UTF-8 with BOM» у нижньому правому куті.
TPM і Secure Boot видно тільки адміністратору. Запущена звичайним користувачем, Get-Tpm не видає помилку — вона повертає порожні поля, і скрипт легко прийняв би це за «TPM немає». Тому в CSV пишеться саме «потрібні права адміністратора», а не «немає».
Не визначайте версію Windows за назвою. Ключ ProductName на Windows 11 досі повідомляє «Windows 10 Pro». Надійна ознака — номер збірки: 22000 і вище означає Windows 11.