Common CURL Parameters

–http1.0 Use HTTP 1.0
–http1.1 Use HTTP 1.1
–http2 Use HTTP 2
-4 Resolve domain names to IPv4
-6 Resolve domain names to IPv6
-k Allow insecure connections in SSL
HTTP options
–data …HTTP POST data
–data-urlencode …HTTP POST data (‘@’ allowed)
-F name=content Specify multipart MIME data
-G Put POST data in URL and use GET
-H header/@file Pass custom header to server
–oauth2-bearer token Use OAuth2 bearer token
-u user:password Server user and password
–url URL to work with
-D fileWrite received headers to file
-fFail silently on HTTP errors
-i Include response headers in output
-o file Output to file name
-LFollow redirects
-sSilent mode

My List of Ubiquitous Software

(Really just a list for myself when I reinstall a new computer.)



  • Skype – but the Windows client, not the Win10 app
  • Slack – collaboration/chat client


Tools & Utilities





  • Inkscape – SVG editor
  • Corel Paint Shop Pro 9 – pretty good image editor, fast, lightweight, but only version 9
  • NAPS 2 – scanner utility



  • Apache/PHP – web server (links to Windows downloads)
  • MySQL – still my favorite database
  • Zabbix – server monitoring, takes a while to set up right but when it works, it’s nice
  • OpenHAB 2 – IoT automation and monitoring (a real pain to set up right, but powerful when it works)
  • Bitvise SSH Server – free Windows ssh server
  • RabbitMQ – messaging platform

Common wget Parameters

-oOutput file name
-ncNo-clobber (don’t overwrite anything)
-cContinue (add to existing file)
-NOnly retrieve if newer than existing
-SDisplay server response
-nHDon’t create host directories
–header=xInsert custom header
–save-headersSave headers to file
–referer=x Use custom referer
–method=xUse custom HTTP method
–post-data=STRSet POST data from string
–post-file=FILESet POST data from file
-l nMaximum recursion level
-kConvert links to local
-pPage requisites
-LFollow relative links only
-npNo-parent (don’t ascend into parent directory)

Just Like Riding a Bike

I’ve always felt like national economy is kind of like riding a bike.

Remember back when people didn’t have LED’s or batteries, but just the plain old dynamo, that you put against the wheel, and the faster you went, the brighter the lights got?

Just like a wheel, the national economy spins around. Goods and services are being produced and consumed, and the money that pays for it is constantly shuffled around, from person to person – just like a big bike wheel. The faster it goes, the richer we all become. The slower it goes, the poorer we are. (This may be slightly oversimplified, but bear with me.)

Now, some bright person comes up with the idea that it would be beneficial to everyone – you know, the country riding on the bike – if we could add a little dynamo and then have bright lights illuminating the road ahead. And what a great idea! Bright, shining light piercing the darkness!

Of course, it gets a little harder to ride the bike with the dynamo. We have to push a little harder, and the bike runs a little bit slower.

But the concept is so brilliant that we quickly come up with more things we can run off of the dynamo. Healthcare, social security, funding police and military forces, public schools, free tuition for universities… the list goes on and on; and it’s so great because we all contribute to it and in return get all of these very useful public services.

Only the problem is that now it’s really, really heavy to push the bike forward. Some people give up altogether and quit pedaling, which causes the bike to go even slower. And now the people pushing on the pedals get quite upset and become rather loud in their criticism, suggesting that maybe we could get rid of maybe one or two public services, so the dynamo will require a little less speed and the bike can run a little faster (and easier!)

Those loud people are quickly silenced and shamed, since who wants to get rid of all these public services benefiting so many? Keep pedaling, the downhill is coming, people shout.

And the downhill comes, and the bike flies along. Everyone is happy, the economy is doing great, even more public services are added. Phones, phones for everyone! Free healthcare, not just subsidized! Some people even float the idea of a universal “citizen salary” that is paid to everyone whether they work or not. Some people jump on it and stop pedaling. It’s going downhill anyway, why bother?

But the downhill slope eventually ends, the bike levels out, and the uphill comes along – caused by financial turmoil in Greece or Japan – and suddenly the power nearly goes out; the light is reduced to a dim flicker, social services are left floundering, military and police forces are reduced to a bare minimum. Criminality grows. Poverty strikes. Protests are forming, both by those who now are practically killing themselves trying to push the pedals, and those desperately relying on these now largely defunct social services. The bike, due to the slow speed, becomes increasingly unstable.

Pray that the wheel never actually stops, for that is where coups, revolutions and civil war happens. Instead, pray that we have the foresight to minimize public spending where necessary in time, trim government programs, and encourage self-reliance instead of government dependence. And let’s not forget the regular people (taxpayers) who day by day push the bike forward, in rain or sunshine, without any thanks at all.

Password Management Survey Results

(Please scroll to the bottom to see a few simple password recommendations and guidelines.)

A week or two ago, I sent out a request on Facebook and LinkedIn for people to participate in my survey about password management. My interest was to see, given how complex passwords are becoming and how easy it really is to crack most passwords, how people on various technical levels approach password management.

I did get a handful of responses – not overwhelming by any means, but still enough to put together a survey result, which I think is interesting to analyze. The initial results confirmed my suspicions that there is a discernible divide between people who rated themselves “high” on an IT competence scale (security experts, software developers, people who have to manage IT security) and “low” (at-home users or people who get exposed to security issues at work).

Let’s dig in.

1. How do you manage passwords?

Most people use either a few passwords for all their needs, or rely on an online manager to remember their passwords. What’s interesting is the divide between higher or lower IT competence – people who manage computer security need more complex passwords and use password managers to remember their passwords, while everyday users use a few lower-complexity passwords to get around.

We’re really today at the point where some kind of manager is necessary – with widespread hacks of online services and multi-million password dumps on the internet, it is no longer viable to use a single password or a few – the recommendation is to use a different one for every website you visit, and no one can remember those.

At a minimum, email accounts, social media accounts, and financial/bank accounts must have separate, individual passwords.

It’s also interesting to note the low score of Google/Facebook sign-in responses. They both provide a fully functional trust mechanism to authenticate yourself online, but seem unpopular for some reason.

2. Two-factor authentication

On the lower end of IT competence, most users responded that they did not know what 2FA (two-factor authentication) was. On the higher end, the trend was to secure a few accounts with 2FA (presumably the most important ones).

Two-factor authentication means that not only do you have a password to secure your account with, you’re also sent login codes through SMS, or more preferably these days, an authentication software such as Google Authenticator.

My guess is that most people are not aware of why this is necessary, and perceive it as an unnecessary complexity. However, given the fact that with someone’s email account, you can usually recover a major portion of the passwords from every other website, securing your email and social media accounts with SMS codes or app verification is absolutely vital.

3. Online banking authentication methods

Because I wanted full anonymity, I disabled IP address tracking in my survey; however, that also meant I lost the capability to check the origin country of the survey results, which would have been interesting.

It seems largely evenly split between using some kind of authentication service (Bank-ID was mentioned in the options) and using passwords with security questions.

My guess is that it’s rather evenly split between U.S. banks and Swedish banks. U.S. banks typically use passwords with security questions (which is rather behind the curve and poor security for banks), while Swedish banks rely on the BankID infrastructure – which is much more cryptographically secure.

An increasing trend seems to be sending security codes with email or text messaging – which is already outdated and once again proves the absolute necessity of securing your email account – and very few rely on one-time passwords (codes written on paper), which is highly secure but pose more cost and complexity in administration.

4. Password recovery

The most interesting divide between users with higher IT competence and not is the method to remembering or recovering passwords. IT professionals mostly use passwords stored online, while common users rely more on their memory. Unfortunately the human mind is not suited well to remembering complex passwords – the more random, the better, and the mind wants to remember patterns which can easily be exploited.

An interesting point is that so many rely on online password storage, while very few rely on offsite storage. The danger, of course, with online storage is that you also rely on the protection mechanisms of the online provider – and should that get breached, your entire online life is fully and completely exposed.

5. Password complexity

As expected, most common users rely on variations of word patterns, with capitalization and the odd digit thrown in. As IT security competence increases, so does password complexity, and it’s good to note that security professionals are trending towards full randomization of passwords with included punctuation. While horribly difficult to remember and in some cases to type in, one would assume that these passwords are protecting administrative accounts to a larger extent, which could exponentially increase the severity of a hack.

However, there is still a firm reliance on using words as passwords. Given that the English language has about 250,000 words; and a modern, GPU-powered password cracker can easily try 100 million passwords per second on lower-complexity password hashes; using variations of words is becoming increasingly dangerous.

With proper security implementations – for instance, using salted bcrypt/scrypt hashes or similar for password storage – trying brute-force attacks on passwords should be infeasible; but as we’ve so often seen, developers frequently use poor hashes to store passwords – or even storing them as plain text.

The danger here is that if one password is used for many websites, it only takes one breakthrough on a poor-security website to access the password, and hackers can then move laterally through different systems in the search for deeper security access.

6. Training

I added this question to gauge the interest in either online videos or local classes when it comes to computer security. Among the people responding, almost half would be interested in watching an online video, while the rest felt that they did not need training or that they already knew enough. There was a trend among security professionals to not be interested (because they already knew enough), but not completely.

Perhaps it would be interesting to put together a training video and see if it’s possible to educate people on online security and password management. I have to wonder if I’m the best instructor, though, since I rely on KeePass for offline password storage and other rather complex mechanisms… ūüôā

Final thoughts and recommendations

It is clear to me that passwords have outlived their usefulness, and that we’re heading for authentication tokens instead – long, cryptographically complex strings that allow us to access resources and identify us with – which are, of course, impossible to memorize but can easily be handled by computers.

However, the infrastructure today doesn’t really exist. In the meantime, online password management seems to be a clear trend, and with each cell phone iteration we’re looking at more biometric security systems… which have the unfortunate drawback that once they’re hacked, it’s practically impossible to change the biometric signature (your iris or fingerprint).

My short recommendations are as follows:

  • Use different passwords for every website.
  • Use the password memory feature of your web browser (Firefox, Google Chrome) to remember the passwords. It’s a good idea to enable synchronization – the web browser should be doing that automatically if you’re logged in to it.
  • You may also want to look into password managers – LastPass, 1Password and others are popular. If you have the skill to do so, you may want to use an offline manager such as KeePass or KeePassX – but do take backups!
  • For higher-value websites, such as email, social media and financial institutions, do enable 2-factor authentication if at all possible.
  • For banks or any other websites which can have dramatic life implications if they get hacked, avoid letting any web browser store the password. Use a good password manager or write it down somewhere out of sight.

For work users, it’s very important to stay vigilant, follow the work security policy and keep the rules above in mind. Surprisingly often, hackers gain entry to a high-value target by hacking a regular user and then moving laterally through the inside systems, looking for further security weaknesses to exploit.

Thank you for participating!

Faith? Or Science? Or Both?

I’ve always loved science.

Science, to me, represents the quest for understanding; the peeling back of the layers of our world and figuring out how it all works. It is the believe-nothing, question-everything-until-proven approach that demands hard evidence and rigid logic before it accepts anything, in its ongoing mission to seek out the truth. And, judging by the results, it seems to work pretty well. I like it a lot.

But here’s the crux: I’m also a Christian, believing in a God that we cannot see nor measure. Anyone who has ever tried to prove the existence of God (and there have been many) has always failed, hard; and the various reasons presented why God should exist rarely survive long in the face of scientific rigor.

Reconciling these two viewpoints is an interesting difficulty – and, thus, people who love science tend to ridicule Christians for believing in something so ghastly unproven, while Christians berate scientists for their lack of faith and cynical view of the world.

It makes me sad, because I really do love both of them. And I don’t find it difficult at all to reconcile the two views; because I’ve come to understand that they both serve radically opposite purposes. The purpose of science is to believe nothing until absolutely and irrefutably proven; the purpose of faith is to believe even in the absence of proof. They are diametrically opposite and yet both necessary: Science exists to reveal the world; faith determines our approach and response to it. If science is the brain of this methodology, faith would definitely be the heart; and trying to live without either brain or heart tends to be difficult.

The thing is, at one point in my life, I bumped into God. It just happened sort of gradually one spring/summer a long time ago – and God, in his usual custom, asked me if I wanted to follow him; just like he did with his disciples two millennias ago, and with everyone else ever since. I said yes, and thus I began a rather different path through life. I didn’t make this choice because of the great eloquence of the gospels, or the amazing rationality therein (there is, but it’s somewhat hidden); there was no great proof convincing me. Rather, I made the choice simply because I met him, and I have walked with him ever since; and furthermore he insists that he wrote a book called the Bible, and that this book constains the truth.

There are, of course, areas of conflict here. The Bible claims that God created the world; science doesn’t specifically refute that (largely due to a lack of authoritative scope), but at least insists that the world must be a lot older than the claimed six thousand years. I… personally tend to lean towards the scientific side of things, simply because I feel the bible was never meant to be the amateur astronomist’s guide to the universe; the purpose of the bible is to reveal God and his plan for salvation, and those bits and pieces that deals specifically with the big bang, the formation of the world and the organization of the universe are rather hastily glossed over, perhaps to the benefit of the people who wrote it 3500 years ago and who had only the most rudimentary understanding of Kepler’s laws of planetary motion.

All I can do is to really just shrug my shoulders, and say that I wasn’t there when it happened. I don’t know. Ideally, if both science and faith are correct, they should at one point align with each other and confirm each other (scientific truth confirming biblical truth). Whether that happens on this side of eternity or not, I don’t know.

In the meantime, I keep coding.

Gingerbread Christmas Tower

Behold —

A stately tower now was made
With candy, frosting and decor;
Three ginger levels keenly laid
Upon another there did soar;
And the peak in brilliance alight
With candied decoration bright
Shone forth on white and frosted floor.
    Each level carefully aligned –
    A testament to bakery refined,
O, tower, harbinger of Christmastide,
Bring forth thy season glorified!

Steps to Greater Happiness and Fulfilment of Joy with Dropbox and KeePass

I use Dropbox and KeePass together to manage all my passwords; for websites, email accounts, PIN codes and everything else. I use KeePass because I don’t trust online services to store my passwords for me; I want them at home, private, where only I can see them and no one else. However, it takes a little bit of effort to set this up – but it’s well, well worth it. Here’s how I do it:

Set up Dropbox

  1. Install Dropbox from
  2. If you do not have an account, sign up for an account with your email address. Otherwise, log in. If you do not remember your password, set a new password using the account recovery mechanism (click on “forgot your password”).
  3. You should now have access to your Dropbox account, and there should be a Dropbox folder on your computer, which you can access either by double-clicking on the Dropbox icon in the system tray (or the desktop), or by navigating to the dropbox folder using the regular file access views in Windows (so called Windows Explorer).
  4. If you want to change the location of the Dropbox folder, you may do so by doing the following. This is an optional step and is not necessary, but can be useful if you want your files in a different location.
    • Click on the Dropbox icon in the system tray
    • When the little window appears with Dropbox notifications, click on the cogwheel in the upper right part and select Preferences.
    • Select the Sync tab in the Dropbox Preferences¬†window.
    • Click the Move¬†button under Dropbox folder location¬†at the bottom.
    • Select a folder on your computer where you want the Dropbox folder to reside. Do not include the actual “Dropbox” in the folder name; if you want the dropbox folder to be D:\Dropbox, just select D:\¬†as the location – this is useful if you have two hard disks and want the dropbox files on the second hard disk, separated from the system drive.
  5. I also recommend putting your Desktop inside the Dropbox folder, so everything on the desktop is automatically backed up. Usually people put a lot of things on the desktop, and it’s good to have that backed up. The downside is that everything on the desktop will have a little green check-mark on it, but it’s well worth it. (This applies to Windows 10, specifically, but probably works in other Windows versions too.)
    • First of all, in the Dropbox folder, create a new folder somewhere called Desktop. It can be anywhere; I like to create a folder called sys or system¬†and underneath that one keep things like the desktop folder, and so on, so I keep them separated.
    • Open the File Explorer (or just about any folder on your computer works too).
    • On the left, you should have a list of folders, like Desktop, Downloads, Documents, Pictures and so on. Right-click on Desktop¬†in this list, and select Properties.
    • Click on the Location¬†tab, and click on Move. Navigate to the new folder you created for the desktop in the Dropbox folder and click Select Folder; verify that the dialog box now shows you the new desktop folder in Dropbox, and click OK.
    • All of your desktop files should now be synchronizing with Dropbox.

Set up KeePass

  1. Now we’re going to set up KeePass. If you don’t have KeePass, download it from and set up a password database as needed. Please choose the Installer for Windows¬†and the most recent version (2.x something).
  2. Install the program, and create a new database. Be sure to have a good, strong password; something like “I always eat 52 pizzas!” Don’t make it too long – you have to type it in on your phone as well. (Of course, if you already have a password database from before, simply move it inside the Dropbox folder and make sure it gets the little green check-mark on it.)
  3. Add a few passwords for good measure. Save the file somewhere in Dropbox.
  4. After this, it might be a good idea to head over to the menu option File > Database Settings in KeePass, and look under the Security tab for Iterations. Increase the number significantly (to at least 100,000) and use the Test button to find a number that results in about ~0.1 seconds. This is a computing-intensive step that will harden access to your database and make it utterly impractical to run brute-force passwords crackers against it. (Bear it mind that your cell phone may not have the computing capacity of your computer, and will likely take a little longer to open the database. 0.1 seconds should be good.)
  5. Once again, make sure the KeePass database is saved inside the Dropbox.
  6. You should now be able to access the password database from anywhere, as long as you have access to your Dropbox account and a KeePass program that can read it. Please do not do so from any computer you don’t absolutely trust, as the data stored in the password database is a gold-mine for criminals.

Accessing the KeePass database from your Android phone

  1. To access the password database from your Android phone, start by installing Dropbox on your phone, and log in. Make sure you can see your files.
  2. Open the Play Store and install KeePassDroid by Brian Pellin.
  3. Now, go back to Dropbox, and navigate to your password database. Click on the little menu icon (the three dots) on the right side of the password file. Select Available offline. Your password database should now automatically be available offline and visible under the Offline files section in the Dropbox main menu.
    • Please note that Dropbox will not automatically synchronize it unless you actually open Dropbox. For this reason, the recommended way to access the file is to go through Dropbox – this will ensure that it’s properly updated before you use it.
    • It is possible that there are better alternatives than Dropbox – someone mentioned DropSync. I have no experience with this.
  4. Now, by clicking on the password file in the Dropbox offline section, KeePassDroid should automatically open. (If it doesn’t, try “Open With”.) Enter the password, and behold the glory and joy of having all your passwords instantly accessible on your phone, and yet securely.
    • I try to only use the computer to actually update or change the passwords; I’m not 100% confident that those Android apps will make changes to the password database without problems. If there’s anything you don’t want, it’s a corrupted password database.

That should be it.

Aggregated Fail States

The concept of a program failure, in the mind of a software developer, usually takes the form of a boolean or an exception. It’s either true or false, fail or no-fail.

But sometimes you come across more subtle error states – and this is especially true with web-based applications or applications that consume external services. Temporary errors, due to connectivity issues, pop up from time to time, and handling those correctly means the program has to have some sense of whether the error is temporary, localized, important-enough-to-abort, and handle multiple errors at the same time.

Collecting data from Facebook API’s, for instance, can result in most calls succeeding, but one or two failing. Maybe Facebook deprecated a particular metric. Maybe there’s packet loss on the way. Maybe there’s a slight temporary error… and sometimes there are just hard failures (like authorization failures where access tokens have expired).

I am moving to something I call a ResultState. It’s a simple class that looks something like this:

    public class ResultState
        public bool Success { get; set; }
        public bool Finished { get; set; }
        public int TryCount { get; set; }
        public List<LogEntry> Messages { get; } = new List<LogEntry>();

        public bool Retry(int maxAttempts)
            Finished = TryCount++ >= maxAttempts;
            Success = false;
            return !Finished;

        public void Set(bool successful, LogEntry message = null)
            Finished = true;
            Success = successful;
            if (LogEntry != null)

It’s a simple class I’m using in a Batch Call function – every request inside a batch request is capable of being successful, not successful, or unfinished (retrying). The Batch Processor will keep submitting the request to the external API until all calls are complete – whether they ended in a failure or not.

    // Run batch request
    do {
    } while (!batchItems.All(x => x.Finished));

    // Dump messages to application log
    Logger.Write(batchItems.SelectMany(x => x.Messages).ToList());

The important thing is to constantly be able to feed upper-level methods with a “state” – the LogEntry object carries a descriptive message along with a severity code that allows the main process to evaluate the severity of the situation and take appropriate action. Indeed, from the Batch request it receives a List that describes all the various states and errors that were returned. It runs a Distinct() on these to feed the end result to the user.

For headless operations (where a process runs activities in the background), there are several consumers of ResultStates that might be interesting:

  • Upper-level methods and diagnostic software that must act on the information.
  • System operators, responsible for monitoring and debugging the software.
  • End users that are interested in the result of the operation, and need to know when or why things are failing.

Nothing is worse than running an automated job and receiving no response whatsoever whether it failed or ran successfully. And nothing is more frustrating than to receive a simple “failed” status back without any indication as to why. Aggregated fail states that can bubble up messages from individual methods are necessary in communicating just what happens, and why. Ideally, a system operator should be able to investigate the failure by just looking at easily accessible web-based logs.

Windows CMD reference

I spent a part of yesterday looking through all the commands in Cmd.Exe (the Windows command shell, inheritor of the old COMMAND.COM). It’s interesting how they’ve added switches and stuff to improve on it since the early days, but how almost nobody seems to use it. Admittingly, it’s a far cry from bash, the Unix command shell, but there’s a few old tricks you still can pull out of the hat. People may flame it and despise it, but I always thought you should be able to do more with the good ol’ shell.

Here’s a few of the things I found … in alphabetical order.

ATTRIB [/s] [/d]

Changes file attributes. /s makes it recursive, /d makes it operate on directories as well. I didn’t know about these switches before. Handy.

CALL :label arguments

Neither did I know you could call a label in a batch file. This should make it easier to write “gosub”-like routines. And the parameters can be expanded with new interesting features, see below. To exit from the subroutine, use the “goto :eof” statement.


Schedule a check-disk on next boot. Might come in handy sometime.

EXIT /b [errorlevel]

Exits the command shell. If you use the /b switch, exits the current batch file. You can also pass an errorlevel along.


Pressing F7 brings up the history list. How come I never knew that?

FINDSTR [/r] [/c:]”search string” filespec

Find strings in files. I might still use Turbo Grep, but this is cool too. Normally it searches using an OR pattern on the search string (meaning “I love you” finds all instances of “I”, “love” or “you”), use the /c: switch to make it an AND search.

The /r parameter turns the search string into a regexp. Note, some of the fancier stuff might not work as usual, consult the FINDSTR /? or the online help for further information.

FOR %%v IN (set) DO …

The FOR command is one of the coolest features in batch programming. I had no idea you could do so much with it.

FOR %%f IN (dpr pas dfm res) DO COPY *.%%f \deploy

Copy all Delphi source files for a project to a specific directory.

FOR /d %%d IN (set) DO ...

Match directories in wildcards instead of files.

FOR /r [path] %%v IN (set) DO ...

Recursive operation on files found, optionally operating relative to “path” instead of the current directory. It might be used like “FOR /r c:\deploy %%f IN (*.*) DO ATTRIB -r %%f”, which will recursively remove the read-only attribute from all files in c:\deploy.

FOR /l %%v IN (start, step, end) DO ...

For-loop. “FOR /l %%v IN (1, 1, 5)” gives the sequence 1 2 3 4 5.

FOR /f ["options"] %%v IN (file-set | "string" | 'command') DO ...

The /f parameter is probably the most interesting feature I’ve found. It reads lines from an input file, string, or result from a shell command, tokenizes them and processes a command for each line. Normally, the token delimiters are space and tab, and it usually operates on the first token found, so without extra options you will always get the first word in each line. But it can be modified with the following options:

eol=c             Set the end-of-line character. One character only.
skip=n            Skip n lines in the beginning.
delims=xxx        Delimiter set, default is space and tab.
tokens=x,y,n-m    Which tokens to feed into the command. Variables start at the variable 
                  given, and allocates further as needed in alphabetical order. * means
                  "the rest of the line".
usebackq          Use backticks instead of apostrophe for the command evaluation. The 
                  format changes to ("file-set" | 'string' | `command`). Required if you 
                  use filenames with spaces.
FOR /f "eol=; tokens=2,3* delims=, " %%i IN (myfile.txt) DO @ECHO %%i %%j %%k

Parse each line in myfile.txt, ignoring lines that begin with semicolon, pass 2nd and 3rd tokens into the command, separating each token my either comma or space. Notice how the sequence goes: %i, %j, %k.

FOR /f "usebackq delims==" %%i IN (`set`) DO @ECHO %%i

Enumerate all variables found.

Expansion of variable parameters is also available, see below.

GOTO :eof

Jump to end of file. Handy way of exiting from a script.

IF comparisons

IF [NOT] EXIST filename ...
IF [NOT] string1==string2 ...
IF [/i] string1 EQU|NEQ|LSS|LEQ|GTR|GEQ string2 ...

The normal IF command is enhanced, too. It can check errorlevels as before, file existance, and compare strings. But is also has new operators. For instance, the “IF ERRORLEVEL 3” statement can now be written “IF %ERRORLEVEL% LEQ 3”.

/i means case-sensitive (or case-insensitive, I forgot which). Numeric strings evaluate as numbers, not strings.

IF now also supports multi-line statements and ELSE statements, see below.

MD \a\b\c\d

Will create new directories in sequence.


Extended more. These keys are available:

P n     - next n lines
S n     - skip n lines
F       - next file
Q       - quit
=       - show line number
?       - show help line
space   - next page
return  - next line


Start from line n.

PUSHD \\server\path

Create a temporary drive allocation, starting from Z:, for the particular UNC path. This will be cleared with POPD.

RD /s /q

Very dangerous command.


SET [var[=[value]]]
SET /a [var=]expression
SET /p var=[prompt]

SET only will display all variables. SET P will display all values starting with P. SET P= will clear variable P.

SET /a will perform a calculation, for instance SET /a X=2*2 + 5.

SET /p will prompt for user input and store the result in a variable.


Make local changes to the environment. Work all you want with it, then call endlocal to revert back to where you were. Also handy, especially with some of the advanced SET features.

SHIFT [/n]

Shift parameters. Optionally start at the nth position, preserving all elements %0 .. %(n-1).

SORT [/+n] [/o outfile]

Sort may start sorting at the nth position now. Could be good for unwanted stuff in the beginning (timestamp in logs, perhaps). /o is faster than piping.

Interesting ways of treating variable expansion

Some new ways of treating variables are available. Like, string substitution and substring matching.

%PATH:str1=str2%      Substitute all occurrences of str1 with str2.
%PATH:~10,5%          Substring, start at position 10 and extract 5 characters.
%PATH:~-10%           Only get the last 10 characters.
%PATH:0,-2%           Extract all but the last 2 characters.

%CD%                  The current path
%DATE%                Current date
%TIME%                Current time
%RANDOM%              A random number between 0..32767.
%ERRORLEVEL%          The current errorlevel.

%*                    All arguments
%0 .. %9              Arguments
%~1                   Remove quotes from parameter 1
%~f1                  Expand to fully qualified filename
%~d1                  Expand to drive letter only
%~p1                  Expand to path only
%~n1                  Expand to file name only
%~x1                  Expand to extension only
%~s1                  Expand to short file name only
%~a1                  Expand to file attributes
%~t1                  Expand to file date/time
%~z1                  Expand to file size
%~$PATH:1             Search through all directories specified in %PATH%. If the file is found,
                      return the fully qualified filename in that directory. If the file isn't 
                      found, return blank.
%~dp1                 Expand to drive and path. (Further elements may be combined: 
                      %~ftza1 gives a DIR-like output)

Interesting ways of doing IF and FOR statements

There’s a syntax I’ve never seen either with IF and FOR statements. You can use IF-ELSE-syntax in this way:

IF EXIST hello.txt (
    DEL hello.txt
) ELSE (
    ECHO hello.txt is missing!

…or even…

IF EXIST hello.txt (DEL hello.txt) ELSE (ECHO hello.txt is missing!)

And how about this?

FOR /l %%v IN (1 1 5) DO (
    ECHO This is line number %%v.

The crucial thing seems to be, in ELSE statements, that ELSE has to be written “on the same line” as the IF statement. This is why ELSE is written on the same line as the parantheses.

So there you are. A whole new way of writing batch files. No extra software needed, just plain old Windows XP.