Как же определить версию Windows, работающую в корпоративном окружении?

Вопрос кажется простым, правда?

Microsoft позволяет определить номер версии Windows различными способами:

  • Существуют значения в реестре, которым отчаянно не хватает документации.
  • Есть множество командлетов PowerShell, вызовов Windows API и т. п.
  • Также есть варианты для конечного пользователя, например, команда winver, которая вызывает всплывающее окно с версией Windows.
  • И много других способов…

Разобраться во всём этом вам поможет наш пост.
Существует множество инструментов, позволяющих определить, какая версия Windows запущена у ваших клиентов, например, SCCM и PDQ. В этом посте мы рассмотрим встроенные способы определения версии Windows.

▍ Реестр


Для определения запущенной в системе версии Windows можно использовать следующие значения реестра:

Ключ Значение Пример данных Объяснение
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion ReleaseId 2009 Целочисленное значение версии (в виде строки). Добавлено в версии 1803, начиная с версии 21H1 не рекомендуется к использованию
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion DisplayVersion 20H2 Кодовое имя версии в формате строки с цифровыми значениями. Добавлено в версии 1803.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion CurrentBuild 19042 Номер сборки версии, используемый программой winver.exe.
Примечание: перечисленные в таблице значения официально не задокументированы Microsoft (см. ниже).

Предупреждение


Microsoft не сообщала об изменениях в этих значениях реестра, не документировала их официальную поддержку и не гарантировала, что в будущем не появится критических изменений. Из-за этого описанными выше ключами реестра пользоваться бывает иногда неудобно, учитывая непостоянство изменений этих ключей, вносимых Microsoft в прошлом. Примеры:

  • ReleaseID не рекомендуется к использованию, начиная с версии 21H1. ReleaseID для 21H1 остаётся равным 2009.
  • Server 2012R2 не имеет ReleaseID и DisplayVersion (они пока не были добавлены в Windows)
  • Server 2016 имеет ReleaseID (1607), но не имеет DisplayVersion
  • Server 2019 имеет ReleaseID (1809), но не имеет DisplayVersion

▍ PowerShell


Ниже приведено несколько примеров того, как можно использовать PowerShell, чтобы определить версию Windows, которая работает в системе:

# При помощи класса System.Environment
[System.Environment]::OSVersion

# При помощи класса CIM Win32_OperatingSystem
Get-CimInstance Win32_OperatingSystem

# При помощи исполняемого файла systeminfo
systeminfo.exe /fo csv | ConvertFrom-Csv

# При помощи командлета Get-ComputerInfo
# ПРИМЕЧАНИЕ: начиная с 21H1 OsHardwareAbstractionLayer не рекомендуется к использованию
Get-ComputerInfo | Select WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer

▍ Windows API Call


Единственный поддерживаемый (задокументированный) систематический способ определения версии Windows — при помощи вызова Windows API класса AnalyticsInfo. Это можно сделать через PowerShell:

<#
    Класс AnalyticsInfo - задокументированный способ отслеживания версии ОС. Он возвращает
    строковое значение. Формат этой строки не задокументирован, и нельзя полагаться
    на определённое значение. Эти значения можно использовать только чтобы отличать
    одну версию ОС от другой.
    https://docs.microsoft.com/uwp/api
        /windows.system.profile.analyticsversioninfo.devicefamilyversion
    Этот API недоступен на Server Core
#>

$AnalyticsInfo = [Windows.System.Profile.AnalyticsInfo,Windows.System.Profile,ContentType=WindowsRuntime]
$VersionInfo = $AnalyticsInfo.GetMember( 'get_VersionInfo' )
$AnalyticsVersionInfo = $VersionInfo.Invoke( $Null, $Null )

# На моей тестовой машине этот код возвращает `2814751015109593`
$AnalyticsVersionInfo.DeviceFamilyVersion

<#
    Строго говоря, строку *можно* парсить, если вам любопытно, что в ней,
    хотя этого делать *нельзя*
    https://stackoverflow.com/questions/31783604/windows-10-get-devicefamilyversion
#>

$v  = [System.Int64]::Parse( $AnalyticsVersionInfo.DeviceFamilyVersion )
$v1 = ( $v -band 0xFFFF000000000000l ) -shr 48
$v2 = ( $v -band 0x0000FFFF00000000l ) -shr 32
$v3 = ( $v -band 0x00000000FFFF0000l ) -shr 16
$v4 =   $v -band 0x000000000000FFFFl

# На моей тестовой машине этот код возвращает `10.0.19043.985`
[System.Version]::Parse( "$v1.$v2.$v3.$v4" )

<#
    Не опубликовано *никакого* способа декодирования, позволяющего преобразовать
    какое-то из приведённых выше значений в удобную для отображения версию,
    например `21H1`
    Показанная ниже альтернатива доступна только в последних версиях ОС, 
    начиная с Azure Stack HCI, версии 20H2
#>

Get-ComputerInfo -Property 'osDisplayVersion'

▍ Варианты для конечного пользователя


В документации Microsoft перечислено несколько команд, которые конечные пользователи могут применять для определения запущенной версии Windows. Например, чтобы выяснить версию Windows, можно использовать команду winver или меню Параметров Windows. Эти способы предназначаются больше для конечных пользователей, чем для масштабного определения версии системы. Ниже показаны примеры:



▍ Почему это важно


После определения запущенной в системе версии Windows можно использовать эту информацию выполнения детерминированных действий: обновлений Windows, установки патчей и т. п. Например:

Можно запросить значение реестра DisplayVersion (см. раздел «Реестр» выше), чтобы определить запущенную версию Windows. Затем можно задать перечисленные ниже значения реестра, чтобы сообщить Windows, какая версия должна быть запущена в системе. При помощи трёх ключей реестра вы полностью контролируете то, до какой версии Windows ваши системы будут пытаться обновиться!

Ключ Значение Пример данных Объяснение
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate TargetReleaseVersion 1 Если присвоить единицу, то это включает Feature Upgrades до версии TargetReleaseVersionInfo
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate TargetReleaseVersionInfo 20H2 Целевая версия системы
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate ProductVersion Windows 10 Новый ключ Windows 11 — имеет значение или «Windows 10», или «Windows 11»

Эти значения реестра можно задавать или напрямую, или через групповую политику.

▍ Куда двигаться дальше


Хотя вам необязательно управлять версиями Windows, запущенными на компьютерах компании, ей было бы ценно знать, какие это версии Windows. По крайней мере, потому, что Microsoft регулярно прекращает поддержку разных версий Windows.

Стоит также заметить, что показанные выше примеры — это неполный список способов определения версии Windows, однако он полезен для людей, управляющих окружением Windows. Эти способы оказались полезными для меня при устранении проблем, задании политик и т. п. Надеюсь, вам они тоже пригодятся.

Кроме того, ситуация с управлением версиями Windows постоянно меняется, поэтому я напишу ещё один пост, когда Microsoft перестанет рекомендовать перечисленные здесь способы.

Дополнительные ссылки



Комментарии (15)


  1. gdt
    20.06.2022 16:18
    +2

    Если мне не изменяет память - единственный более-менее надёжный способ - это детектить и проверять build number, т. к. есть ситуации, в которых запрос версии из приложения может вернуть более старую версию (например, если в манифесте не указаны поддерживаемые версии ОС).


  1. Javian
    20.06.2022 16:38
    +1

    По-моему такого разнообразия версий как в ХР больше никогда не было.


  1. Neom1an
    20.06.2022 17:00
    +15

    Спросить у пользователя: "какой формы и цвета кнопка " Пуск""?


    1. Komrus
      20.06.2022 17:16
      +9

      И через пол-дня мучений ВНЕЗАПНО выяснить, что пару лет назад кто-то поставил на комп с Win10 "Classic Shell" с настройками под Win-XP :)))


    1. IL_Agent
      20.06.2022 17:19
      +1

      Можно начать с её расположения)


  1. iig
    20.06.2022 18:53

    в корпоративном окружении

    Корпоративное окружение - Active Directory - Get-ADComputer: Find Computer Details in Active Directory with PowerShell


  1. RumataEstora
    20.06.2022 19:08

    Еще ссылка в копилку:

    https://www.lifewire.com/windows-version-numbers-2625171


  1. cartonworld
    20.06.2022 20:14
    +2

    Также есть варианты для конечного пользователя, например, команда winver, которая вызывает всплывающее окно с версией Windows

    Ещё есть ver, которая в Windows 11, например, выводит "Microsoft Windows [Version 10.0.22000.739]" (а [System.Environment]::OSVersion -- 10.0.22000.0)


    1. infund
      20.06.2022 21:50
      +3

      ver был ещё во времена DOS


  1. Nipheris
    20.06.2022 20:22
    +1

    Добавлю ещё про ключик Update Build Revision: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UBR . Оттуда как раз можно получить второе число из OS Build, которое как раз и выдаётся командой ver. Это же число видно и в окне System > About в панели управления.


  1. unwrecker
    20.06.2022 20:40
    +10

    Ну и классика :)


  1. R7R
    20.06.2022 21:52

    Как же определить версию Windows, работающую в корпоративном окружении?


    Стоит только добавить «через демонстрацию в Zoom и работающей в руках 17-летней вчерашней школьницы, далекой от ИТ» — как этот вопрос станет намного интереснее :)


  1. artemisia_borealis
    21.06.2022 11:23

    dxdiag.exe же ещё есть, почему-то про него забыли.
    Можно и без cmd/far/powershell запустить, а и через Start→Run, что важно для большинства «активных» пользователей ПК.
    А вот ver, например, так не запустить.


  1. Aleator13
    21.06.2022 11:58

    Всегда пользовался командой systeminfo )

    win+r/cmd/systeminfo


  1. maxwolf
    21.06.2022 15:04
    +1

    Не вполне понял извращение с «systeminfo.exe /fo csv | ConvertFrom-Csv». Зачем заказывать вывод в csv и потом его конвертировать в читабельный вид, если systeminfo без параметров и так всё показывает в читабельном виде (и версию виндов и, кстати, список накаченных hotfix'ов?

    P.S. Кстати, поделитесь, если у кого есть рабочий алгоритм накатывания апдейтов безопасности на «старые венды». Т.е. как на условную 10.0.10240 поставить все актуальные на июнь 2022 security патчи, но не ставить feature updates?