Link to home
Start Free TrialLog in
Avatar of ace350
ace350Flag for United States of America

asked on

Check Disk (CHKDSK) on all volumes and fix if needed.

I may have gone off the deep end with this attempt.  I must stay with "batch".  I can use VB but it bust be embedded in batch to work with all my servers.  I am trying to figure out a way to schedule "CHKDSK /F" for the next reboot ... but only if it is needed.  I also need to report out to a txt file.
Here is what I have so far:

@ECHO Off
MD "C:\temp\" >nul 2>&1
setlocal EnableDelayedExpansion
ECHO FreeSpace Info
(for /f "skip=1" %%d IN ('wmic logicaldisk where drivetype^=5 get deviceid') DO echo/%%d )>C:\temp\CDdrives.txt
set /p CDDrive=<C:\temp\CDdrives.txt
for /F "tokens=2 delims==" %%V in ('
    echo. ^|wmic VOLUME GET Name /VALUE
') do for /F "delims=" %%L in ("%%V") do (
    echo.%%L

) >> C:\temp\drives1.txt

(For /F "Usebackq Tokens=*" %%# in ("C:\temp\drives1.txt") Do (
    Echo "%%#" | FIND /I "\" 1>NUL && (
        Set "Line=%%#"
        Call Set "Line=%%Line:~0,-1%%"
        Call Echo %%Line%%
    ) || (
        Echo %%#
    )
)) > C:\temp\drives2.txt

Type C:\temp\drives2.txt | findstr /V !CDDrive! > C:\temp\drives3.txt
set "file=C:\temp\drives3.txt"

<"!file!" (
  for /f %%i in ('type "!file!" ^| find /c /v ""') do set /a n=%%i && for /l %%j in (1 1 %%i) do (
    set /p "line_%%j="
  )
)
Del "C:\temp\drives1.txt"
Del "C:\temp\drives2.txt"
Del "C:\temp\CDdrives.txt"

ECHo ********************************************************************************
ECHo * Check disk - Results
ECHo ********************************************************************************
Echo.
ECHO Performing Check Disk > CON
ECHO ******************************************************************************** > CON
ECHO. > CON

(
for /l %%i in (1 1 !n!) do echo ***** Performing Check Disk on volume !line_%%i! ***** & chkdsk !line_%%i!
)  > "C:\temp\Temp_ChkdskInfo_Output.txt"
Findstr /V /c:"percent complete." "C:\temp\Temp_ChkdskInfo_Output.txt" | Findstr /V /c:"specified." | Findstr /V /c:"mode." | Findstr /V /c:"completed." | Findstr /V /c:"CHKDSK" | Findstr /V /c:"processed." | Findstr /V /c:"scanned." | Findstr /V /c:"recovered." > "C:\temp\Temp_ChkdskInfo_Output2.txt"
Findstr /v "^$" "C:\temp\Temp_ChkdskInfo_Output2.txt"

REM Del "C:\temp\Temp_ChkdskInfo_Output.txt"
REM Del "C:\temp\Temp_ChkdskInfo_Output2.txt"
REM Del "C:\temp\drives3.txt"

Open in new window


This is a small part of a larger analysis suite of batch scripts.  This batch should work on all Windows server OS flavors.  My goal is to completely automate my process, and this is an unexpected challenge that I thought I knew how to handle.  I know there are probably more efficient ways of getting the results, but like all bad code, it was just a small script that grew.  Any suggestions are welcome.  Thanks in advance.
Avatar of David
David
Flag of United States of America image

You can't ever know if chkdsk is needed.  You can only know if it WAS needed.    Even if system was shut down properly and last thing you did was a chkdsk, then you can still have an unrecoverable read error resulting in filesystem problem on powerup.
Avatar of ace350

ASKER

@dlethe -

Thank you for your comment.  You are correct.  

I think a better explanation of my goal is needed.  I am running a remote process on hundreds of computer.  With the restrictions of the multiple environment and server landscape setting, I am forced to reduce my scripting tech to almost the most basic common language ... that's why batch and vbscript.  So, this particular part of the process produces a bit of data by running just "CHKDSK" on all the volumes found on each server and gives some quick feedback by condensing the CHKDSK output to just needed info.  I have just been authorized to automate the "CHKDSK /F" during a scheduled reboot, at a later date.  The catch is that I must report back to the Data Center hosting company what I have done, when it is done and justify the execution of the "CHKDSK /F" by providing a report that provides the tested volume and the "CHKDSK" feedback that "Windows found problems with the file system."  If the report from "CHKDSK" states "Windows has scanned the file system and found no problems.", "CHKDSK /F" should not be scheduled to run during the next scheduled server reboot.

So ... I am not looking for the need for "CHKDSK /F" at the time of a reboot, but rather a reaction to an output that is run days or weeks before a reboot actually happens.
The only one that will be scheduled is for the OS partition. The other prompts and if answered in the affirmative, tge partition is "unmounted" and scanned.

The point dlethe pointed to deals with if there is a dirty bit.
You could look at using fsutil to test/set dirty bit.
Your batch script could use tests to determine what capabilities/options exist and then run ....... The variation of best suitable scripts in the environment.


With that said, setting chkdsk /f on next reboot is complicated depending on the system, hardware/raid controller.
ASKER CERTIFIED SOLUTION
Avatar of arnold
arnold
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Arnolds responses are absolutely correct. He deserves the points
Avatar of ace350

ASKER

Sorry for the delay .... Thank you for your feed back.  I have used a combiniation of the "dirty bit" and the registry settings to address all of my variables.  Thanks again.
UPDATE:
Here is the .cmd that I ended up putting into production .... the only bug is that mounted voumes are not taken into consideration.
[code]
:BaseFileCreation
      setlocal EnableDelayedExpansion
      ECHO FreeSpace Info
      (for /f "skip=1" %%d IN ('wmic logicaldisk where drivetype^=5 get deviceid') DO echo/%%d )>C:\temp\CDdrives.txt
      set /p CDDrive=<C:\temp\CDdrives.txt
      REM echo !CDDrive!
      for /F "tokens=2 delims==" %%V in ('
            echo. ^|wmic VOLUME GET Name /VALUE
      ') do for /F "delims=" %%L in ("%%V") do (
            echo.%%L

      ) >> C:\temp\drives1.txt

      :: Above has to be double >> because of loop, if not it will only write last drive to txt

      (For /F "Usebackq Tokens=*" %%# in ("C:\temp\drives1.txt") Do (
            Echo "%%#" | FIND /I "\" 1>NUL && (
                  Set "Line=%%#"
                  Call Set "Line=%%Line:~0,-1%%"
                  Call Echo %%Line%%
            ) || (
                  Echo %%#
            )
      )) > C:\temp\drives2.txt

      Type C:\temp\drives2.txt | findstr /V !CDDrive! > C:\temp\drives3.txt
      set "file=C:\temp\drives3.txt"

      <"!file!" (
        for /f %%i in ('type "!file!" ^| find /c /v ""') do set /a n=%%i && for /l %%j in (1 1 %%i) do (
            set /p "line_%%j="
        )
      )
      Del "C:\temp\drives1.txt"
      Del "C:\temp\drives2.txt"
      Del "C:\temp\CDdrives.txt"
:CHKDDSK
(
for /l %%i in (1 1 !n!) do echo ***** Performing Check Disk on volume !line_%%i! ***** >> "C:\temp\!line_%%i:~0,1!_ChkdskInfo_disk.txt" & (chkdsk !line_%%i! >> "C:\temp\!line_%%i:~0,1!_ChkdskInfo_disk.txt") & (Findstr /V /c:"percent complete." "C:\temp\!line_%%i:~0,1!_ChkdskInfo_disk.txt" | Findstr /V /c:"specified." | Findstr /V /c:"mode." | Findstr /V /c:"completed." | Findstr /V /c:"CHKDSK" | Findstr /V /c:"processed." | Findstr /V /c:"scanned." | Findstr /V /c:"recovered." | Findstr /v "^$" > "C:\temp\!line_%%i:~0,1!_ChkdskInfo_disk.txt")
for /l %%i in (1 1 !n!) do Findstr /c:"found problems" "C:\temp\!line_%%i:~0,1!_ChkdskInfo_disk.txt" > NUL && (
ECHO Check Disk:                  Error - !line_%%i! - Problems found - CHKDSK /F will run at next reboot
FSUTIL Dirty set !line_%%i!
) || (
ECHO Check Disk:                   OK - !line_%%i! - NO Problems found
)
) >> "C:\temp\Temp_ChkdskInfo_Feedback.txt"
Findstr /V /c:"SQL" "C:\temp\Temp_ChkdskInfo_feedback.txt" > "C:\temp\Temp_ChkdskInfo_Feedback2.txt"
Type "C:\temp\*.txt" >> "C:\temp\Temp_ChkdskInfo_Output.txt"
Type "C:\temp\Temp_ChkdskInfo_Output.txt"
Type "C:\temp\Temp_ChkdskInfo_Feedback2.txt" >> "C:\temp\FeedBack.txt"

DEL "C:\temp\Temp_ChkdskInfo_Feedback.txt"
DEL "C:\temp\Temp_ChkdskInfo_Feedback2.txt"
DEL "C:\temp\Temp_ChkdskInfo_Output.txt"
for /l %%i in (1 1 !n!) do DEL "C:\temp\!line_%%i:~0,1!_ChkdskInfo_disk.txt"
[/code]