Berit Larsen
Berit Larsen

Reputation: 752

Commands in batch script not working

I made the following script:

SET localfolder="%~dp0"
mkdir %localfolder%
SET logger="%~dp0"\%~n0.log
echo %date% %time% logger=%logger% >> %logger%

set "list=a b c"
set disk=""

FOR %%i IN (%list%) DO (
    SET disk=%%i: & call :chk
)

:chk
cd C:\windows\system32
%disk% >> %logger%
chkdsk %disk% >> %logger%

Running this script file results in the following output:

22.12.2014 11:38:36,82 logger="W:\Scripts\"\chkdsk_all.log

W:\Scripts>(SET disk=b: & call :chk )

W:\Scripts>cd C:\windows\system32

W:\Scripts>b: 1>>"W:\Scripts\"\chkdsk_all.log

W:\Scripts>chkdsk b: 1>>"W:\Scripts\"\chkdsk_all.log

W:\Scripts>(SET disk=c: & call :chk )

W:\Scripts>cd C:\windows\system32

W:\Scripts>c: 1>>"W:\Scripts\"\chkdsk_all.log

W:\Scripts>chkdsk c: 1>>"W:\Scripts\"\chkdsk_all.log

I don't understand why it doesn't work, what am I missing?

Upvotes: 0

Views: 487

Answers (2)

Berit Larsen
Berit Larsen

Reputation: 752

It works after I changed "cd C:" to "cd /D C:"

Upvotes: 0

rojo
rojo

Reputation: 24466

I've got a few improvements to suggest.

  1. %~dp0 is the drive and path of the directory containing the running script. I'm puzzled about why you are trying to mkdir %~dp0 when it is impossible for that directory not to exist already. Are you trying to create a directory with the same name as the script? If so, try md %~dpn0 instead, and set "logger=%~dpn0\%~n0.log".

  2. Rather than supplying a static list of drive letters in a for loop, why not ask WMI to supply the list? wmic logicaldisk where "DriveType=3" will get you a list of the non-removable, non-network drives in your system.

  3. Why are you doing cd %windir%\system32? What ability do you gain by changing to that directory that you don't already have from the script's running directory? I don't think you need it.

  4. You know when you chkdsk c: you get an error saying the volume can't be checked while mounted? I suggest adding chkdsk /x to dismount drives first. In the case of the C: drive, you'll probably get "Chkdsk cannot run because the volume is in use by another process. Would you like to schedule this volume to be checked the next time the system restarts? (Y/N)". You can go ahead and supply the Y ahead of time by piping and echo Y| chkdsk /x %drive%.

So here's what I suggest:

@echo off
setlocal

set "logfile=%~n0.log"

for /f "tokens=2 delims==:" %%I in ('wmic logicaldisk where "DriveType=3" get DeviceID /format:list ^| find "="') do (
    >>"%logfile%" (
        echo Checking "%%I:"
        echo y| chkdsk /x %%I:
    )
)

Upvotes: 2

Related Questions