Using functions in cmd (advanced scripting no.3)

Comment from Alun Jones (thx!) reminds me I forget to mention “functions” in batches! We were talking about script block, which are great if you combine them with call… Lets have a look what I have in my mind:


Echo Beginning…


Call :CheckForUserName %UserName%



Echo End…

Goto EndOfScript

:: Subroutines
:CheckForUserName
Net User %1 /Domain > nul
If %ErrorLevel% NEQ 0 (
   Echo User doesnt exist
   Goto EndOfScript
   ) Else (
   Echo User exist
   )


:EndOfScript

If you use it this way, you can see that it will execute CheckForUserName with parametere username and then it will return back (where Call was used), which can be extremely usefull sometimes.


However sometimes you need to end function (for example if error is encountered). Many people are asking me why I am always using EndOfScript when I can simply use Goto :EOF command – the reason is that if Goto :EOF is used inside this function, it WONT just to end of script – it will simply jump to end of function!

Script blocks in CMD (advanced scripting no.2)

Well, I know I talked about this few times, but I decided to write more comprehensive article about this (this will follow previous about delayed expansion).


Many people think batches are stupid – I dont agree, I think you can do miracles with batches.


One of not really often used features are script block – I mean commands that are on more than one line. You can often see this:


If %Errorlevel% NEQ 0 Echo Error %ErrorLevel% occured!
If %Errorlevel% NEQ 0 FixError.cmd %ErrorLevel%
If %Errorlevel% NEQ 0 Goto EndOfScript


You can write this in more intelligent way:If %Errorlevel% NEQ 0 (
   Echo Error %ErrorLevel% occured!
   FixError.cmd %ErrorLevel%
   Goto EndOfScript
   )


And this is script block. You can use them either with If command or For command… And you can have many nested script blocks… For example this:


If %ErrorLevel% NEQ 0 (
   For /f “usebackq delims== tokens=1-2″ %%i IN (`Set Error.`) Do (
      Echo Error %%j occured
      )
   Goto EndOfScript
)


Of course this is just example – you can make much MORE complex script blocks, for example some of mine are about 50 lines long (and when they are running, they create like 300 lines of code). When you get familiar with script block, you wont use common GoTo structure anymore – there is no need to.


But there is also one disadvantage – you must be advanced script write, because the script block is evaluated at beggining, so if you have some error, it is sometimes really hard to find out whats wrong.


 

One more time – what the heck are delayed variables???

This is one of the most common problems with scripting batches:
most administrators dont know/dont understand delayed expansion, which is EXTREMELY important if you want to make more complex scripts.


So what is it about?


First let me show one really small example:


Set Variable=1
If %Variable% EQU 1 (
   Set /a Variable=%Variable% + 1
   Echo %Variable%
   )


Quite simple script, right? Set variable is one, if it is one, add one and show the result. And what do you think the result is? Two?


WRONG!


The result is in fact one! That is because variables are expanding when interpreter encounters the beginning on the script, so Echo %Variable% command output is prepared BEFORE Set /a Variable… is evaluated.


However there is something called delayed variables, which means these variables are expanded in the moment when they are encountered.


So how to enable these functionality? It is quite simple – you just need to add SetLocal EnableDelayedExpansion at the beginning of the script and then you can use !Variable! (note that you can decide if you want to use normal %variable% or delayed !variable!).


But lets show it on example: 


SetLocal EnableDelayedExpansion


Set Variable=1
If %Variable% EQU 1 (
   Set /a Variable=%Variable% + 1
   Echo %Variable%
   Echo !Variable!
   )


Output from this script block is 1 (normal %Variable%) and 2 (delayed !Variable!).


If you want to implement more complex script blocks (nested For + If + If + For etc.), you must understand this concept and get familiar with it :)


 

How to raise (lower) errorlevel in scripts?

This is really common question – how can I raise/lower errorlevel in batches using integrated tools?
In fact there is really simple answer to this question:


Resetting errorlevel:
Just use command
Verify > nul
It will automatically “reset” errorlevel back to normal


Increasing errorlevel to 1:
We can use verify command again:
Verify blablabla 2>nul
Because verify dont know blablabla parameter, it will automatically increase errorlevel to 1.


Do you find it userful? There are many different methods how to increase errorlevel – share your favourite :)   

Get rid of old .ini files – redirect them to registry!

If you remember, loooong time ago (Windows 3.x) we used .ini files for setting almost everything.


These files were often placed in %WinDir% (which is quite disaster when you try to implement LUA). What can you do about it (instead of logging, creating security templates and so on)?


There is functionality built-in Windows called Initialization file mapping, that allow you to “upgrade” your registry-unaware software -> this software will now be able to use registry :)


How to do it? It is quite simple – the best documentation I found is here:


http://www.oreilly.com/catalog/manwinreg/chapter/ch08.html#32309

Do you prefer keyboard to mouse? Use qliner! :)

If you are using keyboard a lot (like myself), you probably know shortcuts like Winkey+R for run dialog or Winkey+E for explorer window. There is really nice tool available, that will allow you to edit winkey combination…


For example, on my computer, Winkey+C means command line, Winkey+X means Monad and so on (I also have set up volume control etc.) You can try it and share your feedback – it is FREE ;)


http://www.qliner.com/hotkeys/

Bunch of GREAT links!

Hey guys! I run into few REALLY nice links (at least for me) and I would like to share them with you.


1.) Do you ever encountered SDK documentation? I think so. However it is kind of “cryptic” on a first look. What the heck does Class Win32_Service : Win32_BaseService { boolean AcceptPause; … } mean??? For those of you who want to see some description about HOW to read SDKs, check this link:


http://www.microsoft.com/technet/scriptcenter/resources/begin/ss0206.mspx


2.) You got an iPod (or PDA, mp3 player etc.) and want to use it for something else then just playing same song all the way? There are mp3 podcasts available from Scriptcenter :)


http://www.microsoft.com/technet/scriptcenter/audio/sweek3.mspx


3.) For those of you interested in security, I REALLY recommend one article at Washington Post. I was really suprised how “easy” it was to read through article (I mean that I read it at once ;)).


http://www.washingtonpost.com/wp-dyn/content/article/2006/02/14/AR2006021401342.html


 


Now you can tell me, should I post links that interested me like I did today?