CMD Substring Extraction On Output Variable

Viewed 141

Looking for guidance on performing substring extraction in a batch script on the variable of a command output. Specifically the command I am using is powershell (Get-CimInstance Win32_OperatingSystem).version

I have this variable set up successfully using for /f "tokens=*" %%i in ('"powershell (Get-CimInstance Win32_OperatingSystem).version"') do set OSvar=%%i

As you can see I am querying OS version, and I have an undisclosed, semi-valid use case for using this specific method to find it. Even if my reasoning behind using the above method to query may be misguided, I still want to learn how to perform substring extraction on this output, for my own edification. Finding a solution is less important than finding a solution in the given context.

Obviously, this will output something to the effect of "6.2.9200", "6.3.9600", or "10.0.XXXXXXX". I want to know how to extract the output before the 2nd decimal, but all of the attempts I've tried after researching are failing, including setting delims and using a second variable set equal to the first with :~0,3%. Can the gurus here help a guy out?

3 Answers

Well, split the result by .

@echo off
for /f "tokens=1,2delims=." %%i in ('powershell (Get-CimInstance Win32_OperatingSystem^).version') do (
    set "OSvar=%%i.%%j"
)
echo %OSvar%

or a oneliner from the same code:

@echo off
for /f "tokens=1,2delims=." %%i in ('powershell (Get-CimInstance Win32_OperatingSystem^).version') do echo %%i.%%j

you can use the standard ver command as well;

@for /f "tokens=1-5,*delims=. " %%i in ('ver') do @set OSvar=%%l.%%m

Explanation as requested. Seeing as we split the string by . each token gets to assigned to a metavariable. In other words. Let's assume it is windows 10.0.18362.959 then tokens=1,2 will assign 10 to %%i and 0 to %%j

If you only want the major and minor numbers, via , then it seems more sensible to return only those, instead of parsing the result afterwards:

For /F %%G In ('^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" ^
 -NoProfile -NoLogo -Command "[System.Environment]::OSVersion.Version | " ^
 "ForEach-Object { '{0}.{1}' -F $_.Major,$_.Minor }"^"') Do Set "OSVar=%%G"

As a oneliner:

For /F %%G In ('%__AppDir__%WindowsPowerShell\v1.0\powershell.exe -NoP "[System.Environment]::OSVersion.Version|%%{'{0}.{1}' -F $_.Major,$_.Minor}"')Do Set "OSVar=%%G"

If you really want to stick with using and Get-CimInstance:

For /F %%G In ('^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP ^
 "(Get-CimInstance Win32_OperatingSystem).Version.Split('.')[0,1] -Join '.'"^"'
) Do Set "OSVar=%%G"

As a oneliner:

For /F %%G In ('%__AppDir__%WindowsPowerShell\v1.0\powershell.exe -NoP "(GCim Win32_OperatingSystem).Version.Split('.')[0,1] -Join '.'"')Do Set "OSVar=%%G"

However, should you prefer to parse it after retrieval in your do portion, then I'd suggest a simpler method than using tokens and delimiters:

For /F %%G In ('^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" ^
 -NoProfile -NoLogo "(Get-CimInstance Win32_OperatingSystem).Version"^"'
) Do Set "OSVar=%%~nG"

As a oneliner:

For /F %%G In ('%__AppDir__%WindowsPowerShell\v1.0\powershell.exe -NoP "(GCim Win32_OperatingSystem).Version"')Do Set "OSVar=%%~nG"

In the previous two examples the .BuildNumber is seen as an extension, so using metavariable expansion we can return the name without extension.


However, you don't need to get the WMI information, you could use instead:

For /F %%G In ('"%__AppDir__%wbem\WMIC.exe" OS Get Version'
) Do If "%%~xG" NEq "" Set "OSVar=%%~nG"

And again as a oneliner:

For /F %%G In ('%__AppDir__%wbem\WMIC.exe OS Get Version')Do If "%%~xG" NEq "" Set "OSVar=%%~nG"

Hope this what you want to extract :

@echo off
@For /f "tokens=1,2,3 delims=." %%a in (
    '"powershell (Get-CimInstance Win32_OperatingSystem).version"'
) Do ( 
    Set "FirstVar=%%a"
    Set "SecondVar=%%b"
    Set "ThirdVar=%%c"
    Set "AllVar=%%a.%%b.%%c
)

echo FirstVar  = %FirstVar%
echo SecondVar = %SecondVar%
echo ThirdVar  = %ThirdVar%
echo AllVar    = %AllVar%
pause
Related