Yesterday, Microsoft delivered to us a bouquet of a dozen patches, just in time for our Valentine’s Day celebration today. With those patches, and a recent inundation of other vulnerabilities (Solaris Telnet? Are you kidding me?), I’d like do a quick change of pace to give you a couple of fun tips for using the Windows command line.

It’s become something of a ritual around here. Whenever I’m Handler on Duty, I reinforce my ultimate goal of eliminating the Windows GUI from use by administrators and incident handlers by writing a tip or two for using the Windows command line. One of the most frequent questions I get recently whenever I teach a SANS session on the Windows command line involves searching for files with a given name. Suppose, for example, that you want to find the program wmic.exe in your directory structure. There are two approaches I use:

First, you can change into a given directory that you want to search (such as C:\windows\system32), and then run the dir command appropriately:

C:\> cd c:\windows\system32
C:\> dir /s /b wmic.exe

The /s means that we want to recurse subdirectories. The /b means that we want the bare form of output (which will omit the volume information, ., and .. from our listing). When /b is used with /s, it will print out the full path to the item for which we search (context-specific command flags that change their behavior in light of other flags can be trouble for memorization, I admit). The downside of doing this is that you have changed out of your current directory to do the search.

But, diligent readers Michael Wilson, Chris Wolf, and a reader desiring anonymity have pointed out that you can search for something without changing your current directory by running the command thusly:

C:\> dir /s /b c:\windows\system32\wmic.exe

It looks like this command would only find a wmic.exe if it is system32 itself, but it actually looks through system32 and all of its subdirectories, doing just what we want. Pretty cool! And, you don't lose your current directory in the process.

The second approach is to use the dir command again, but to scrape through its output using the find command, as in:

C:\> dir /s /b c:\windows\system32 | find “wmic.exe”

The first approach has better performance (because we are not scraping through Standard Out).

Oh, and another frequent question I get: How can I do a line count on the output of another command? UNIX and Linux folks frequently use “wc –l” to count stuff…. How can we do this in Windows? Suppose, for example, you wanted to count the number of files and subdirectories inside of c:\temp. There is no wc command built in, but here is a method I use:

C:\> dir /b c:\temp | find /c /v “~~~”

The dir command gets a directory listing, in bare format (/b) of c:\temp. I use the find command to count (/c) lines that DO NOT contain (/v) the string ~~~. It would be very unusual to have that string, so it gives me a pretty accurate line count. If you are really concerned about having such lines, you can run it without the /v and make sure the count is 0. Also, you can recurse subdirectories using /s, as you might expect. And, this technique can also be used to count other things, like the number of running processes called svchost.exe, using the tasklist command (built into Win XP Pro and 2003):

C:\> tasklist /fi “imagename eq svchost.exe” | find /c /v “~~~”

Don’t forget to subtract the appropriate number of column headers and footer lines from your output (in the case of tasklist, you have to subtract 3, because of the Column titles, the ===== under the columns, and an extra carriage return it puts at the end). Attentive reader Chris Luhman mentioned that you can use the /nh option in tasklist to get it to omit the header (nh stands for no header). Then, you'll only have to subtract one from the output. It is an odd but recurring thing in Windows command line tools. They often put an extra line at either the beginning or the end of their output. I see this a lot with wmic.

Oh, and there are other things you can do with the line count method I've described above. For example, to count the number of lines in your win.ini file, you can use the type command (the rough equivalent to the UNIX cat command):
c:\> type c:\windows\win.ini | find /c /v "~~~"

And the list goes on and on...

This is a rather contrived way of doing a line count, but it works very nicely for me. If you know of a better way, using only built-in Windows commands, please let me know.