Знімає з комп’ютера версію системи (за номером збірки, а не за назвою в реєстрі — вона бреше), процесор, пам’ять, диск, прошивку, TPM і Secure Boot. Ставить вердикт і дописує рядок у спільний CSV, який відкривається в Excel. Перевірений на Windows 11 Pro 26200.
Нічого не змінює — тільки читає і пише рядок у ваш CSV.
# Інвентаризація парку перед міграцією на 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 зчитаються повністю |
Get-Tpm не видає помилку — вона повертає порожні поля, і скрипт
легко прийняв би це за «TPM немає». Тому в CSV пишеться саме
«потрібні права адміністратора», а не «немає».
ProductName
на Windows 11 досі повідомляє «Windows 10 Pro». Надійна ознака — номер збірки:
22000 і вище означає Windows 11.