32

I need to get the OS version with a batch file. I 've seen a lot of examples online, many uses something like this code:

@echo off

ver | find "XP" > nul
if %ERRORLEVEL% == 0 goto ver_xp

if not exist %SystemRoot%\system32\systeminfo.exe goto warnthenexit

systeminfo | find "OS Name" > %TEMP%\osname.txt
FOR /F "usebackq delims=: tokens=2" %%i IN (%TEMP%\osname.txt) DO set vers=%%i

echo %vers% | find "Windows 7" > nul
if %ERRORLEVEL% == 0 goto ver_7

echo %vers% | find "Windows Vista" > nul
if %ERRORLEVEL% == 0 goto ver_vista

goto warnthenexit

:ver_7
:Run Windows 7 specific commands here.
echo Windows 7
goto exit

:ver_vista
:Run Windows Vista specific commands here.
echo Windows Vista
goto exit

:ver_xp
:Run Windows XP specific commands here.
echo Windows XP
goto exit

:warnthenexit
echo Machine undetermined.

:exit

The problem is when I execute this on Vista or Windows 7 I get the message

Machine undetermined

Is there any other way to do what I want?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Yerko Antonio
  • 657
  • 3
  • 8
  • 16
  • I'd be careful here, anyone who took the offer to upgrade to windows 10 may have the old version number in there, my machine was windows 8.1 and i upgraded to 10 and its still showing 6.3 in the registry as the "CurrentVersion" – Pete May 26 '17 at 03:36
  • systeminfo output is language dependent,e.g. in German it is "Betriebssystemname" – Maddes May 09 '21 at 19:12

20 Answers20

55

It's much easier (and faster) to get this information by only parsing the output of ver:

@echo off
setlocal
for /f "tokens=4-5 delims=. " %%i in ('ver') do set VERSION=%%i.%%j
if "%version%" == "10.0" echo Windows 10
if "%version%" == "6.3" echo Windows 8.1
if "%version%" == "6.2" echo Windows 8.
if "%version%" == "6.1" echo Windows 7.
if "%version%" == "6.0" echo Windows Vista.
rem etc etc
endlocal

This table on MSDN documents which version number corresponds to which Windows product version (this is where you get the 6.1 means Windows 7 information from).

The only drawback of this technique is that it cannot distinguish between the equivalent server and consumer versions of Windows.

Goldorak84
  • 3,714
  • 3
  • 38
  • 62
Jon
  • 428,835
  • 81
  • 738
  • 806
  • 8
    To properly handle Windows XP, you need to modify the delims because "ver" on winXP produces "Microsoft Windows XP [Version 5.1.####]", but on more recent versions of windows "ver" produces "Microsoft Windows [Version 6.1.####]". Notice that windows XP has "XP" in the string. The correct delims are "delims=[.XP ". Notice the space after XP. The space is required. – ZenCodr Feb 02 '16 at 02:34
  • Does changing the delims to `"delims=[.XP "` break Win7/8 detection? And do I still want to include `tokens=4-5`? What is the correct line of code to use? – Aaron Franke Apr 23 '18 at 07:45
22

These one-line commands have been tested on Windows XP, Server 2012, 7 and 10 (thank you Mad Tom Vane).

Extract version x.y in a cmd console

for /f "tokens=4-7 delims=[.] " %i in ('ver') do @(if %i==Version (echo %j.%k) else (echo %i.%j))

Extract the full version x.y.z

for /f "tokens=4-7 delims=[.] " %i in ('ver') do @(if %i==Version (echo %j.%k.%l) else (echo %i.%j.%k))

In a batch script use %% instead of single %

@echo off
for /f "tokens=4-7 delims=[.] " %%i in ('ver') do (if %%i==Version (set v=%%j.%%k) else (set v=%%i.%%j))
echo %v%

Version is not always consistent to brand name number

Be aware that the extracted version number does not always corresponds to the Windows name release. See below an extract from the full list of Microsoft Windows versions.

10.0   Windows 10
6.3   Windows Server 2012
6.3   Windows 8.1   /!\
6.2   Windows 8   /!\
6.1   Windows 7   /!\
6.0   Windows Vista
5.2   Windows XP x64
5.1   Windows XP
5.0   Windows 2000
4.10   Windows 98

Please also up-vote answers from Agent Gibbs and peterbh as my answer is inspired from their ideas.

oHo
  • 51,447
  • 27
  • 165
  • 200
  • 1
    For W10 I like getting the whole version. Thank you. You're answer is what I was looking for. `for /f "tokens=4-7 delims=[.] " %i in ('ver') do @(if %i==Version (echo %j.%k.%l) else (echo %i.%j.%k))` – E.V.I.L. Sep 15 '16 at 14:09
  • Thanks, more enhanced method based on this is here: https://stackoverflow.com/a/75970274/3268088 – captain_majid Apr 10 '23 at 01:02
16

Have you tried using the wmic commands?

Try wmic os get version

This will give you the version number in a command line, then you just need to integrate into the batch file.

liamog
  • 238
  • 2
  • 11
7

I know it's an old question but I thought these were useful enough to put here for people searching.

This first one is a simple batch way to get the right version. You can find out if it is Server or Workstation (if that's important) in another process. I just didn't take time to add it.

We use this structure inside code to ensure compliance with requirements. I'm sure there are many more graceful ways but this does always work.

:: -------------------------------------
:: Check Windows Version
:: 5.0 = W2K
:: 5.1 = XP
:: 5.2 = Server 2K3
:: 6.0 = Vista or Server 2K8
:: 6.1 = Win7 or Server 2K8R2
:: 6.2 = Win8 or Server 2K12
:: 6.3 = Win8.1 or Server 2K12R2
:: 0.0 = Unknown or Unable to determine
:: --------------------------------------
echo OS Detection:  Starting

ver | findstr /i "5\.0\."
if %ERRORLEVEL% EQU 0 (
echo  OS = Windows 2000
)
ver | findstr /i "5\.1\."
if %ERRORLEVEL% EQU 0 (
echo OS = Windows XP
)
ver | findstr /i "5\.2\."
if %ERRORLEVEL% EQU 0 (
echo OS = Server 2003
)
ver | findstr /i "6\.0\." > nul
if %ERRORLEVEL% EQU 0 (
echo OS = Vista / Server 2008
)
ver | findstr /i "6\.1\." > nul
if %ERRORLEVEL% EQU 0 (
echo OS = Windows 7 / Server 2008R2
)
ver | findstr /i "6\.2\." > nul
if %ERRORLEVEL% EQU 0 (
echo OS = Windows 8 / Server 2012
)
ver | findstr /i "6\.3\." > nul
if %ERRORLEVEL% EQU 0 (
echo OS = Windows 8.1 / Server 2012R2
)

This second one isn't what was asked for but it may be useful for someone looking.

Here is a VBscript function that provides version info, including if it is the Server (vs. workstation).

private function GetOSVer()

    dim strOsName:    strOsName = ""
    dim strOsVer:     strOsVer = ""
    dim strOsType:    strOsType = ""

    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2") 
    Set colOSes = objWMIService.ExecQuery("Select * from Win32_OperatingSystem") 
    For Each objOS in colOSes 
        strOsName = objOS.Caption
        strOsVer = left(objOS.Version, 3)
        Select Case strOsVer
            case "5.0"    'Windows 2000
                if instr(strOsName, "Server") then
                    strOsType = "W2K Server"
                else
                    strOsType = "W2K Workstation"
                end if
            case "5.1"    'Windows XP 32bit
                    strOsType = "XP 32bit"
            case "5.2"    'Windows 2003, 2003R2, XP 64bit
                if instr(strOsName, "XP") then
                    strOsType = "XP 64bit"
                elseif instr(strOsName, "R2") then
                    strOsType = "W2K3R2 Server"
                else
                    strOsType = "W2K3 Server"
                end if
            case "6.0"    'Vista, Server 2008
                if instr(strOsName, "Server") then
                    strOsType = "W2K8 Server"
                else
                    strOsType = "Vista"
                end if
            case "6.1"    'Server 2008R2, Win7
                if instr(strOsName, "Server") then
                    strOsType = "W2K8R2 Server"
                else
                    strOsType = "Win7"
                end if
            case "6.2"    'Server 2012, Win8
                if instr(strOsName, "Server") then
                    strOsType = "W2K12 Server"
                else
                    strOsType = "Win8"
                end if
            case "6.3"    'Server 2012R2, Win8.1
                if instr(strOsName, "Server") then
                    strOsType = "W2K12R2 Server"
                else
                    strOsType = "Win8.1"
                end if
            case else    'Unknown OS
                strOsType = "Unknown"
        end select
    Next 
    GetOSVer = strOsType
end Function     'GetOSVer
RLH
  • 1,545
  • 11
  • 12
5

Here is another variant : some other solutions doesn't work with XP, this one does and was inspired by RLH solution.

This script will continue only if it detects the Windows version you want, in this example I want my script to run only in win 7, so to support other windows just change the GOTO :NOTTESTEDWIN to GOTO :TESTEDWIN

ver | findstr /i "5\.0\."        && (echo Windows 2000 & GOTO :NOTTESTEDWIN)
ver | findstr /i "5\.1\."        && (echo Windows XP 32bit & GOTO :NOTTESTEDWIN) 
ver | findstr /i "5\.2\."        && (echo Windows XP x64 / Windows Server 2003 & GOTO :NOTTESTEDWIN)
ver | findstr /i "6\.0\." > nul  && (echo Windows Vista / Server 2008 & GOTO :NOTTESTEDWIN)
ver | findstr /i "6\.1\." > nul  && (echo Windows 7 / Server 2008R2 & GOTO :TESTEDWIN)
ver | findstr /i "6\.2\." > nul  && (echo Windows 8 / Server 2012 & GOTO :NOTTESTEDWIN)
ver | findstr /i "6\.3\." > nul  && (echo Windows 8.1 / Server 2012R2 & GOTO :NOTTESTEDWIN)
ver | findstr /i "10\.0\." > nul && (echo Windows 10 / Server 2016 & GOTO :NOTTESTEDWIN)

echo "Could not detect Windows version! exiting..."
color 4F & pause & exit /B 1

:NOTTESTEDWIN
echo "This is not a supported Windows version"
color 4F & pause & exit /B 1

:TESTEDWIN
REM put your code here
Badr Elmers
  • 1,487
  • 14
  • 20
  • It'd be better to save the output of `ver` to a variable and then echoing that through `findstr` rather than calling `ver` 8 times. – Ryan Beesley May 07 '20 at 18:35
  • @Ryan Beesley `ver` is a builtin command not an external command so it takes the same it will take using echo; I prefer to let it like that for simplicity without using the long `for...` solution to save the ver result. – Badr Elmers Feb 23 '21 at 03:53
  • That's a valid point. I don't know if the command has that information built in, I suspect it is still looking at the registry or internal data structure to generate the output, so I would still think it is cleaner to cache it, but it doesn't have the overhead running an external command might. – Ryan Beesley Feb 23 '21 at 08:04
5

So the answers I read here are mostly lengthy. The shortest answer by Alex works good, but not so clean.

Best part is that unlike others', it works fast.

I came up with my own one-liner:

FOR /F "usebackq tokens=3,4,5" %i IN (`REG query "hklm\software\microsoft\windows NT\CurrentVersion" /v ProductName`) DO echo %i %j %k

Above is for command prompt. To make it work in batch file, replace all % with %% to make it look like:

FOR /F "usebackq tokens=3,4,5" %%i IN (`REG query "hklm\software\microsoft\windows NT\CurrentVersion" /v ProductName`) DO echo %%i %%j %%k

In my computer, it simply produces Windows 10 Pro

  • Thank you! This is so much better than most solutions I've been able to find! It should probably print more tokens though (e.g. 3,4,5 to 3,4,5,6,7 and %%i %%j %%k to %%i %%j %%k %%l %%m) for instance to display *Windows 10 Enterprise LTSC 2019* instead of just *Windows 10 Enterprise* – Cestarian Dec 21 '20 at 13:24
  • @Cestarian: `for /f "tokens=2,*" %i IN ('REG query "hklm\software\microsoft\windows NT\CurrentVersion" /v ProductName') DO echo %j` to get the whole string (independent of how many words it contains) – Stephan Apr 09 '23 at 08:56
3

This will return 5.1 for xp or 6/1 for windows 7

for /f "tokens=4-7 delims=[.] " %%i in ('ver') do (
if %%i == Version set OSVersion=%%j.%%k
if %%i neq Version set OSVersion=%%i.%%j
)
peterbh
  • 93
  • 9
2

Here's my one liner to determine the windows version:

for /f "tokens=1-9" %%a in ('"systeminfo | find /i "OS Name""') do (set ver=%%e & echo %ver%)

This returns the windows version, i.e., XP, Vista, 7, and sets the value of "ver" to equal the same...

user1
  • 153
  • 1
  • 8
  • 1
    This method does not use the official Microsoft versions as specified in [this table](http://msdn.microsoft.com/en-us/library/ms724832%28VS.85%29.aspx) – ZenCodr Feb 02 '16 at 02:30
2

Actually, that one liner doesn't work for windows xp since the ver contains xp in the string. Instead of 5.1 which you want, you would get [Version.5 because of the added token.

I modified the command to look like this: for /f "tokens=4-6 delims=[. " %%i in ('ver') do set VERSION=%%i.%%j

This will output Version.5 for xp systems which you can use to indentify said system inside a batch file. Sadly, this means the command cannot differentiate between 32bit and 64bit build since it doesn't read the .2 from 5.2 that denotes 64bit XP.

You could make it assign %%k that token but doing so would make this script not detect windows vista, 7, or 8 properly as they have one token less in their ver string. Hope this helps!

sulfureous
  • 1,526
  • 1
  • 14
  • 22
2

Use a reg query and you will get an actual name: reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v ProductName

This would return "Windows 7 Professional", "Windows Server 2008 R2 Standard", etc. You can then combine with the ver command to get exact version.

1
@echo off
for /f "tokens=2 delims=:" %%a in ('systeminfo ^| find "OS Name"') do set OS_Name=%%a
for /f "tokens=* delims= " %%a in ("%OS_Name%") do set OS_Name=%%a
for /f "tokens=3 delims= " %%a in ("%OS_Name%") do set OS_Name=%%a
if "%os_name%"=="XP" set version=XP
if "%os_name%"=="7" set version=7

This will grab the OS name as "7" or "XP"

Then you can use this in a variable to do certain commands based on the version of windows.

1

If you are looking to simply show windows version in a batch file such as Windows 10 etc.

you can simply use the ver command just type ver and the windows version will be displayed

RN Tech
  • 11
  • 2
1
wmic os get Caption,CSDVersion /value

This will do the job.

Pang
  • 9,564
  • 146
  • 81
  • 122
Alex
  • 11
  • 1
1

The Extract the full version x.y.z proposed by @olibre looks the most suitable to me. The only additional thing is to take into account other languages except English, as a string "version" may be completely different in a localized Windows. So, here is a batch file tested under Windows XP, 7, 8.1 and 10, using US and Russian locale:

for /f "tokens=4-5 delims= " %%i in ('ver') do (
  if "%%j"=="" (set v=%%i) else (set v=%%j)
)
for /f "tokens=1-3 delims=.]" %%i in ("%v%") do (
  set OS_VER_MAJOR=%%i
  set OS_VER_MINOR=%%j
  set OS_BUILD_NUM=%%k
)
echo Detected OS version: %OS_VER_MAJOR%.%OS_VER_MINOR%.%OS_BUILD_NUM%

The values of %OS_VER_MAJOR%, %OS_VER_MINOR% and %OS_BUILD_NUM% can be checked for exact version numbers.

DVV
  • 204
  • 2
  • 5
0

The first line forces a WMI console installation if required on a new build. WMI always returns a consistent string of "Version=x.x.xxxx" so the token parsing is always the same for all Windows versions.

Parsing from the VER output has variable text preceding the version info, making token positions random. Delimiters are only the '=' and '.' characters.

The batch addition allows me to easily check versions as '510' (XP) up to '10000' for Win10. I don't use the Build value.

Setlocal EnableDelayedExpansion

wmic os get version /value 1>nul 2>nul

if %errorlevel% equ 0 (
   for /F "tokens=2,3,4 delims==." %%A In ('wmic os get version /value')  Do (
      (Set /A "_MAJ=%%A")
      (Set /A "_MIN=%%B")
      (Set /A "_BLD=%%C")
      )
    (Set /A "_OSVERSION=!_MAJ!*100")
    (Set /A "_OSVERSION+=!_MIN!*10")
    )

endlocal
Bruce Gavin
  • 349
  • 3
  • 9
0

On more recent versions (win 7 onwards) you can have powershell do the job for you.

for /F %%i in ('powershell -command "& {$([System.Environment]::OSVersion.Version.Major),$([System.Environment]::OSVersion.Version.Minor) -join '.' }"') do set VER=%%i

goto %VER%


:6.1
REM specific code for windows 7

:10.0
REM specific code for windows 10

see this table for version numbers

Federico Destefanis
  • 968
  • 1
  • 16
  • 27
0

None of the previous answers work on Win9x, and will soon fail with w10 22h1. First 4 lines are win3.x compatible ("set /P"; "for /F" are illegal there). It then saves the version on wver var, used on comparisons: The leading space on search string is essential to catch the begining of the number in the ver string (ie: "4." matches w10 21h2 string: "Microsoft Windows [Version 10.0.19044.1348]"). Most of previous solutions will soon fail with [future] windows versions. Next w10 22h1 string will be: "Microsoft Windows [Version 10.0.19045.1xxx]", that will match the "5.1" XP search string.

@echo off
ver | find " 3." >nul
if not ERRORLEVEL 1 goto :wold
ver | find " 4." >nul
if not ERRORLEVEL 1 goto :wold
    rem put version on wver variable
    for /F "delims=" %%a in ('ver') do set wver=%%a
    echo Windows Version: %wver%
    rem Do all >= w2000/xp tasks here
  if not "%wver: 5.=%" == "%wver%" ( echo 5.0=2k 5.1=xp 5.2=xp64/2k3 & goto fin )
    rem Do all >= vista tasks here
  if not "%wver: 6.0=%" == "%wver%" ( echo vista/2k8 & goto fin )
    rem Do all >= w7 tasks here
  if not "%wver: 6.1=%" == "%wver%" ( echo w7/2k8r2 & goto fin )
    rem Do all >= w8 tasks here
  if not "%wver: 6.=%" == "%wver%" ( echo 6.2=w8/2012 6.3=w8.1/2012r2 & goto fin )
    rem Do all >= w10 tasks here
  if not "%wver: 10.=%" == "%wver%" ( echo w10.x & goto fin )
    rem Do all >= w11 tasks here
  if not "%wver: 11.=%" == "%wver%" ( echo w11.x & goto fin )
    rem Do all >= w12? tasks here
  goto fin
:wold
echo Unsupported windows 3.x 9x me nt3 nt4...
:fin
isidroco
  • 3
  • 2
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 03 '21 at 07:50
0

Here is the batch file I finally came up with to determine if the operating system was less than Windows 11 (including my debugging echo statements to help users track what's happening). (My use case is that I'm customizing toolbars in the Windows taskbar, and toolbars are not Win11-compatible at the moment, so I don't want to run it on Win11 PC's.)

It can be modified to accommodate to whatever windows versions you want to filter out by modifying the LSS 11 line.

It stores the entire output of wmic os get Caption | findstr /v Caption in %%i. It then loops through each space-delimited "token" within %%i until it hits an integer (detected with regex). If the integer is less than (LSS) 11, it sets lesthaneleven to true. (It skips comparing any proceeding integers.)

This is more verbose/juvenile code than other answers, but I'm happy with it, because I feel it's pretty easy to read and thus modifiable for others' needs.

@echo off

for /f "tokens=*" %%i in ('wmic os get Caption ^| findstr /v Caption') do (
    for %%j in (%%i) do (
        echo token: %%j
        if not defined lessthaneleven (
            echo("%%j"|findstr "^[\"][-][1-9][0-9]*[\"]$ ^[\"][1-9][0-9]*[\"]$ ^[\"]0[\"]$">nul&& (
                    if %%j LSS 11 (
                        set "lessthaneleven=true"
                    ) else (
                        set "lessthaneleven=false"
                    )
                ) || (
                    echo token not numeric
                )
            )
        )
    )
)
if "%lessthaneleven%" == "true" (
    echo less than eleven
) else (
    echo not less
)
set lessthaneleven=

regex credit

velkoon
  • 871
  • 3
  • 15
  • 35
0

Why this answer is better than oHo's answer ?

Because it let you:

  1. Use arithmetic operators for comparison (EQU, NEQ, GTR, LSS, LEQ, GEQ), for a range of OSes, or if you want one not above or not under a certain OS, thanks to the leading 0.
  2. Easily distinguish between versions of Window 10,11 and vNext (until Windows 40 where the script collapse).
  3. Easily test the script using predefind verString.

Explanation

  • Replace %verString% with 'ver' on a real OS.
  • The if %%i==Version checks for token #4 to see if its Windows XP or not.
  • The arithmetic operators for comparison: EQU, NEQ, GTR, etc.. is done char by char like normal string sorting, so 10.0 is less than 6.3, because 6 is greater than 1.
  • So we've to add a leading 0 if Windows is less than 10 for the comparison to work correctly.
  • Rember to use the leading 0 for any comparison.

Batch

@echo off
set verString="Microsoft Windows [Version 39.0.99999]"
REM set verString="Microsoft Windows [Version 10.0.22621]"
REM set verString="Microsoft Windows [Version 10.0.22000]"
REM set verString="Microsoft Windows [Version 10.0.10240]"
REM set verString="Microsoft Windows [Version 6.3.9600]"
REM set verString="Microsoft Windows [Version 6.1.7601]"
REM set verString="Microsoft Windows XP [Version 5.1.2600]"
REM set verString="Microsoft Windows [Version 4.10]"

Set osName=Unknown Windows
for /f "tokens=4-7 delims=[.] " %%i in (%verString%) do @(if %%i==Version (set os_ver_org=%%j.%%k) else (if %%i geq 10 (set os_ver_org=%%i.%%j.%%k) else (set os_ver_org=%%i.%%j)))
set os_ver=%os_ver_org%
if %os_ver_org:~0,1% gtr 3 set os_ver=0%os_ver_org%

if %os_ver% GEQ 10.0.22000 set osName=Windows 11
if %os_ver% GEQ 10.0.10240 if %os_ver% lss 10.0.22000 set osName=Windows 10
if %os_ver% equ 06.3 set osName=Windows 8.1
if %os_ver% equ 06.2 set osName=Windows 8
if %os_ver% equ 06.1 set osName=Windows 7
if %os_ver% equ 06.0 set osName=Windows Vista
if %os_ver% equ 05.2 set osName=Windows XP x64 or Server 2003
if %os_ver% equ 05.1 set osName=Windows XP
if %os_ver% equ 05.0 set osName=Windows 2000
if %os_ver% lss 05.0 set osName=Windows ME or 98 or less

echo Detected %osName% x%PROCESSOR_ARCHITECTURE:~-2% (%os_ver_org%)
if %os_ver% lss 06.3 echo Only Windows 8.1 or above are supported !
captain_majid
  • 140
  • 13
-1

I use this:

@echo off & @echo.
setlocal
@echo Getting Windows version... & @echo.
@echo. > Windows_version_and_Key.txt
@echo Windows Version: >> Windows_version_and_Key.txt
for /f "tokens=* delims=. " %%i in ('ver') do set VERSION=%%i
@echo %VERSION% >> Windows_version_and_Key.txt
@echo. >> Windows_version_and_Key.txt
@echo. >> Windows_version_and_Key.txt
wmic os get Caption >> Windows_version_and_Key.txt
@echo. >> Windows_version_and_Key.txt
@echo Getting Windows license KEY...
@echo License KEY: >> Windows_version_and_Key.txt
wmic path softwarelicensingservice get OA3xOriginalProductKey >> Windows_version_and_Key.txt
powershell -c "(Get-Content .\Windows_version_and_Key.txt) -replace '\x00+', '' | Set-Content .\Windows_version_and_Key.txt"
type Windows_version_and_Key.txt
@echo. & @echo. & @echo Done! Press any key to Exit!
endlocal
pause
exit

It gives your windows key in case of you already lost it and need it.

All will be writed in a text file at end.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Persona78
  • 1
  • 1