RSS

Tag Archives: cmd

ERRORLEVEL doesn’t work within an IF bracket

Just that day, I found that if I evaluate ERRORLEVEL within a IF bracket, ERRORLEVEL always returns 0. For example, the below construct will always set HAS_NAME = YES if evaluated, regardless of findstr

IF IS_WIN2K==YES (
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MyStuff" /v "MyKey" | findstr /i "kelvin"
If %ERRORLEVEL% EQU 0 SET HAS_NAME=YES
) ELSE (
Do something else
)

But if I extract this outside the IF brackets. The expression works perfectly

reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MyStuff" /v "MyKey" | findstr /i "kelvin"
If %ERRORLEVEL% EQU 0 SET HAS_NAME=YES

I could not find anyway to explain this despite hours of googling. At the end, I had to resort to calling a sub to evaluate the condition instead

IF IS_WIN2K==YES (call :SETNAME) ELSE (Do something else)

:SETNAME
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MyStuff" /v "MyKey" | findstr /i "kelvin"
If %ERRORLEVEL% EQU 0 SET HAS_NAME=YES
GOTO :EOF
 
2 Comments

Posted by on April 17, 2012 in Scripts, Windows CMD

 

Tags:

Getting FOR command to ignore spaces as delimiter in your input list

For those who uses the FOR command often enough, you will know that by default the command will take SPACE between characters as a delimiter. This will cause an issue if your input line actually includes SPACES.

For example, I have a list of user names call names.txt which I am using for a query using FOR:

  • Doe, John: HP Singapore
  • Wong, Kelvin: Palm
  • Li, Na: WTA

If I just use the following standard command, the output is not what I want:

FOR /f %a in (names.txt) do @echo %a

  • Doe,
  • Wong,
  • Li,

That’s because FOR command recognises SPACE by default and splits your input lines into a few tokens using SPACE as a delimiter. To trick FOR command to ignore SPACE, you can use a fake delimiter (ensure that the character you use does not appear in the input list) as below:

FOR /f “tokens=1 delims=~” %a in (names.txt) do @echo %a

  • Doe, John: HP Singapore
  • Wong, Kelvin: Palm
  • Li, Na: WTA
 
1 Comment

Posted by on February 23, 2011 in Scripts, Windows CMD

 

Tags:

CMD script that doesn’t work between 1AM – 9AM

One of the guys in another team complained to me the other day that one of the scheduled tasks which they were running seems to fail between 1 AM and 9 AM daily. The script is a simple CMD batch file and after troubleshooting for a while we could not find any issues with the account used to run the script or any other restrictions, so the focus now goes to the script. So I asked the guy to set echo on and pipe the results to have a look. Part of the script looks like this:

...
for /f "tokens=1,2,3 delims=/" %%i in ("%date%") do set LogDate=%%k-%%j-%%i
for /f "tokens=1,2,3,4 delims=:." %%i in ("%time%") do set LogTime=%%i-%%j-%%k.%%l
SET TMPFOLDER=C:\Mytemp
SET F1=%TMPFOLDER%\%LogDate%_%LogTime%_f1.txt
DIR C:\MYPATH /ad /on /b > %F1%
...

Now this looks exceptionally normal, but when I piped the results, I saw the following output:

C:\scripts>DIR /ad /on /b 9-04-21.20_f1.txt 1>C:\Mytemp\2010-05-07_
The system cannot find the path specified.

That was really strange because if you look at the command for DIR it only pipes to one file, how did we end up with 2 files? A quick look at it, I realized that the file was cut into half, with the second half being “9-04-21.20_f1.txt”.

Okay, so we decided to quote “%F1%” to see what happens and it works! Immediately I could see the problem…

C:\scripts>DIR /ad /on /b 1> "C:\Mytemp\2010-05-07_ 9-04-21.20_f1.txt"

There is a space in the output file! A quick check of the result of the output found the following culprit.

C:\scripts>for /F "tokens=1,2,3,4 delims=:." %i in (" 9:04:21.20") do set LogTime=%i-%j-%k.%l
C:\scripts>set LogTime= 9-04-21.20

The time variable %time% contains a leading space if the hour is between 1 to 9. This explains why the script only works outside 1 AM – 9 AM!

The solution is a quick fix by added [space] as one of the delimiters.

for /f "tokens=1,2,3,4 delims=:. " %%i in ("%time%") do set LogTime=%%i-%%j-%%k.%%l

 

 
Leave a comment

Posted by on May 7, 2010 in Scripts, Windows CMD

 

Tags:

CMD: Calling internal procedures in a batch file

I was not aware that one could create a procedure within a batch to call it until some 3-4 years ago.  To get this working, first you must create a procedure. A procedure is like any standard batch script except that you must enclose it with a label at the head and goto label at the foot.

:MyProc

set myname=%1

@echo this is my first procedure

@echo my name is %1

goto :EOF

The start of the procedure is defined by the label :MyProc. A label always begins with a semi-colon. If you are accepting arguments in your procedure, you should treat it like a normal arguments, i.e. %1, %2, etc. You must end the procedure with a goto :EOF statement, if you don’t the procedure will continue running any commands below it. Read the rest of this entry »

 
Leave a comment

Posted by on May 16, 2008 in Scripts, Windows CMD

 

Tags:

CMD: Quick repeated body file generation

Having come from DOS to Windows, batch commands have been indispensable part of my admin work. Its surprisingly how weak a lot of the Windows administrators nowadays are at writing simple batch scripts. Instead they tend to just repeat what they do with copy and paste using GUI, over and over.

Anyway, batch scripts is not rocket science, but I have seen some that is so good that it can probably launch a rocket! So here is my first batch script sharing that I hope can help some of you out there to improve your work.

Below is something I quickly hacked up because I needed to generate an import file with a list of 14 server names in XML format. The format of the file is a typical header/footer with a repeated body containing different host names.

I basically added a FOR loop into the batch file to generate the body. It makes a call to the procedure :body, which you can treat like another batch file. Few people are aware that you can call a procedure in a batch file. I also only found that out some years ago. Just need to remember to start the procedure with :Name and end with GOTO :EOF, which is effective a return call.

Some may wonder what %~dp0 means. This is a very useful variable substitution for the full path of the current script. Hence if my script is in c:\scripts, %~dp0host.txt will return c:\scripts\hosts.txt. To find out more, type FOR /?.

I have attached my file GENVRD.CMD (please rename ext to cmd) so that you can make sense what I am talking about. You will notice in the script I used ^> and ^< to escape the gt and lt signs.

@echo off
@echo Header Text > myfile.txt

for /f %%a in (%~dp0host.txt) do call :body >> myfile.txt

goto end

:body
@echo REPEAT BODY with %1
@echo REPEAT BODY with %1

goto :EOF

:end
@echo Footer Text > myfile.txt

 
Leave a comment

Posted by on December 7, 2007 in Scripts, Windows CMD

 

Tags:

CMD: Scripting Windows drive creation

For some reasons, our newly published (by our engineering team) server build program missed creating and formating the D drives on Windows 2000 servers. Of course, the simple solution it to just logon to the servers and format D: as normal to resolve this problem. But what if you have 30 or 100 servers that had the D: missing? This gives me another opportunity to test my scripting skills agian.

To create and partition the disk, I used DISPART.exe, which is a free MS util that you can download from, where else, MS website.

I used the following commands to create an new D partition:

SELECT Disk 1
Create Partition Primary
Assign letter=D

Unfortunately diskpart does not have a format function. For that, you have to use your old trusty FORMAT.EXE.

In command prompt, I typed the following command:

Format d: /fs:ntfs /v:DataD

But it gave me an error saying the volume or drive could not be found. I realise what happened quickly, I was logged on via terminal session and Windows 2000 did not refresh my session with the new drive information that FORMAT can use. I had to log off and log on again and rerun the command, which works. Now… I am even more determined to script this as I neither want to logon to console to do this one-by-one, nor log on, off and on just to create a D drive.

The problem with the FORMAT command is that it will prompt you with warning that you are going to erase all data. There are not quiet mode around this. To script it, you have to send the text “Y” to the command. Hence, the improved command is now:

type %~dp0ANS.txt | format d: /fs:ntfs /v:DataD

ANS.txt just contains “Y” with a carriage return.

For those who don’t know it %~dp0 is a variable substitution that substitutes the full path where your script is being run.

So I started up my task scheduling script and changed it so that it schedules diskpart to run first, then 2 minutes later, another task runs the format command. The 2nd task should get the new drive as it logs on to run the task.

 
Leave a comment

Posted by on August 8, 2007 in Windows, Windows CMD

 

Tags:

REM slowing down BAT execution

This may come to a surprise to some of us, but about 2 years back engineering guys implemented a batch logon script which is run on in Windows XP workstations. The domain controllers are centralised to Singapore and the small branches (e.g. Thailand) logon to the DC in Singapore.

A strange thing happened at logon, it was taking a few minutes to execution. We all thought that it was the bandwidth was causing the problem, it couldn’t be the XP machines, since they are new and no way would execute a simple logon script that slowly. However, the bandwidth was found to be acceptable and so I had a look at the logon script. Nothing unusual with it, its a few lines and calls some other routines.

So I modified the logon file and piped “time /t” commands between codes to see where it was slowing down. The result was interesting, it took a few minutes to execute the starting portion of the logon script. When I looked at it, there was no routines or programs being executed, only REM as part of documentation and change history. It was just too weird, I had thought that REM would not cause any penalties to the execution cycles. Disbelieving myself, I took all the REM statements out and the logon script went through at normal speed!

This was 2 years ago, so I don’t know if it has changed much, but my conclusion went something like this:

  • REM statements are evaluated in Windows and takes up cycle time.We don’t notice them most of the time because of the speed of execution. However, because the batch file was run from a moderate to low bandwidth location across a WAN, this becomes obvious.
  • The execution engine for BAT (legacy DOS) and CMD are different. The logon file was running as a BAT file uses possibly a 16-bit DOS engine, whereas CMD used the 32-bit engine. I tested the same batch file by renaming it to CMD and it ran perfectly. (I cannot find any reference for this, so I might be wrong).
 
4 Comments

Posted by on March 25, 2007 in Scripts, Windows, Windows CMD

 

Tags: