Get started Bring yourself up to speed with our introductory content.

Automate security with GUI shell and command line scripts

JP Vossen explains how Windows command line scripts and the GUI shell can be used to improve security.

Windows' ubiquitous point-and-click GUI has made command line scripting one of the OS's most underutilized features.

The Unix world calls them shell scripts. The DOS world calls them batch files. Whatever you call them, command line scripts are easy to forget in the GUI world of Windows. While scripting on Windows isn't as powerful as on Unix, some of the improvements introduced in Windows NT 4.0 may surprise you. Scripts are ideal for ensuring consistency, for scheduling periodic tasks and for automating tedious tasks. In other words, they're perfect for security.

For example, you can use shell scripts to periodically search a file server for "contraband" files, to automate server-hardening tasks, to filter relevant events out of large log files, to add or delete user accounts, and for just about anything else you can think of. Any multistep process that needs consistency every time it's performed and that can be done from a command line is a candidate for scripting.

Although useful for augmenting security and other tasks, scripting can also get you into trouble. If not done correctly, scripting can open new holes and create new vulnerabilities in critical system processes.

Shells and Scripts

In their simplest form, shell scripts are text files containing a list of commands that you could have typed in on the command line (also known as the DOS Prompt). Remember that a "shell" is the interface between you and the operating system -- the place where you tell it to do things.

The default MS-DOS shell was This command line shell remained unchanged in Windows 9x, but explorer.exe -- a GUI shell -- was added. Explorer.exe runs in several modes in Windows. The first mode is the main GUI shell itself, which creates the Windows desktop, Start menu, etc. Other modes are the file and directory browsers, which may look different depending on how they're invoked or run.

The GUI shell in Windows NT/2000/XP is still explorer.exe, but the command line shell is now cmd.exe-DOS is finally gone (note how the shortcut changed from DOS Prompt in Win9x to Command Prompt in NT and above, though the NT 4.0 icon still says "MS-DOS"). Beginning with NT 4.0, cmd.exe includes command extensions (the NT 3.51 cmd.exe doesn't have them) that are turned on by default and controllable with the /x switch. They extend the old DOS batch file language (BAT), making it more powerful and flexible. It's still not as good as Unix shells, but it's an improvement over DOS.

The old .bat filename extension still works, but the .cmd extension was added. In NT 4.0 and above, both .bat and .cmd are recognized as executable (i.e., batch files or shell scripts). However, Windows 9x doesn't recognize command extensions or scripts named with .cmd, even if all of the commands would otherwise have worked. Therefore, it's a good idea to name scripts that use command extension features with a .cmd so you don't try to run them on a Windows 9x machine (see "Sample Scripts," p. 68).

Windows Scripting Host (WSH)

When you need GUI control during scripting, this tool gives it to you.

One of the limitations of command line scripting in the Windows environment is that sometimes you need to control a GUI program, or aspects of the GUI. Cscript (command line) and wscript (GUI) are the script engine components of WSH that allow you to run things like Microsoft JScript or VBScript as standalone scripts. There's also a facility to allow you to push keystrokes into a GUI application.

An example of this GUI control is using command line scripting to set the keyboard repeat delay to short and repeat rate to fast. The following script uses the Control Panel's Keyboard applet to set these speeds.

' KRate.vbs - (Re) Set keyboard rate to maximum in Windows

' v1.0 30-May-2001 JP Vossen

' Information Security Magazine, February 2002

' My KVM switch sometimes causes my Windows machines to "forget" that the

' keyboard repeat rate is set to the maximum. If you go into Control Panel,

' Keyboard, fiddle, Apply, set to max and save, it works again for a while.

' If WSH is properly installed, and .VBS properly registered, typing "krate"

' on the command line will open the GUI window, adjust the rates, and close

' the window.

set WshShell = CreateObject("WScript.Shell")

WshShell.Run "control keyboard"

WScript.Sleep 800

' Lower the sliders for Repeat Delay and Repeat Rate, then Apply

WshShell.SendKeys "{left}{tab}{left}%A"

' Raise the sliders for Repeat Delay and Repeat Rate, then hit OK

WshShell.SendKeys "4{right}{tab}4{right}{enter}"


Shell scripts are written to run under a particular shell, like cmd.exe or the Unix default Bourne shell (sh). But they aren't the only type of scripts. There are lots of scripting languages to choose from, each with varying degrees of complexity, flexibility and suitability for particular tasks. Some are prevalent in the Unix world, like Tcl or Expect. Some are prevalent in the WinTel world, like REXX. And some, such as Perl, have crossed into both. There are also several scripting languages specifically for and in Windows, including KiXtart and Windows Scripting Host (WSH) (see box, above). Visual Basic for Applications (VBA) is arguably a scripting language, and WinBatch (and similar programs) has various built-in scripting facilities.

Alternative shells for Windows, such as 4DOS and 4NT from JP Software, also exist. These replacement shells provide enhanced standard commands, many new commands, improved command line editing and batch file language, and many additional built-in variables and functions. There are various free and commercial ports of Unix shells -- such as the default Bourne shell (sh) and the Bourne Again Shell (Bash).

Note, if you use Unix shells or commands under Windows, they'll probably be case sensitive, unlike regular DOS or Windows commands. And where Windows uses a backslash ( \ ) as a directory separator and a forward slash ( / ) as a parameter separator, Unix uses the backslash as a line continuation character, the forward slash as the directory separator and a dash ( - ) as a parameter separator.

Interpreted, Not Compiled

Just as James Bond prefers his martinis "shaken, not stirred," scripts and shell scripts are "interpreted, not compiled." This means the correct interpreter must be present each time they run.

The interpreter reads the script line by line and executes it. The interpretative nature of scripts has advantages and disadvantages. The disadvantages are that the interpreter must exist on every machine a script will run on, and it will run significantly slower than compiled programs, such as C or C++.

Some advantages are that most scripts are relatively small, since the interpreter contains the binary code that actually executes. And since they're in a plaintext read/write format (unlike compiled binary programs), most people can review them to understand what they're doing and edit them to do needed tasks. They're also usually simpler and easier to understand than many "regular" programming languages, such as VBS or C++.

As with all programming environments, the ability to use variables is key. Variables hold data assigned to them until the user or the script changes it. With looping functions, they form the basis for the control structures that allow you to automate and execute a task. With variables comes greatly expanded flexibility and adaptability. Without variables, the best you can do is automating a series of static commands. For example, the script fragment "copy c:\winnt\system32\?script.exe c:\adminutils" will fail unless the Windows directory is "c:\winnt." If your system is set up properly, the variable "%YSTEMROOT%" in the script fragment "copy %SYSTEMROOT%\system32\?script.exe c:\adminutils" will always work.

Pipelines and Redirection

Another critical scripting concept is pipelines, which in turn depend on redirection. Pipelines and redirection are part of the philosophy upon which Unix was built, but many people are unaware that they can also be used in Windows.

Redirection deals with the virtual devices, including STDIN, STDOUT, STDERR and pipes. STDIN is the so-called standard input -- usually the keyboard. STDOUT is the standard output-usually the screen. STDERR is standard error, which is also the screen but uses a logically different data stream.

Understanding the different redirection pathways is important, since you'll want to send data to the proper destination. The simplest form of redirection is just sending a command's output to a file-such as the fragment "dir %SYSTEMROOT%\system32\*.exe > c:\Sys32-Files.txt," which redirects the listing of a the .exe files in a system directory into the test file "c:\Sys32-Files.txt." You can then open and modify this file in Notepad or any text editor.

Redirection is a powerful tool when it's taken a step further to create pipelines, which are the redirection of one program or command's output into the input of another. Pipelining can create complex results by chaining small programs together. This is a key concept in the Unix design philosophy. For example, say you need to know what your IP address is, but you don't want to see any other information, like your default gateway.

This simple pipeline will provide the correct IP address:

Pipeline command: C:\> ipconfig /all | find "IP Address"

Actual output: IP Address. . . . . . . . . . . . :

This is handy, but what if you just need the IP address itself, without the text label and all the spaces and dots? Well, there are a lot of options here, but since our focus is built-in Windows functionality, here's an effective (though, admittedly, not very intuitive) solution.

This pipeline will provide just the IP address itself:

Pipeline command: C:\>for /f "delims=: tokens=2" %X in ('ipconfig / all^|find "IPAddress"') do @echo %X

Actual output:

There are several things to notice about this command. First, it may not be obvious, but in the output there's a leading space before the numeric IP address, which could be a problem if you plan to use the output as input into another script or program. Second, a caret (^) is used to escape the pipe ( | ) before the find command. This has to do with the way the cmd.exe shell parses the command line.2

Another note of interest is that the use of the text parsing function of the "for" command (an NT 4.0 and above command extension function) is a way to get output from some external command into your script. This is trivially easy in Unix -- you enclose the external command in backticks ( ` ) -- but quite arcane in Windows.


Commonplace in Unix, filters are often a foreign concept in the Windows world. A filter-type program is intended to do something to data flowing from a source (usually a file or another program's output) to a destination (usually a file or another program's input).

Suppose you want to see what ports your computer is listening on. You can use "find" with the /I switch (which makes it non-case sensitive) as a filter between netstat and sort. Due to the lack of leading zeros, or a "numerical" option, the sort order isn't always what you might expect or want. For example, the command "C:\> netstat -an | find /i "listening" | sort" will produce a response of:












Contrast this with the usual output of netstat, which is several screens long and shows a lot of other information besides what ports are listening. Find has been used to filter data flowing between the netstat and sort commands, so you only see what you're interested in. Don't get confused by the word "filter." Find, sort and other filter-type programs can be used to add or change data -- not just to remove it. Filters are really just an intermediate step in processing the data "in-line," so to speak.


The built-in tools in the Windows command line environment are useful, but sometimes lack needed functionality, flexibility and consistency. For example, there's no way to send e-mail from the command line using only native Windows tools. Likewise, the native Windows date and time commands don't have flexible output formats and don't lend themselves to easy use in scripts. These limitations sometimes make the use of third-party tools desirable or even unavoidable.

Fortunately, there's no shortage of tools for filling these gaps. Some are commercial, such as the incredibly useful Windows Resource Kits from Microsoft and the replacement shells from JP Software. There's a huge array of excellent free tools available as well, such as Blat (for sending e-mail from the Windows command line) and various ports of Unix utilities. As mentioned above, part of the Unix design philosophy was the ability to chain small single-purpose utilities together to perform complex tasks. With the advent of these tools on Windows, this power and flexibility may be applied to Windows administrative and security tasks.

The Windows Resource Kit utilities provide a great many tools for use on the command line, such as SC, the Windows service controller; NTRights, which allows you to grant or revoke NT user rights; xcacls, an improved version of the built-in cacls for administering NTFS ACLs, and many more.

Some resource kits also bundle a version of Perl and a Perl module ( that provides an object-oriented Perl API to the Windows Management Interface (WMI). This allows you to change your IP address, view or change NTFS permissions, set disk quotas, and perform user administration and a whole lot more from within a Perl script. One note: the ActiveState Perl provided with the Windows Resource Kits is usually quite old. You'll want to get a current version free from ActiveState.

Scripting Resources

Scripting Languages

ActivePerl is ActiveState's quality-assured binary build of Perl, available for Linux, Solaris and Windows.

ActiveState's quality-assured binary build of Tcl, available for Linux, Solaris and Windows.

A binary build of Perl 5.6 for Win32, with an integrated Apache Web server for testing and developing CGI scripts.

KiXtart 95
A logon script processor and/or enhanced batch language for Windows 95/NT workstations in a Windows Networking environment.

A server-side, cross-platform, HTML-embedded scripting language.

This page links to documents relating tothe REXX, Object REXX and NetRexxprogramming languages.

Tool Command Language (Tcl/Tk)
Tcl is a language and a library intended primarily for issuing commands to interactive programs. Tk is a graphical user interface toolkit that makes it possible to quickly create powerful GUIs.

Windows Script
A comprehensive scripting infrastructure for Windows.

Tools & Resources

Auditpol, xcacls.exe, Reg.exe, regini.exe
Various tools for displaying or modifying auditing (logging) policies, editing NTFS ACLs and accessing the Windows Registry.

GNU Utilities for Win32
Common GNU Unix utilities ported to native Win32.

A port of the popular GNU Unix development tools/environment for Windows.

A tool for automating interactive applications, such as Telnet, ftp, passwd, fsck, rlogin, tip, etc.  (For Unix and Windows, requires Tcl/Tk.)

These tools make the C:\ prompt more flexible and robust than the built-in DOS or OS/2 tools. They come with hundreds of new batch file tools as well. And they fully support standard commands such as COPY and DIR, making them easy to learn and use.

The GNU Project's

Official Win32 Ports
The official GNU Unix utilities ported to Win32.

GNU, Semi-compatible tcsh
A Windows port of the Unix tc shell that's mostly compatible with the original tcsh.

GNU, Semi-compatible zsh
A Windows port of the Unix z shell that's mostly compatible with the original zsh.

MKS Toolkit
A commercial package providing Unix tools and services under Windows.

Unix and Unix-like Tools
More Unix-like utilities for Windows.

A port of a Unix environment for Windows by David Korn; free for education or research uses.

Windows Services for Unix
Information and tools for making Windows services interoperate with Unix systems.

Windows Tools for Monitoring Registry and File Systems
Includes advanced utilities, technical information and source code related to Windows 9x/NT/2000/ME internals.

The "Net" Command

Notwithstanding the comments above, Windows does contain a number of useful built-in commands, including the highly underrated and underappreciated "net" command. Usually only used for mapping drives or listing shares, net.exe can change passwords, enable or disable accounts, set or view account lockout and password properties, control and cancel print jobs, and create, modify or delete local and global groups. Try "net user guest newpassword," "net user guest /active:no," "net accounts," and "net/?" for yourself and see what you can do.

While the net command can start and stop services, it does get a little tricky under NT 4.0, since the display name in Control Panel Services isn't necessarily the actual service name needed for the "net stop|start {service}" command. Windows 2000 and XP are little better about displaying all the various names of the services.

Even setting the computer's clock in the autoexec.bat or startup group is possible with the command: "net time \\My CompanyPDC /set /yes." Window 2000's "Windows Time" service also allows you to use SNTP (a subset of the Network Time Protocol that keeps Internet time in sync) to set the clock. But it's poorly documented and a little confusing.

Registry Files

You can't talk about built-in Windows functions for long, especially in a security context, without covering the Windows Registry and REG files. Technically, REG files aren't scripts, but they're important to Windows scripting (particularly for security) because they allow for the manipulation of the Registry.

Files with a .reg extension are associated with RegEdit.exe (9x/XP) or RegEdt32.exe (NT/2000; for XP this is a stub that runs RegEdit.exe). Like scripts, many REG files are simple text files that are interpreted by RegEdit or RegEdt32, though some Windows versions use a binary type of .reg file as well. Even though they're not truly scripts, REG files can be very powerful.

Adding or changing Registry values is relatively easy using REG files. However, deleting values or making decisions based on Registry values isn't possible without some third-party tool (several are supplied with the various Windows Resource Kits). The other notable exception is setting actual permissions on Registry keys, which can only be done by manually using the RegEdt32 GUI interface (RegEdit in XP; not applicable in 9x), the Security Configuration Manager (SCM) or the Security Configuration and Analysis MMC (Microsoft Management Console) snap-in. The trick in creating Registry files is identifying exactly what key to create or change and the value it should be. For example, "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ EventLog\System\Retention" is the number of days for which the system event log is retained. The default value is hex "93a80," which is 604,800 decimal (/60/60/24 = 7 days). If you set it to decimal 24, the results won't be what you intended.

The best way to learn about the Registry is through hands-on experimentation (on a test box, of course). REG file neophytes can find a value, such as the system event log retention setting, then manipulate it with the appropriate GUI tool and see how the Registry value changes. To create REG files, find the appropriate keys, then save or export them to a file (use the REGEDIT4 format if given an option). From there, open the resulting file in a text editor. But don't double click on it; otherwise, it will be re-imported into the Registry. Often, admins can create a useful REG file in this way by exporting the values and deleting any that won't be changed. You can use a semicolon ( ; ) at the beginning of a line to add comments to a REG file, similar to using "REM" (for remark) in a batch file.


Another notable part of Windows security scripting is the Security Configuration Manager/Security Configuration Editor (SCM/SCE) in NT 4.0 and the Local Security Policy and Security Configuration and Analysis snap-ins in Windows 2000/XP. First made available on the NT 4.0 SP4 CD-ROM, SCM/SCE was essentially back-ported from the code that became the Local Security Policy and Security Configuration and Analysis in Windows 2000. These are excellent tools for hardening or locking down most aspects of a Windows computer.

These Microsoft Management Console (MMC) snap-ins are basically an interpreter for security-specific .ini files that allow you to specify a great many Windows system and security settings. When installed on an NT 4.0 computer, one of the effects is that the old NT 4.0 NTFS ACL editor is replaced by the one from Windows 2000.3 Under many circumstances, this isn't desirable. However, under Windows 2000/XP, it's built in, so it's a no-brainer. You'll definitely want to have these tools in your toolkit.

Although not as elegant as in the Unix world, scripting is more than possible in Windows environments. It takes a little time, study and practice to turn this lost art into a productive security tool. As with any coding-like technique, scripting does have a downside that parallels its benefits. If done properly, scripting can augment security functions, making them easier and more robust. But when done poorly, scripting can create more security problems by opening new vulnerabilities or leaving systems open to exploitations (see "Shell Script Security"). Nevertheless, the benefits outweigh the risks, making the pass-phrase for scripting "use with care."

About the author:
JP Vossen, CISSP, is a technical editor for Information Security and an infosec consultant.

This was last published in February 2002

Dig Deeper on Hacker tools and techniques: Underground hacking sites