Search code examples
datetimebatch-filecommand-lineformattingwmic

How to format date/time output in a Windows batch script?


I'm writing a simple batch script to get the last date/time of when a PC was rebooted. Found two simple ways:

  1. systeminfo | find /i "Boot Time" which outputs:

System Boot Time: 5/4/2019, 5:04:44 AM

  1. wmic os get lastbootuptime which outputs:

LastBootUpTime

20190504050444.500000-420

I'm basically looking to format the output of the second one to be the same or similar as the first one (something readable). On newer PCs, the first one works fine but most of our customers are still running Windows 7 and it takes forever for the first one to load while the second one is quite instant even on OS older than Windows 7.

I was thinking of putting the output of second one to a variable and doing regex stuff:

for /f %%i in ('wmic os get lastbootuptime') do set lastboottime=%%i

but I keep getting "%%i was unexpected at this time" error. I'm a PowerShell user and have no idea about batch syntax.


Solution

  • Using gives you control over the output string you want, but it can take some time to run, if the system has never run WMIC before.

    The issue you're facing is due to the line endings used in the WMIC output, this can be simply solved by only setting the variable If it has not already been Defined, (sets the first line of output only):

    @Echo Off
    Set "LBT="
    For /F EOL^=L %%A In ('""%__AppDir__%wbem\wmic.exe" OS Get LastBootUpTime 2>Nul"
    ')Do If Not Defined LBT Set "LBT=%%~nA"
    Echo System Boot Time: %LBT:~,4%/%LBT:~4,2%/%LBT:~6,2%, %LBT:~8,2%:%LBT:~10,2%:%LBT:~-2%
    Pause
    

    You can read a little more about the WMIC line endings issue, over on DOSTips, complete with other suggestions on overcoming the issue.

    However, as an alternative, and without using SystemInfo, you may prefer the output from net.exe instead:

    @Echo Off
    For /F EOL^=^ Skip^=1Delims^= %%A In ('""%__AppDir__%net.exe" Statistics Work"
    ')Do If Not Defined _lb For %%B In (%%A
    )Do Echo=%%B|"%__AppDir__%findstr.exe" "[0-9][0-9]">Nul&&(
        Call Set "_lb=%%_lb%% %%B")
    Echo System Boot Time: %_lb%
    Pause
    

    You'll note that this may give a slightly different time, usually a little later, but I doubt that the accuracy of either method would be critical.

    Of course, as you say you're a guy, you could just as easily use that from a too.

    @Echo Off
    For /F Delims^= %%A In ('
        PowerShell -NoP "GWMI Win32_OperatingSystem|Select @{e={$_.ConvertToDateTime($_.LastBootUpTime)}}"
    ')Do Set "BUT=%%A"
    Echo System Boot Time: %BUT%
    Pause
    

    +:

    @Echo Off
    For /F Delims^= %%A In ('PowerShell -NoP "(GCIM Win32_OperatingSystem).LastBootUpTime"')Do Set "LSB=%%A"
    Echo System Boot Time: %LSB%
    Pause