Время на прочтение
5 мин
Количество просмотров 17K
Как же определить версию Windows, работающую в корпоративном окружении?
Вопрос кажется простым, правда?
Microsoft позволяет определить номер версии Windows различными способами:
- Существуют значения в реестре, которым отчаянно не хватает документации.
- Есть множество командлетов PowerShell, вызовов Windows API и т. п.
- Также есть варианты для конечного пользователя, например, команда
winver
, которая вызывает всплывающее окно с версией Windows. - И много других способов…
Разобраться во всём этом вам поможет наш пост.
Существует множество инструментов, позволяющих определить, какая версия Windows запущена у ваших клиентов, например, SCCM и PDQ. В этом посте мы рассмотрим встроенные способы определения версии Windows.
▍ Реестр
Для определения запущенной в системе версии Windows можно использовать следующие значения реестра:
Примечание: перечисленные в таблице значения официально не задокументированы 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 ваши системы будут пытаться обновиться!
Эти значения реестра можно задавать или напрямую, или через групповую политику.
▍ Куда двигаться дальше
Хотя вам необязательно управлять версиями Windows, запущенными на компьютерах компании, ей было бы ценно знать, какие это версии Windows. По крайней мере, потому, что Microsoft регулярно прекращает поддержку разных версий Windows.
Стоит также заметить, что показанные выше примеры — это неполный список способов определения версии Windows, однако он полезен для людей, управляющих окружением Windows. Эти способы оказались полезными для меня при устранении проблем, задании политик и т. п. Надеюсь, вам они тоже пригодятся.
Кроме того, ситуация с управлением версиями Windows постоянно меняется, поэтому я напишу ещё один пост, когда Microsoft перестанет рекомендовать перечисленные здесь способы.
Дополнительные ссылки
- Microsoft nixes update deferral settings, but gives us a TargetReleaseVersionInfo
- Windows 10 Version History
- Windows Server Versions.
В этой статье мы рассмотрим какие версии PowerShell существуют, в чем отличие Windows PowerShell от PowerShell Core и как узнать, какая версия PowerShell установлена на локальном или удаленных компьютерах.
Содержание:
- История версии PowerShell, PowerShell Core
- Как узнать версию PowerShell из консоли?
- Получаем версию PowerShell на удаленных компьютерах
История версии PowerShell, PowerShell Core
По умолчанию PowerShell устанвлен во всех версиях Windows, начиная с Windows 7 SP1 и Windows Server 2008 R2 SP1. В следующей таблице представлен список актуальных версий PowerShell:
Версия PS | Примечание |
PowerShell 1.0 | Можно было установить вручную в Windows Server 2003 SP1 и Windows XP |
PowerShell 2.0 | Предустановлен в Windows Server 2008 R2 и Windows 7 |
PowerShell 3.0 | Установлен в Windows 8 и Windows Server 2012 |
PowerShell 4.0 | Предустановлен в Windows 8.1 и Windows Server 2012 R2 |
PowerShell 5.0 | Предустановлен в Windows 10 RTM, и автоматически обновляется до 5.1 через Windows Update |
PowerShell 5.1 | Встроен в Windows 10 (начиная с билда 1709) и Windows Server 2016 |
PowerShell Core 6.0 и 6.1 | Следующая кроссплатформенная версия PowerShell (основана на .NET Core), которую можно установить не только во всех поддерживаемых версиях Windows, но и в MacOS, CentOS, RHEL, Debian, Ubuntu, openSUSE |
PowerShell Core 7.0 | Самая последняя версия PowerShell, вышедшая в марте 2020 (в новом релизе выполнен переход с .NET Core 2.x на 3.1) |
Вы можете вручную установить более новую версию PowerShell в предыдущих версиях Windows. Для этого нужно скачать и установить соответствующую версию Windows Management Framework (PowerShell входит в его состав).
Стоит обратить внимание, что последние 2 года Microsoft приостановила развитие классического Windows PowerShell (выпускаются только исправления ошибок и безопасности) и сфокусировалась на открытом кроссплатформенном PowerShell Core. В чем отличия Windows PowerShell от PowerShell Core?
- Windows PowerShell основан на NET Framework (например, для PowerShell 5 требуется .NET Framework v4.5, нужно убедиться что он установлен). PowerShell Core основан на .Net Core;
- Windows PowerShell работает только на ОС семейства Windows, а PowerShell Core является кроссплатформенным и будет работать в Linux;
- В PowerShell Core нет полной совместимости с Windows PowerShell, однако Microsoft работает на улучшением обратной совместимости со старыми командлетами и скриптами (перед переходом на PowerShell Core рекомендуется протестировать работу старых PS скриптов). В PowerShell 7 обеспечивается максимальная совместимсть с Windows PowerShell.
- Редактор PowerShell ISE нельзя использовать для отладки скриптов PowerShell Core (но можно использовать Visual Studio Code)
- Т.к. Windows PowerShell более не развивается, рекомендуется постепенно мигрировать на PowerShell Core.
Как узнать версию PowerShell из консоли?
Самый простой способ определить какая версия PowerShell у вас установлена с помощью команды:
host
Следующий скриншот из Windows 10, в которой как и в Windows Server 2016 по умолчанию установлен PowerShell 5.1.
или
$PSVersionTable
Можно получить только значении версии:
$PSVersionTable.PSVersion.major
(в этом примере мы получили версию PSVersion 2.0 с чистого Windows Server 2008 R2)
Команда
$PSVersionTable
корректно работает в PowerShell Core на различных операционных системах.
Также можно узнать установленную версию PowerShell через реестр. Для этого нужно получить значение параметра PowerShellVersion из ветки реестра HKLM\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine с помощью Get-ItemProperty
(Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name 'PowerShellVersion').PowerShellVersion
Данный способ работает, начиная с Windows Server 2012/Windows 8. В Windows Server 2008 R2/ Windows 7 нужно получить значение параметра реестра в другой ветке:
(Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine -Name 'PowerShellVersion').PowerShellVersion
Для определения установленной версии PowerShell Core нужно использовать команду:
(Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PowerShellCore\InstalledVersions* -Name 'SemanticVersion').SemanticVersion
Получаем версию PowerShell на удаленных компьютерах
Для получения версии PowerShell на удаленных компьютерах нужно использовать значение переменной окружения $PSVersionTable или получать данные непосредственно из реестра. Другие способы могут возвращать некорректные данные.
Вы можете получить версию PowerShell с удаленного компьютера с помощью команды Invoke-Command:
Invoke-Command -ComputerName dc01 -ScriptBlock {$PSVersionTable.PSVersion} -Credential $cred
Major Minor Build Revision PSComputerName ----- ----- ----- -------- -------------- 5 1 14393 3383 dc01
Можно получить установленные версии PowerShell с нескольких компьютеров таким скриптом (их список сохранен в текстовом файле):
Invoke-Command -ComputerName (Get-Content C:\PS\servers.txt) -
ScriptBlock{$PSVersionTable.PSVersion} | Select PSComputerName, @{N="PS Version";E={$_.Major}}
Либо можно получить список компьютеров домена через Get-ADComputer и получить версию PowerShell на них:
$adcomputer=(Get-ADComputer -Filter 'operatingsystem -like "*Windows server*" -and enabled -eq "true"' -SearchBase ‘OU=servers,dc=winitpro,dc=ru’ ).Name
Invoke-Command-ComputerName $adcomputer -Scriptblock{$PSVersionTable.psversion} -ErrorAction SilentlyContinue
Если ваш скрипт PoweShell использует специальный функционал определенной версии PS, вы можно принудительно переключиться в режим другой версии PowerShell. Например, для запуска консоли в режиме PowerShell v3, выполните (должен быть установлен .Net Framework 3.5):
PowerShell.exe -version 3
Определение версии PowerShell может быть важно при выполнении скриптов и запуске команд, которые используют командлеты или специальные возможности определенной версии PS. Если вы хотите в скрипте PS определить какая версия PowerShell установлена, и в зависимости от этого использовать разные командлеты, вы можете использовать такой скрипт:
$ps_version = $PSVersionTable.PSVersion.major
if ( $ps_version -eq "2” )
{
write "Вы используете Powershell 2.0"
}
elseif ( $ps_version -eq "5" )
{
write " Вы используете Powershell 5"
}
В следующей статье мы рассмотрим, как обновить версию PowerShell в Windows.
In addition to other answers, here are some useful information that can be retrieved using PowerShell:
Querying OS & Hardware Info via PowerShell:
Querying General OS (Operating System) Information:
Quickest way to view the OS name:
cmd ?
#Using Get-ComputerInfo:
Get-ComputerInfo | select WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer
#Using Get-WmiObject:
$name=(Get-WmiObject Win32_OperatingSystem).caption
$bit=(Get-WmiObject Win32_OperatingSystem).OSArchitecture
$ver=(Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId
Write-Host " OS-Name: `t $name `n Architct: `t $bit `n Release: `t $ver"
To list Major Minor Version info:
[System.Environment]::OSVersion.Version
Querying HostName:
$Env:ComputerName
OR
hostname #cmd command
Also, if you know the IP address, use the «ping» command (e.g.: ping /a <your_ip_address>
) you will see your «hostname» in first line.
Querying Current (Logged-in) User:
whoami #cmd command
OR
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Querying Mapped Drives:
List Mapped Drives — using WMI:
Get-WmiObject -Class Win32_LogicalDisk | Format-Table
OR
wmic logicaldisk get name #list just logical-drive letters
OR, to list logical-drive info: FreeSpace, Provider (Real Network Location), Size, and VolumeName:
wmic logicaldisk list brief
List Mapped Drives — using [DriveInfo] class:
[System.IO.DriveInfo]::GetDrives()
List Removable Drives:
$drives = [System.IO.DriveInfo]::GetDrives()
$r = $drives | Where-Object { $_.DriveType -eq 'Removable' -and $_.IsReady }
if ($r) {
return @($r)[-1]
}
Querying disk capacity, space & Volume-Type
Invoke-Command -ComputerName S1 {Get-PSDrive C} | Select-Object PSComputerName,Used,Free
Free Space:
(Get-PSDrive C).Free
OR (in GB)
[Math]::Floor(((Get-PSDrive C).Free /[Math]::Pow(2, 30)*10)) /10
Used Space:
(Get-PSDrive C).Used
OR (Used space in GB’s)
[Math]::Floor(((Get-PSDrive C).Used /[Math]::Pow(2, 30)*10)) /10
Additionally to view total Space: (in GB)
$totalSpace = ((Get-PSDrive C).Used + (Get-PSDrive C).Free)/(1024*1024*1024)
OR
$totalSpace = ((Get-PSDrive C).Used + (Get-PSDrive C).Free)/[Math]::Pow(2, 30)
Rounded off values:
[Math]::Floor($totalSpace*10) / 10
OR
[Math]::Round($totalSpace,1)
Querying Motherboard info:
wmic baseboard get product,Manufacturer,version,serialnumber
Querying Disk Volume (Of Disk Partitions) Info:
Get-Volume returns information about storage drive’s partitions, e.g.:
Get-Volume # All partitions
Get-Volume -DriveLetter C # Specific partition
#file system type:
Get-Volume -DriveLetter C | select FileSystem
(Get-Volume -DriveLetter C).FileSystem
#partition size:
Get-Volume -DriveLetter C | select Size
OR (in GB)
[Math]::Floor(((Get-Volume -DriveLetter C).Size/[Math]::Pow(2, 30)*10)) /10
Querying Memory / Query RAM
Get-WmiObject Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum
OR (in GB)
$memory = (Get-WmiObject Win32_PhysicalMemory | Measure -Property Capacity -Sum).Sum
$memory = [Math]::Floor(($memory/[Math]::Pow(2, 30)*10)) /10
$memory.ToString() + " gb"
#Query RAM including Frequency / Speed:
Get-CimInstance win32_physicalmemory | Format-Table Manufacturer,Banklabel,Configuredclockspeed,Devicelocator,Capacity,Serialnumber –autosize
As mentioned, this answer goes bit beyond the question asked, but could be useful for those who’d like additional OS or Hardware information using PowerShell.
Посмотреть в Powershell версию Windows можно с помощью WMI или отдельных командлетов. Самый простой способ — это запустить:
Get-ComputerInfo
Мы можем получить сразу через Powershell версию ОС, не выводя всю информацию:
(Get-ComputerInfo).WindowsVersion
#или
Get-ComputerInfo -Property *Version*
Минусом этого командлета является то, что он долго отрабатывает каждый раз подгружая всю информацию. Если нужно узнать версию ОС на сотнях ПК, то стоит использовать другой вариант.
Командлет выше появился в версии PS 5.1, так что если сомневаетесь запустите:
host
#или
$PSVersionTable
Таким образом мы можем узнать версию билда:
$PSVersionTable.BuildVersion
Или использовать:
[System.Environment]::OSVersion.Version
Как получить в Powershell версию Windows используя WMI
Через WMI мы можем вернуть практически любое значение ОС, так что нужно найти только нужный класс:
Get-WmiObject -List | where -Property Name -Like "win32_Oper*"
Класс, который вернет версию ОС называется «Win32_OperatingSystem»:
Get-WmiObject -Class Win32_OperatingSystem | fl -Property Version, BuildNumber
…
Теги:
#powershell
Part of troubleshooting a Windows computer is finding out the operating system version. A typical user would know to check the computer’s properties to see the Windows version and build, similar to the one below.
Alternatively, you can execute the winver command and get the below result.
But what if you don’t have access to the GUI? Perhaps you need to get the same information from a remote computer? That’s where the awe of PowerShell shines through.
How do we get the Windows version the PowerShell way? Let’s explore several ways.
Method 1: PowerShell Get OS Version from the Registry
Would you be surprised that the Windows operating system information can be found inside the registry? Probably not. You can find that information in this location in the registry.
HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion
Viewing the Windows OS version in the registry editor is fine, but that’s not what we’re learning here. So, how do we perform the PowerShell get OS version from the registry method?
Open PowerShell and run this Get-ItemProperty command.
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
But as you can see above, the command returns many properties we don’t need. So let’s clean it up by selecting only the properties we want.
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | ` Format-List ProductName,DisplayVersion,CurrentBuildNumber
Isn’t this a lot better?
Note. Take a look at our article HTTP/HTTPS requests via Invoke-WebRequest PowerShell cmdlet.
Method 2: Query the Win32_OperatingSystem Class (WMI)
Through WMI classes, you can query different information about the local or remote computer. One of the details you can pull from WMI is the computer’s operating system version through the Win32_OperatingSystem or CIM_OperatingSystem class.
You can query WMI classes using the Get-WmiObject or Get-CimInstance cmdlets. There are differences between these two cmdlets that are not relevant to this task, but both will achieve the same goal.
Note. Get-CimInstance is the recommended and modern cmdlet.
# Windows PowerShell Get-WmiObject Win32_OperatingSystem | ` Format-List Caption, Version, BuildNumber
# PowerShell Core Get-CimInstance CIM_OperatingSystem | ` Format-List Caption, Version, BuildNumber
If you want to query a remote computer instead, you must append the -ComputerName parameter followed by the remote computer name.
# Windows PowerShell Get-WmiObject Win32_OperatingSystem -ComputerName <COMPUTER_NAME> | ` Format-List Caption, Version, BuildNumber # PowerShell Core Get-CimInstance CIM_OperatingSystem -ComputerName <COMPUTER_NAME> | ` Format-List Caption, Version, BuildNumber
Method 3: PowerShell Show Version from the System.Environment Class (.NET)
PowerShell can expose .NET classes and call their static methods. For example, the System.Environment class has an OSVersion property that returns the current operating system version.
Run the below command in PowerShell to get the Version property.
[System.Environment]::OSVersion.Version
Unfortunately, this method only shows the platform version and build numbers. The result does not say the friendly name (ie. Windows 11, Windows 10, etc.). Like in this example, the build number 19044 translates to Windows 10 20H2.
Refer to the List of Microsoft Windows versions.
This method may not be the best option if you care to retrieve the operating system name instead of only the version numbers.
Method 4: PowerShell Check Windows Version with the Get-ComputerInfo Cmdlet
The Get-ComputerInfo cmdlet is a built-in cmdlet that returns various details about the local computer. If you run it on its own, you’ll get a result similar to the one below.
Note. Check our guide on how to use PowerShell to check the status of a Windows service with Get-Service cmdlet.
But since we’re only interested in getting the Windows OS version, let’s append the -Property parameter with the specific properties we need.
Get-ComputerInfo -Property OSName,OSVersion
And that’s how you get the OS version the PowerShell way.
Method 5: PowerShell Check Windows Version with SystemInfo Command
Like the Get-ComputerInfo cmdlet, the systeminfo.exe command is a native command that returns the computer information, too.
But since systeminfo.exe is not a PowerShell cmdlet, it doesn’t produce the result as an object, so we can’t select specific properties from it. Instead, we can pass the result to the Select-String cmdlet to filter the OS Name and OS Version lines.
systeminfo.exe | Select-String "\bOS Name","\bOS Version"
Note. The \b switch is a regular expression to set a word boundary for the match. Without it, the result would also match BIOS because it has the OS characters.
Conclusion
You’ve now learned the many ways to get the Windows version in PowerShell. You see how to use built-in cmdlets, native commands, .NET classes, and the registry to retrieve the current Windows version.
Cyril Kardashevsky
I enjoy technology and developing websites. Since 2012 I’m running a few of my own websites, and share useful content on gadgets, PC administration and website promotion.