A few examples of traditional and modern Windows commandline utilities.

Version : 2.1
Date : 06/06/2011
By : Albert van der Sel
For who : For anyone who likes (or needs) to work from the Windows commandline

With respect to the Windows command line, and scripting, nowadays you should do as much as possible with Powershell.
However, if you still need to use traditional "cmd shell" commands and batch scripting, hopefully this note provides
some usefull pointers.

Although the information here is "reasonable", I am not very glad about the formatting and the text itself.
But I leave it here, since maybe someone might have some use of it.

Main Contents:

1. The "sc" command
2. The "netsh" command
3. The "systeminfo", "msinfo", and "msinfo32" commands
4. The "runas" command
5. The "taskkill" or "tskill" command
6. The "driverquery" command
7. The "netstat" and "nbtstat" commands
8. Some examples of commands, to invoke a Graphical Utilty
9. Some examples of commands that enables you to implement scheduled tasks
10. Some examples of handling txt (or ascii) files
11. The "WMIC" command
12. The "typeperf" command
13. The "cacls" command, and similar commands
14. Free (gnu) shells or tools for Windows
15. How to determine your ".NET" (dot net) version, and your "Windows installer" version
16. How to start an application with other priority, from the prompt
17. A few usefull file manipulation commands
18. The "forfiles" command.
19. The "net" command.
20. Determining "svchost" processes.
21. The "rundll32" command.
22. How to determine you are running in a VM or physical machine.
23. Some very very "OLD" batch stuff

1. The "sc" command.

SC is a command line program used for communicating with the
NT Service Controller and services.

sc server [command] [service name] option1 option2...

The "server" parameter takes the form "\\ServerName". If not present, it is your local machine.
You can query on "services", add services, delete services and much more.
Here are a few examples:

1.1 List (a partial) listing of services:

-- list all services:

C:\> sc query

-- put the list in the txt file "C :\temp\services.txt":

C:\> sc query > C :\temp\services.txt

-- Filter the list on (for example) the string "SQL":

C:\> sc query | find "SQL"

You can also use the "traditional" net start command, to obtain a list of running services.
Use that command like this:

C:\> net start

or pause the output to screen (pressing a key to continue), using "| more", like so:

C:\> net start | more

1.2 Add a service:
SC can also be used to add, modify, or delete a service. This section only wants to make
you aware of this option. If you really want to use it, normally more options
should be provided on the commandline. Just compare it to what you normally might find
in the correseponding Registry Hive (like boottype of that service etc..).

C:\>sc.exe create MyService binPath= "C:\local\myprg\bin\myserv.exe -k runservice" DisplayName= "My own Service"

1.3 Starting or stopping a service:
Suppose you want to start or stop the service "myservice"

C:\>sc.exe start myservice
C:\>sc.exe stop myservice

Note 1: Other ways of stopping and starting services:

You can ofcourse also use the traditional "net [start|stop] service_name" command.
Like for example:
C:\> net start MSSQLSERVER

Note 2: Other ways to retrieve a list of services:

Again, you can use the "traditional" net command. Just use "net start", or "net start | more" to pause the output.
But you can also use the (very versitile) "wmic" command, as for example:

C:\> "wmic service" or "wmic process"

Produces a list of services, or processes, with their properties.
For example:

C:\> WMIC /OUTPUT:C:\ProcessList.txt PROCESS get Caption,Commandline,Processid

This produces a file (C:\TEMP\Processlist.txt) with as content a process list, with names, commandline, and process-id's.
For more information on the "wmic" command, please see section 11.

2. The "netsh" command.

This is a very versatile command. As you might already have guessed from the name, the utility is network oriented.
Let's view a few simple examples:
There are two general ways to work with netsh:

- You can use the command with all the options you want, "all in once", right from the commandline, like:

C:\>netsh interface ip show config # This shows you all current IP parameters

- You can enter the shell interactively, and subsequently enter all sorts of submenu's, like for example:

netsh> interface # goto the interface submenu
netsh interface> ip # goto the ip submenu
netsh interface ip>show config # This shows you all current IP parameters, just like above

As you can see above, once you are in the "ip" submenu, you can only use commands with parameters, like:
"show config" This shows you all current IP parameters

A few examples setting IP parameters:

To set the interface called "LAN", to use DHCP for its IP address configuration:
C:\> netsh interface ip set address name="LAN" source=dhcp

To set static IP parameters on the interface called "LAN":
C:\> netsh interface ip set address name="LAN" static

To set a DNS Server entry on the interface called "LAN":
C:\> netsh interface ip set dnsserver "LAN"

A few examples showing IP parameters and diagnostics:

Like already shown above, the following shows you all current IP parameters:
C:\>netsh interface ip show config

As an other example of obtaining information, wouldn't you like a a command
that shows all your interfaces (just like you can easily do in Unix/Linux)?
For that, you can use the "diag" option (or submenu).

C:\> netsh
netsh> diag
netsh diag>show adapter

Network adapters
1. [00000008] Realtek RTL8169/8110 Family Gigabit Ethernet NIC
2. [00000011] Intel(R) PRO/Wireless 2200BG Network Connection

netsh diag>show ip

IP Address
2. [00000011] Intel(R) PRO/Wireless 2200BG Network Connection
IPAddress =

netsh diag>show modem

Modems (ZTE Proprietary USB Modem)

As the last example, here is how you can use netsh to configure your Windows firewall.
C:\> netsh
netsh> firewall
netsh firewall> set portopening udp 3343 "cluster service" enable

Resetting your network parameters:

One usable command for resetting all of your networksettings, might be the command below.
Do not execute it just like that. As an exercise, try to figure out what this command will actually do
on your system:

C:\> netsh int ip reset resetlog.txt

By the way:
- the "getmac" command will show you the MAC address of all your adapters.
- the "ipconfig" or "ipconfig /all" shows you all IP params as well.

3. The "systeminfo" and "msinfo32" commands.

-- The systeminfo command:

If you want a concise report (from the command line) of many system features, and your OS,
you might like the systeminfo command. The report shows many details like the BIOS version,
OS version, cpu info, License key, Hotfixes installed etc...
Note: not all Windows versions have the "systeminfo" command on board.

Just use it like so:


gives a bunch of system info...

If you want to have the same info in a textfile, use a command like for example:

C:\>systeminfo > C:\TEMP\systeminfo.txt

Also, try the "systeminfo /?" for what you can use for special options.
If you are only interrested in your Windows version, you might like the "winver" command,
which shows you a dialogbox with the Windows version, Servicepack level, and build.

-- The msinfo32 command:

If the "msinfo32" command is available on system, you can retrieve much system information,
about nummerous items like hardware (irq's, dma, conflicts etc..) and all software modules like drivers etc..
It will be displayed in a graphical utility, that enables you to "zoom in" into a particular subject.
If you run XP (or newer), it should be on your system.
Just run it from your prompt, like this:

C:\> msinfo32

4. The "runas" command.

The "runas" command, allows you to start a program, with other "credentials" than the credentials
with which you are currently logged on.
So, suppose you haved logged to a workstation as a Domainuser (say antapex\harry), and you want
to run a program as the local Administrator of that workstation, then you can use "runas" for that purpose.
But, "runas" will always prompt for the password of that other account.

From the prompt, use runas:

C:\>runas [/profile] [/env] [/netonly] /user:user Program

/profile|noprofile: Option to load the user's profile (if applicable for a program)
/env: Use current environment instead of user's.
/netonly: Use if the credentials specified are for RAS only.
/user: Username in form of user@DOMAIN or DOMAIN\user (or COMPUTERNAME\user, in case of a local account)
Program: The command to execute

Some examples:

C:\> runas /user:Administrator@antapex.org "mycommand.exe"

C:\> runas /user:WKST10\Administrator "mybatch.bat"

In all cases, runas will prompt for the password.
As alternatives for the Microsoft "runas" utility, you can download other similar tools,
which can be used with a password passed along on the commandline, or stored in a batchfile.
There also exists "luxury" editions which allows you to use an "encrypted" password.

5. The "taskkill" or "tskill" command.

In older versions of Windows, you needed the Resource Kit, in order to obtain the "kill" command.
Since XP (proffesional), the "taskkill" command is a standard feature in the OS.

Taskkill can be of help, in terminating "a runaway" or inresponsive, process.
Ofcourse, you need to be a bit carefull and be reluctant in it's use, but sometimes you do not have
other options.

It's primary use, will be in killing just one process, if you know it's "process id" (pid).
So, suppose the process with a pid equal to 1480, must be killed, then use the command:

C:\> taskkill /pid 1480

And you can even terminate more processes at the same time, for example:

C:\> taskkill /pid 1530 /pid 1603 /pid 1153

You can find the pid, by using, for example, the "Task Manager".
If it's available on your OS, the command "tasklist" is even a much better command.
If still you do not know the pid, you can specify the "image" name. For example:

C:\> taskkill /f /im myprogram.exe

So, if you know the pid, use the "/pid" option. If you want to use the image name, use the "/im" option.
By the way, the "/f" parameter uses a more powerfull signal (force).

Note: If you already use "PowerShell", kill is a predefined command alias for the Stop-Process cmdlet.

But the taskkill command is much more powerfull (and potentially "dangerous"), than just terminating
a single pid (or more than one pid, listed on the commandline).
The command syntax provides even for wildcards and "operators" (filters) like "eq" (equal) or "ne" (not equal).
You can kill whole groups of processes, by filtering on cpu, memory usage, user etc...
But be carefull, if you work on a machine that's more important than just a test machine.

As a few examples of the extended forms of the taskkill command, take a look at the following commands:

C:\> taskkill /f /fi "status eq not responding"
C:\> taskkill /s starboss /u antapex\administrator /p p@ssword /fi "IMAGENAME eq note*" /im *

For more info on taskkill, take a look at:

Maybe your OS does not have the "taskkill" command (like with the Home Editions).
Then you might use the "tskill" command, which however, has lesser options compared to "taskkill".

The (full) syntax is:
tskill processid | processname [/SERVER:servername] [/ID:sessionid | /A] [/V]

So, here you can, for example, just use:
C:\> tskill 1544
C:\> tskill notepad

Note: the "tasklist" command to retrieve a list of running processes.

In Unix, it's easy to get a list of all processes and their properties. For example, just use the "ps -ef" command.
But what can you use from the prompt on Windows?
In section 11, we will see the "wmic" command, which answers the question above.
But to retrieve a list of processes, you might also consider the tasklist command. Just like in the following example:

C:\> tasklist

System Idle Process 0 Console 0 16 K
System 4 Console 0 96,396 K
smss.exe 764 Console 0 404 K
csrss.exe 836 Console 0 4,032 K
winlogon.exe 860 Console 0 820 K
services.exe 904 Console 0 3,440 K
lsass.exe 916 Console 0 1,504 K
svchost.exe 1092 Console 0 5,152 K
svchost.exe 1156 Console 0 4,312 K
svchost.exe 1300 Console 0 23,108 K
svchost.exe 1372 Console 0 3,476 K
svchost.exe 1572 Console 0 3,884 K
etc.. (in reality, the list is much longer)

6. The "driverquery" command.

Here we can be short. This command will show all installed drivers (name and additional information)
which are on your system. It's available and standard as of XP (although Home editions may lack it).
(Note: "as of XP" ofcourse means that more recent versions like Vista, Windows 7, have it as well.)
driverquery [/s Computer] [/u Domain\User /p Password] [/fo {TABLE|LIST|CSV}] [/nh] [/v] [/si]

So, there are quite some options you can use. In in most basic form, just enter the command driverquery from the commandline, like this:

C:\> driverquery
The output is driver info from your local system...

As you can see from the syntax, you can also query a remote machine, using "/s Computer /u Domain\User /p Password".
Also, the "/v" switch means "verbose", meaning that the list contains more detailed information.

If you would like a graphical output (in a Windows dialog box), you might check out "DriverView",
which can be found at:

7. The "netstat" and "nbtstat" commands.


Netstat is a usefull tool for viewing and checking network connections from the prompt.
netstat [-a] [-b] [-e] [-n] [-o] [-p proto] [-r] [-s] [-v] [interval] [-b]

Depending on the switches that you use, netstat will show you the protocol used in the connections,
the local and remote addresses, the portnumbers, and on modern OS'ses, the "-b" switch will even show
which program on you machine is actually communicating.

Some examples:
C:\> netstat # just shows the active connections
C:\> netstat -a #shows all connections
C:\> netstat -an # shows all connections with addresses and ports in nummerical form (good option!)
C:\> netstat -an | find "4500" # as above, but filters the output on port 4500
C:\> netstat -an 3 # as "netstat -an", but the command is repeated every 3 seconds
C:\> netstat -anb # shows all connections with addresses and ports in nummerical form, and which program is involved
C:\> netstat -r # shows the "routing table" that's in effect on your machine

As a last nice example, try the -e and -s switches. It will you the network statistics of your network interface:

C:\> netstat -e -s

Shows network statistics of your netcard, like bytes send and received, segments send and received etc...


The "nbtstat" utility, is geared towards viewing Netbios "naming" and "registration" information.
Although once a fundamental protocol for IBM and Microsoft, it'still is far from obsolete. Almost all Windows machines still
have a "netbios name", as well as that many services registers, or broadcast, their netbios identifiers
on the network. Services, might register themselves (periodically) through a broadcast, or directed to a WINS Server.
Especially retrieving "naming" information from the local or remote caches, is an important function of the nbtstat utility.
So, for example, using "nbtstat", you can view the netbios naming registrations on your local- or remote machines.
Also, you can see how your machine have resolved "netbios" names into addresses (using -c switch).
So, please do distinguish that we have a "name table" that shows which services have registered, and we have a "naming cache"
which shows how names are resolved into network addresses.

The syntax is the following:
nbtstat [ [-a RemoteName] [-A Remote IP address] [-c] [-n] [-r] [-R] [-RR] [-s] [-S] [interval] ]

Some examples:
C:\> nbtstat -n # Displays the NetBIOS name table of your local machine
C:\> nbtstat -c # Displays the NetBIOS name cache (what is resolved) on your local machine
C:\> nbtstat -a RemoteMachineName # Displays the NetBIOS name table of the RemoteMachineName
C:\> nbtstat -A RemoteIPAdress # Displays the NetBIOS name table of the machine with that Remote IP Adress

So, both "netstat" and "nbtstat" are tools that might help in troubleshooting (or just viewing) network stuff.

By the way, if you want to view the socalled "arp" cache, meaning which IP addresses have been resolved to MAC datalinklayer
addresses on your local machine, use the "arp -a" command, like so:

C:\> arp -a

So you can use the "nbtstat" command to see which names have been resolved to IP Addresses,
and you can use the "arp" command to see which IP Addresses have been resolved to Datalink addresses (card or MAC addresses).

8. Some examples of commands, to invoke a Graphical Utilty.

-- Graphical utilities or mmc snapins:

Many graphical tools, like the 'eventviewer", or "control panel" etc.. means that you must find your
way in the GUI system of Windows. Nothing wrong with that, but sometimes I find it easier to just start a prompt,
and give the appropriate command to launch that GUI component.
Here is a short list of invoking some tools from the prompt. Not all commands work exactly the same
(or are available) on all Windows versions.

But you can just try them out (be a bit carefull with the shutdown commands).

C:\> control # Starts Control Panel
C:\> eventvwr # Starts the eventviewer
C:\> msconfig # Starts the System Configuration utility (startup menu etc..)
C:\> shutdown /l # logoff from Windows
C:\> shutdown /s # Shutdown the local machine
C:\> shutdown /r # Reboot the local machine
C:\> regedit # Starts the Registry Editor
C:\> iexplore # Starts Internet Explorer
C:\> [dsa.msc | admgmt.msc] # Starts Active Directory U+C mmc snapin (goes for other .msc snapins as well)
C:\> sysedit # uniform editor to view/configure wow/console win.ini/system.ini/config.sys
C:\> perfmon # Starts the Performance Monitor
C:\> diskmgmt.msc # Starts the Disk Manager

These are just a few examples. You can easily expand the list yourself, if you would be interrested.
Ofcourse, some commands are (or may be) restricted to be used for Administrative accounts only,
or are disabled by some "policy".
Also, when working from the prompt, the "PATH" settings determine if some executable can be found by the system.
So, if you can start some utility from the GUI, it does not automatically means you can start it from the prompt.

Many of the forementioned "utilities" are, in the more recent Operating Systems, "snapins"in the Microsoft Management Console.
That means that tools like the device manager, performance monitor, and many others,
can be started, like in the following examples:

C:\> %SYSTEMROOT%/system32/devmgmt.msc # Starts the Device Manager tool
C:\> %SYSTEMROOT%/system32/perfmon.msc # Starts the Performance Monitor tool

The environment variable "%SYSTEMROOT%", is a variable that points to the Windows directory, which on most
systems will be "C:\WINDOWS". But if you just use the variable, it does not matter where exactly the Windows directory
is located. Using the variable, will ensure that you refer to the correct location.

-- Control Panel Applets:

Many of the items that you can see, in for example "Control Panel", like the "system applet", are associated
with ".cpl" files (control panel files). That means that you can start such an "applet" right from the prompt,
without going to Control Panel first. Now, it might be a bit different on your particular system, but if I enter
on my system the following commands, you can see what happens in the below examples:

C:\> appwiz.cpl # Starts the "Add and Remove programs" applet
C:\> powercfg.cpl # Starts the "Power management" applet

If the "direct call" to a .cpl file does not work, you might try using "control somecplfile.cpl", like in:
C:\> control powercfg.cpl

9. Some examples of commands that enables you to implement scheduled tasks.

In all Windows versions, it's possible to create a "scheduled task" that will run at dates and times
of your choice. So, for example, you could create a job that runs every Monday at 17:00h.

The interfaces from which you create and maintain jobs, are:

- the prompt, most notably the "at" and "schtasks" commands
- and the Graphical User Interface ofcourse.

If we take a quick look at the GUI first, then there are a few differences in the approach to add a scheduled Task,
if you would compare XP and Win2K3 (Win version 5) on the one side, and Vista and Win2K8 (Win version 6) systems on the other side.
Besides the visual interface on how to "do things", the scheduling "framework" is a bit different as well.

1. Remarks on XP, Win2K3:

In Win2K3, using the GUI, you can go to the Control Panel. There you can find an icon named "Scheduled Tasks".
If you open that, you will encounter several dialog windows which will help you to create the task.

In XP and Win2K3, you can also view, create and modify tasks by using the "schtasks" command.
Let's take a quick look at that:

C:\> schtasks

Shows a listing of scheduled tasks with items like status, next run date etc..

So, just by entering the schtasks command, it will show you all currently existing tasks.

You can add and modify jobs as well. Let's see what the help function of the command will show us:
G:\>schtasks /?

SCHTASKS /parameter [arguments]

Enables an administrator to create, delete, query, change, run and
end scheduled tasks on a local or remote system. Replaces AT.exe.

Parameter List:
/Create # Creates a new scheduled task.
/Delete # Deletes the scheduled task(s).
/Query # Displays all scheduled tasks.
/Change # Changes the properties of scheduled task.
/Run # Runs the scheduled task immediately.
/End # Stops the currently running scheduled task.
/? # Displays this help message.

From each of these parameters, you can have very extended help, using "schtasks /parameter /?
The "schtasks" command, actually should be viewed as a replacement of the former "at" command.
However, the "at" command still works (up to Win2K8), but is not recommended anymore.

The descriptions of the tasks that you created with the GUI or the schtasks command, can also be seen in the "%SYSTEMROOT%\Tasks" directory.
(Note: maybe you are not allowed to "cd" to that directory, but you probably can view the list with "dir c:\windows\tasks".)

2. Remarks on Vista, Win2K8:

In Win2K8, you would go to the Control Panel, and from there choose the "Administrative Tools". There you can find the
option to Add a Scheduled Task. If you start that up, you will see that the GUI and framework indeed have changed somewhat compared
to the Win2K3 world. In fact, it's quite some more elaborate and complex.

Here, also, the "schtasks" command (or the "at" command) works as well, just as in XP/Win2K3.

3. Example of adding a (local) task with the "schtasks" command:

C:\> schtasks /Create /SC weekly /D MON,TUE,WED /TN DailyBackup /ST 22:00:00 /TR c:\scripts\dailybackup.cmd /RU Domain\account /RP password

The following create_options might be used:
/RU username /RP password #run job under this account
/SC schedule [/MO modifier] #When to run, like "weekly"
/D day #day is like MON,TUE,WED,THU,FRI,SAT,SUN
/TN taskname /TR taskrun #Name and pathname for task
ST starttime #HH:MM:SS (24 hour)
/SD startdate /ED enddate] #start and end date, in the form dd/mm/yyyy

Don't forget that the credentials under which the "Schedule service" runs, determines if a job can access which resources on the local machine,
and/or can access network resources as well.

4. Example of adding a (local) task with the "at" command:

Take a look at the following example of adding an "at" task:

C:\> AT 23:30 pm /EVERY:m,t,w,th,f backup.cmd
Added new task with task-ID = 1

A simplified syntax of the at command is:

at [\\remote_machine] time [every:[m],[t],[w],[th],[f],[s],[su]] command_that_must_be_scheduled

Notice that when you scheduke a command using "at", you will get the "task-id" returned in the response.
Note: in some locales, you should use "time" like for example "23:30 pm", and at others, you should not use am or pm at all.

Using the "at" command without parameters, shows you all at scheduled jobs, along with their task-id's.

Status ID Day Time Command
1 Today 23:30 pm /EVERY:m,t,w,th,f backup.cmd

If you know the task-id, you can remove an "at" scheduled job as well. Just like so:

C:\> at 1 /delete

Again, the descriptions of the "at" jobs are localized in %SYSTEMROOT%\tasks. So here you may find files like "at1.job".

10. Some examples of handling txt (or ascii) files.

Often, you need to create, or edit or otherwise manipulate, a simple flat txt file.
In any Windows version, the "notepad" utility is present ofcourse. Or you might have
downloaded a "pumped up" acsii editor, like "TextPad" or "notepad+" or any other similar utility.

But sometimes, you want to save time by not starting such a tool, and you just want to do your work
right from the prompt.

10.1 "copy con" (copy from console) to create a txt file

Suppose you are at the prompt, and you just want to create an ascii file with some text.
You can directly create a txt file, from the prompt, using the "copy con" command.
This command means something like "copy directly from the console (keyboard)".

Suppose we are in the directory C:\TEST

C:\TEST> copy con test.txt # type that command and then press Enter
this is some test text # type some text that you want the file to contain, and when ready, press Ctrl-Z

So, for creating simple files (with little text, or no text at all), use "copy con" and use "Ctrl-Z" to end.

If you really don't care what the file contains, you can use almost any ordinary command in combination with ">",
that is, the redirection symbol (operator).
The ">" means, that you can redirect the standard output (stdout) from a program, to "other output",
like for example a file.

C:\TEST> dir > test.txt # the file will contain the directory listing
C:\TEST> echo > test.txt # the file will contain the line "echo is on or off"
C:\TEST> date > test.txt # the file will contain the current date

10.2 Create a filtered or sorted txt file, from a source txt file

We already have seen the use of ">", which means that you change the standard output of some tool.
Another usefull symbol (operator) is the pipeline "|" symbol, which means that you can "link"
two programs or utilities, in such a way, that the output of the first program,
becomes the input for the second program.

To illustrate such a "pipe" between 2 utilities, let's look at an example.
Suppose you have a large txt file, listing usernames and citynames.
Let's view the content of that file:

C:\TEMP>type tst.txt
Harry London
Albert Amsterdam
Nadia Paris

Note: with the "type" command, you can "type" the contents of an ascii (flat) file to your screen,
so you do not need a program like notepad and the like.

Now suppose, you are only interested in the users with the name "Albert".
Instead of browsing through the file, you can "type" the file, and "feed" that output to
the "find" command, which uses that content as it's input. The find command will then search for
the string that you have put as a parameter, which in this case is "Albert".

C:\TEMP>type tst.txt | find "Albert"
Albert Amsterdam

Indeed, the output get's "filtered" by that particular username.

Ofcourse, now you can even redirect, the output of the "find" command, to a new file.

C:\TEMP>type tst.txt | find "Albert" > filtered.txt

C:\TEMP>type filtered.txt
Albert Amsterdam

As another example, suppose that the tst.txt file needs to be sorted alphabetically.
For that, you can use the "sort" command, in a similar way as you used the "find" command.
Only this time, "sort" will not search for a string, but it will sort it's input:

C:\TEMP>type tst.txt
Harry London
Albert Amsterdam
Nadia Paris

C:\TEMP>type tst.txt | sort > sorted.txt

C:\TEMP>type sorted.txt
Albert Amsterdam
Harry London
Nadia Paris

Note: for more of those "dos like" tips, you might view the file "cmdshell.txt", which is available
on this site as well.

11. The WMIC command.

As of XP (Professional), you can use the "wmic" (Windows Management Instrumentation Command) tool.
This allows you to retrieve a large amount of low-level system information from the command line.

For example, in unix/linux, it's very easy to get a list of the processes on your system. Multiple options exists,
but even a relatively simple command as ps -ef, will show you all processes and their attributes, on Unix.

In Windows, you can ofcourse use the graphical "Task Manager" that will also show the processes, but how
to retrieve a list right from the prompt? This question has often puzzled many Windows users.
Ofcourse, in section 5 we have already seen the "tasklist" command which produces such a list.
But the "wmic" command can do similar, and even much more!
That's why we will spend this section on "wmic".

11.1 What is WMI?

In short: WMI is the Microsoft implementation of WEBM and CIM, meaning that an API is deployed, using various
providers, which allows for viewing (and sometimes altering) properties of many low-level system services.
Most WMI enabled (graphical) utilities in Windows, shows you a hierarchical object model.
That's why, in the Windows OS, there are many tools that shows you objects (like devices) in a "tree-like" structure.

WMIC, is the commandline interface on WMI.

Let's take a look at a few commands, that will demonstrate the power of "wmic".

11.2 Retrieving a list of processes and their properties.

Using WMIC, it is possible to list out all the running processes and their parameters.

Get a list of processes on your local machine, with KernelModeTime and UserModeTime statistics:
C:\> wmic PROCESS get Caption,Kernelmodetime,Usermodetime

Get a list of processes, on your local machine, with KernelModeTime,UserModeTime, VirtualMemory statistics:
C:\> wmic PROCESS get Caption,Kernelmodetime,Usermodetime,WorkingSetSize

Or just get a list with all statistics:
C:\> wmic PROCESS get

Get a list of processes on your local machine, in the file "c:\temp\processlist.txt" with some statistics:
C:\> wmic /OUTPUT:C:\TEMP\ProcessList.txt PROCESS get Caption,Commandline,Processid

Now, try the following commands to get various other listings on process statistics:

C:\> wmic process list Statistics
C:\> wmic process list brief
C:\> wmic process list full

You can also "filter" on a particular process image, like:

C:\>wmic process where name=”cmd.exe” get processid, name, executablepath

C:\> wmic process where (name=”cmd.exe” or name=”calc.exe”) list brief

Note the usage of the "where" clause in the above two commands.

You can let "wmic" operate on a remote machine, by using the parameters:
/user:[admin_user] /password:[password] /node:[machine_name]

11.3 Stopping, starting, and influencing a process.

Instead of just retrieving lists, it's also possible to infuence a process.
Although I have seen some differences among the different Windows versions, you might try
the following examples on your Windows test machine.

--> terminating an application:

C:\> wmic PROCESS WHERE Name="calc.exe" CALL Terminate

For example, all instances of notepad can be terminated by using:

C:\> wmic PROCESS where (caption=”notepad.exe”) call terminate

--> starting an application (using the "create" method):

C:\> wmic PROCESS call create calc.exe

--> altering the priority of an application:

C:\> wmic PROCESS where name="myprg.exe" call setpriority 16384

In this section, ofcourse, I have only "scratched the surface" on this topic.
Indeed, the "wmic" command is very powerfull, and it surely takes some time to master it.
If this was your first encounter with wmic, I think you agree to invest some more time.

12. The "typeperf" command.

In this section you will find (just) a few remarks on the "typeperf" command.
You can use the graphical utility "Performance Monitor" (perfmon.exe) to create performance charts
of, for example, cpu utilization, memory usage, disk usage, network statistics, and much more.

Ofcourse, it's probably best to work with Performance Monitor (recently renamed to "System Monitor"), using
the graphical interface.
But who knows: maybe you like to create measurements right from the prompt. If that's so, you might like the "typeperf" command.
And, since typeperf is used from the prompt, you can use it in scripts as well.

With NT system monitoring tools, you will encounter the following naming structure;
- "objects" are representations of (real) components like processor, physicalDisk etc..
- a "counter" (of an object) is a measurable metric that is exposed by that object. An object usually has many counters.
- "instance", for example, you might have an object like a "PhysicalDisk", but.. you might have multiple disks on your system!
So, in this example, you might pick a particular disk (like E:), or choose all of them (mostly designated by "_Total")

So you might have as an object, a "processor", which exposes several counters like "%User Time", "%Priviledge Time", or
"%Processor Time" (which is User + Priviledge).

Using the graphical tool (performance monitor/system monitor), it's quite easy to select multiple objects, and per object,
select the counters that you are interrested in.
Using the command prompt, you are a little bit limited in the amount of counters. This is because you might use
the typeperf command like:

typeperf "Object(Instance)\Counter" ["Object(Instance)\Counter" etc..] [other options]

Again, the full syntax is somewhat more elaborate than what's shown above. (yes, this is only a simple introduction)

Here are a few examples:

C:\> typeperf "\Processor(_Total)\% Processor Time"
Shows a record per second (is default) of the %Processor Time spend, by all cpu instances.

C:\> typeperf "\PhysicalDisk(_Total)\Avg. Disk queue length" -o diskqueue.txt
Shows a record per second (is default) of the Average disk queue lengths, by all (disk) instances.

So, with the -o option, you can specify a file where you can send the output to. You can ofcourse also use ">", to redirect
the output to a file.

13. The "cacls" command, and similar commands.


Sometimes you need to change the NTFS filesystem permissions, possibly for large number of directories, or for
a large number of users or groups.
Anyway, it can be usefull to know how to do that from the commandline.

CACLS is a Windows command-line utility that is used to display or modify file or directory access control lists (ACLs).
NTFS objects, that is files and directories, "contain" an Access Control List", that specifies which users and groups
can access that object, and with what sort of permissions.

Usually, a new object (file or directory) inherits the ACL's from the folder in which it was created.

CACLS is not difficult to use. The syntax is:

cacls FileName [/t] [/e] [/g User:permission] [/r User [...]] [/p User:permission [...]] [/d User [...]]

/t = Changes DACLs of specified files in the current directory and all subdirectories.
/e = Edits a DACL instead of replacing it. For example, add a permission.
/r User = Revokes permissions for the specified user or group (when spaces in the groupname, enclose the name with "")
/p User:permissionlist = Replaces (instead of edit) access rights for the specified user or group.
/d User = Denies access for the specified user.
/g User:permission = Grants access rights to the specified user or group.

When you use cacls to just view, or edit the permissions, you will see some output that might strike you as strange,
like "OI", "CI" etc..
It's not so weird really. Here is what those terms means:

OI - Object inherit
CI - Container inherit
IO - Inherit only
No such output: This folder only.

In practice, you will see mostly "combinations", and they have meanings like:

(OI)(CI) = This folder, subfolders, and files.
(OI)(CI)(IO) = Subfolders and files only.
(CI)(IO) = Subfolders only.
(OI)(IO) = Files only.

So, when you view the acl's on some directory or file you see user and groupnames, along with the terms from above list,
and the permissions. So, you might see stuff like:

C:\> cacls c:\temp

Buildin\Users: (OI)(CI)R # Read for for this folder, subfolders and files for the group "Users"
Buildin\Administrators:(IO)(CI)F # Full Control for this folder, subfolders and files for the group "Administrators"

The permissions you can edit or replace are:

n: None
r: Read
w: Write
c: Change
f: Full Control

Some examples of editing ACL's:
C:\> cacls c:\ /t /e /g Administrators:f
C:\> cacls c:\temp\*.* /e /g "Domain Users":r Users:r /r Everyone
C:\> cacls e:\data\finance /e /t /g "FinanceUsers":f

The utility will ask you "ARE YOU SURE? Y/N" if you use it to edit or replace permissions. In batchfiles, that's not nice.
You can use the command "echo Y |" in front of the cacls the command, like in:

C:\> echo y| cacls [rest of the command..]

Saving acl's into a file using icacls:

Suppose you want to store all ACL's of files and subdirectories into a file, you might like
the "icacls" command. Although this command has many more options than what you will see here,
I just want to focus on saving in, and restoring ACL's from, a file.
Ofcourse you won't save the "datapart" of files. It's only the "acl" related metadata what get's stored in the file.


C:\> icacls d:\data\finance\* /save finacl.txt /t # "/t" means: subdirectories also

As said before, "icacls" is much more powerfull than this example.
If you need to restore the ACL's:

C:\> icacls d:\data\finance\ /restore finacl.txt

With a restore, you need to be a bit carefull. First exercise your commands on a test system, before you use it "for real".


A very good utility is "SetACL".

You can find all information here.

14. Free (gnu) shells or tools for Windows.

Do You like the unix shell utils like awk, sed, dd, od and all those other great tools?
There are some nice "shell environments" you can install in Windows, without that you must install a full Linux partition,
or a Linux Virtual Machine.
If you install such an environment, then next to your cmd, or Powershell (or other Windows tools), you can also run some
nice sh (or ksh etc..) tools as well.
Only a few dll's are installed, in order to create a Linux API emulation layer, providing an environment for the commands.
Ofcourse, it's only a limited commandset, but it's quite nice, and I can really recommend to install one of them.
For example:

The GNU CoreUtils for Windows (small package; choose the "setup")
The Cygwin environment for Windows (larger package; many modules to choose from)

If you are not so familiar with the tools, there are many easy to find docs on the net.

For example, if you want to perform hex dumps of a file, you can use the "od" command. Here is an example:
You will certainly have some ascii file somewhere, and some binary file somewhere too.

Now try this on those files:

od -x -N 64 yourfile +0x1000
od -a -N 64 yourfile +0x1000

Where the -x flag displays output in hexadecimal format (-a in ascii), and the -N flag instructs the system to format
no more than 64 input bytes from the offset parameter (+), which specifies the point in the file where
the file output begins.

15. How to determine your .NET (dot net) version, and your Windows Installer version.

15.1 Determining the .NET version:

Most modern Windows versions will have the .NET (dot net) framework on board. Said very crudely:
It's a sort of runtime environment for .NET applications.
At the time of writing, dot net version 3.5 is quite current.

Some applications require some version of .NET to be installed on your computer.

But how do we determine the current version anyway?

There are lots of ways to find out. You can start up control panel, go to software etc..
Or you can check the Registry.
Here are a few other ways using the prompt:

.NET is largely installed in your Windows directory.
If I start a prompt, and browse around for .NET "looking" directories, I might find a lot of
subdirs in "C:\Windows\Microsoft.NET\".
Next, I just try to find the highest version number under the "Framework" directory, like for example "v3.5".
Then we try to locate a C# compiler like "csc.exe", and let's run it.

C:\Windows\Microsoft.NET\Framework\v3.5> csc

Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.4926
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.

fatal error CS2008: No inputs specified

Ofcourse, an error is returned because I did not specified any inputfile.
But, did you noticed that in the banner, the .NET framework version was shown?

In a former section, we already have seen the "WMIC" command.
This is such a versatile command, and by using it with specific parameters, you can find the .NET version too.
Try this:

C:\> wmic /namespace:\\root\cimv2 path win32_product where "name like '%%.NET%%'" get version

15.2 Determining the Windows Installer version:

This one is quite easy. Just run "msiexec" from the prompt. A help dialogbox will popup,
which also shows the installer version.

C:\> msiexec

16. How to start an application with different priority, from the prompt.

WARNING: it's not always advisable to change the way an application should start, like for example
changing it's "priority".
It could, in some cases, even affect the stability of your system.

There are a limited number of methods to start an application (like an application, or command, or batch script) with
another priority than the "default", or with other properties (like the working directory e.g., for saving files).

From the prompt, you can use the "start" or "wmic" command.

16.1 The "start" command:

If you open a cmd window, and enter "start /?", you can see what your options are when using the start command.
A clipped (limited) output is shown below:

C:\> start /?

Starts a separate window to run a specified program or command.

START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
[/AFFINITY ] [/WAIT] [/B] [command/program]

"title"  Title to display in window title bar.
path  Starting directory
B  Start application without creating a new window. The
  application has ^C handling ignored. Unless the application
  enables ^C processing, ^Break is the only way to interrupt
  the application
I  The new environment will be the original environment passed
  to the cmd.exe and not the current environment.
MIN  Start window minimized
MAX  Start window maximized
SEPARATE  Start 16-bit Windows program in separate memory space
SHARED  Start 16-bit Windows program in shared memory space
LOW  Start application in the IDLE priority class
NORMAL  Start application in the NORMAL priority class
HIGH  Start application in the HIGH priority class
REALTIME  Start application in the REALTIME priority class
ABOVENORMAL  Start application in the ABOVENORMAL priority class
BELOWNORMAL  Start application in the BELOWNORMAL priority class
AFFINITY  The new application will have the specified processor
  affinity mask, expressed as a hexadecimal number.
WAIT  Start application and wait for it to terminate

As you can see, the priority "classes" are (in NT like systems like all modern Windows versions are):
Per default, a process is scheduled in the "NORMAL_PRIORITY_CLASS".
Actually, the priority levels range from zero (lowest priority) to 31 (highest priority)
Within every priority class, there are sublevels defined, which then "explains" those 0 - 31 levels.
However, for regular applications, there is no good reason to use the REALTIME_PRIORITY_CLASS,
since this will compete with basic IO of your system (and disk syncs as well).

Note: depending on the process and your administrative rights to your machine,
you may not be able to change a particular process's priority.
Also, it's not always a good idea to make a change in priority in the first place.

- With the "start" command, you will just use the identifiers HIGH, LOW etc..
- With the "wmic" command, you should use the "ClassValue" numbers. Here, you can use this table:

Priority ClassValue
Normal= 32
Low= 64
Real-time= 128
High= 256
Below Normal= 16384
Above Normal= 32768

Some examples using the start command:

C:\> start /HIGH notepad.exe

C:\> start /min notepad c:\data\mytext.txt

16.2 The "wmic" command:

In section 11, we touched on the "wmic" command.
You can also use that command to change the priority of a process.

Example: put explorer.exe on "LOW"

C:\> wmic process where name="explorer.exe" call setpriority 64

16.3 Other utilities:

- Using the "Task manager", and switching to the process tab, then if you rightclick a process in the list,
you are able to change the priority class of an application.
- For IRQ's, which relate to devices, in some cases, you could (in principle) also modify the registry,
but that's certainly not always recommended.
- For some "regular" applications, it's feasible to modify the Registry and edit the "ImagePath" registry key,
replacing it with the appropriate "start" record.
- No doubt that if you "google", you will find quite a few free utilities that enables you to change the priority.
Needless to say that you should test them first. Never to be used for production systems.

17. A few usefull file manipulation commands.

17.1 To delete all files (not directories) from a directory and all subdirectories:

Delete of files, silently, in all subdirs, also readonly ones.


C:\> cd test
C:\TEST>del /F /Q /S *.*

All files in all subfolders should be erased now, unless you do not have NTFS permissions.
Obviously, you better be very aware on your "location" in the filesystem.

F: even readonly files should be deleted.
Q: Quiet, no confirmation asked.
S: Files in Subdirectories also.

Ofcourse, you do not neccessarily need to use "*.*". If you like to clean out (for example) only all "*.bak" files, use this:

C:\> cd test
C:\TEST>del /F /Q /S *.bak

17.2 To delete all files and all subdirectories from a directory:

Most often, this is what you want instead of what was shown in 17.1.
Just use the "rd" command with the "/S" (and optionally "/Q" for quiet, or no confirmation).
Obviously, you better be very aware on your "location" in the filesystem.


C:\> cd test
C:\TEST>rd tst /S /Q

This will delete all subdirectories and files in "C:\TEST\tst", including the "tst" directory.
So, for example, if you would have the directories "C:\TEST\tst\a" and "C:\TEST\tst\b", each with
a lot of subdirs and files, then it would all be gone.

17.3 The "attrib" command to see and change "attributes":

You know that a file will have certain properties, like filesize, owner, NTFS permissions etc..
In addition (on all usual Windows filesystems, like FAT, NTFS), 4 specific "attributes" may be set.
these are: A (archive needed), H (file is hidden), S (file is a systemfile) and R (file is read-only).
You could have a cmd window open, and you are in some folder. If you then issue the usual "dir" command
to get a list of files and subdirs, you might not "see" everything.
As an example of this, open a cmd window, and go to the systemdisk (usually C:). Then goto to the root of C:,
using "cd \". After that, just enter the "attrib" command.

C:\users\albert> cd \

C:\> attrib

H   C:\Boot.BAK
SHR   C:\boot.ini
ASHR   C:\bootmgr
ASHR   C:\ntldr
ASH   C:\pagefile.sys

So, in this example, the file "ntldr" has all 4 attributes ASHR "set", meaning that they are "+" (or "in place").
So, to mark or unmark a file as "read-only" or "system" or "hidden", use the attrib command like in the following examples:

- To unset (or tear down) the +r, +s, +h attributes on "mytestfile", in order to make it "not a systemfile",
and "not read only" and "not hidden", use:

C:\TEST> attrib -r -h -s mytestfile

- To unset (or tear down) only the +r attribute on "mytestfile", in order to make it read/write, use:

C:\TEST> attrib -r mytestfile

- To make a file Hidden and read-only, use:

C:\TEST> attrib +r +h mytestfile

Sometimes, if you have copied a CD or DVD to your harddisk, those files might be marked as "read-only".
Fortunately, you can use wildcards (*, or *.*) with the attrib command,
and the switch "/s" makes sure that all subdirs are parsed as well. For example:

C:\COPIED_FROM_CD> attrib -r *.* /s

17.4 The "xcopy" command to create backups (or copies of files and trees of directories):

If you need to create a copy of files and subdirectories on the same disk, or to another disk, or to a share,
or to a mountpoint etc.., you can use the "xcopy" command.

One advantage of the regular xcopy command is, thats its available on all Windows versions.
Actually, its a very powerful command, and you can use many switches in order to create good user data backups.

- How to copy a tree of all subdirectories and files:


Suppose on a Win2Kx Server, you have a directory "C:\data" which has under it a big tree of subdirectories
with other data directories (like c:\data\user1, c:\data\user2 etc..).

Now you want to copy this complete tree to another drive, say drive M:, included with all subdirectories, all files,
and information of the Owner and ACL´s.

The following example shows how you might do this:

C:\data> xcopy *.* m:\data /S /C /O /H /Y

Where the switches mean:

/S: copies subdirectories also
/C: copy the files even if an error shows up (like the file is in use)
/O: includes also ownership and Access Control Lists information.
/H: includes also all hidden and system files
/Y: suppresses the confirmation if you are about to overwrite files

Ofcourse, the command xcopy /? will show you all switches.

- How to copy files created or modified after a certain date:

In this case, use the "/D" switch.


C:\data\excel> xcopy *.* /D:01-13-2009 f:\backup

Ofcourse, here you can use the other switches too.

18. The "forfiles" command.

Often, especially on Server systems, all kinds of log files are created.
Also, quite often, those files just piles up, and as a conseqence, your disk(s) might run out of space.

Typically, you only want the last couple of days, or weeks, of those logs kept online on the disk.
The older files then, can be deleted.

It's quite easy to create a scheduled batch script, that will do this, using traditional dos commands.

However, the "forfiles" command is very suited to for this kind of actions.
It should be available (as a standard command) on the latest Windows versions like Vista, win7, Win2K3, Win2K8.
But it's around for quite some time, like for example as a Resource kit tool for Win2000.


forfiles [-p ] [-m SearchMask] [-s] [-c "command"] [-d [{+|-}][{Date|Days}]]


Path: is just the directory where the forfiles command must perform it's work.
Searchmask: a "mask" that specifies the criteria to select files, like *.log, or *.trc etc..
/s: if this parameter is used, subdirectories (with respect to "path") will be processed also.
/d: use it like for example -5, meaning a criteria "older than 5 days".

Note: if you have difficulties to let the command work, take a look at this:
- The older versions want you to use a syntax like "-pE:\logs", while newer versions like "-p E:\logs"
- Sometimes the "-" parameter mark does not seem to work, while the "/" does.

So, it's likely that you need to do a few "experiments" with this command syntax.

How it works:
The forfiles command searches the directory (optionally subdirs too) for files which conform to the
"searchmask" (like *.log), and which conform to the date citeria (like older than 7 days).
Then a list will be created. Then the "command" (like "del") will operate on the list. In such a case,
a variable will be used (per default it is @FILE) which takes on the values of the list, one after the other.
The result command is then "del @FILE", where @FILE will be the filenames from of the list, from start to finish.
Thats why we often will see a @FILE variable in the commandline.

Here are a few examples:

C:\> forfiles -pc:\temp -m*.* -s -d-040211 -c"CMD /C Echo @FILE is quite old!"

C:\> forfiles /P C:\webserver\logs /S /M *.log /D -30 /C "cmd /c del @FILE"

The first example will echo "filename is quite old" for all files in c:\temp, which are older than 04/02/11.
The second example will delete all *.log files in the c:\webserver\logs directory, which are older than 30 days.

19. The "net" command.

In section 1, we talked about the "sc" command, which allows you to control services.
Also, you can also easily just view all services with "sc" command from the prompt.

As an alternative, in the same section, we said that the "net" command could also be used to view running services,
and you have some degree of control as well, because the net command allows you to stop and start a service.


Viewing services:

-- To obtain a list of running services on your screen:

C:\> net start

-- To obtain a list of running services and pausing the output to screen (pressing a key to continue):

C:\> net start | more

-- To put a list of running services into the textfile "c:\temp\services.txt":

C:\> net start > c:\temp\services.txt

-- To filter the list of services (to your screen) which have the string "SQL" in their service name:

C:\> net start | find "SQL"

Starting and stopping services:

-- To stop (for example) the "MSSQLSERVER" service:

C:\> net stop "MSSQLSERVER"

-- To start (for example) the "MSSQLSERVER" service:

C:\> net start "MSSQLSERVER"

But the "net" command has much more to offer! Actually, it (once) was the Windows command to control
network functionality, and even control user account information for the local machine's SAM database.
With regards to account information, on modern Domain Controllers, a number of other
user account and network services commands are availble.

Task: If you like to know what you still can do with user accounts, using the net command,
google on "net accounts" and "net user"

Some Other great functionality of the "net" command:

-- Obtaining some stats of your (SMB) "Server" and "Workstation" (redirector) services:

C:\> net statistics server

C:\> net statistics workstation

-- Obtaining a listing of shares on your Server:

C:\> net share

-- Obtaining a list of open shared files on your Server:

C:\> net file

-- To close a certain open file (with an ID found with the above command):

C:\> net file ID /close

-- To view a list of Servers on your subnet (advertising SMB server service):

C:\> net view

-- To "mount" a (local) Driveletter (like F:) to some remote networkshare:

C:\> net use F: \\servername\sharename

-- To "mount" the next available (local) Driveletter to some remote networkshare:

C:\> net use * \\servername\sharename

-- To "mount" the a (local) Driveletter (like F:) to some remote networkshare, and passing credentials along:

C:\> net use F: \\servername\sharename /user:Domain_name\user_name

Although it seems great to map a driveletter this way, it's not always the best solution for scripts:
Maybe not on all machines, at all times, the same letter is available.
So, you might just use the "url" or "unc" directly in scripts, as in for example
"copy myfile.txt \\servername\sharename" (ofcourse you need permissions on that share)

20. Determining "svchost" sessions.

In the Windows tasklist, you might see one or more "svchost" processes. Typically, you will see multiple processes.
Svchost is used to run services which are coded in (for example) .dll libraries.

It's not very likely that you will run (or need to run) the command yourself, in some customized way.

It's even possible, that a certain svchost process, supports (runs) more than one service.

If you are interested, you might take a look at the Registry key


where each value represents a "svc group", containing one or more services.

If you want a simple list of svchost processes, and what exactly they are running, then use the following command:

C:\> tasklist /svc | find "svchost"

21. The "rundll32" command.

Many code is implemented in .dll files, and you cannot run that "directly" from the command prompt.
However, the "rundll32" commandline utility, allows you to access that code.

The syntax is:

C:\> rundll32 dllname,entrypoint [optional arguments]

Although rundll32 is actually not directly meant for common user access, it provides you
with endless possibilities with working on the commandline, or from scripts.
One famous example is the following command, which illustrates the power of rundll32:

C:\> rundll32 PRINTUI.DLL,PrintUIEntry /?

This will only show you the options which are possible on printer management. So, you can imaging
that there is a lot more to this utility.

22. How to determine you are running in a VM or physical machine.

Suppose you start a rdp session (mstsc, a Windows terminal) to some Windows machine (like a Win2K3 Server).
How would you know that this a machine is a bare metal machine (physical machine), or a Virtual Machine,
like a "VMWare" virtual machine, using only prompt commands?
It's true: it's almost indistinguishable. Both architecture are almost indentical, if you are working
from a Windows console.

Still, there are a few simple tricks, only using prompt commands.

Method 1:

Using the "systeminfo" command from the prompt, you will get a lot of information from your OS and machine.
I like it best to redirect the output to a textfile, so that I can study the information from notepad or so.

C:\TEMP> systeminfo > info.txt

Somewhere in the output, you will see the Manufacturer and model of the system.
IF you see, for example:

System Manufacturer: FUJITSU SIEMENS
System Model: AMILO Pro V2060

Then it's quite likely that you work from a physical machine.

Contrary, if you would find for example:

System Manufacturer: VMware, Inc.
System Model: VMware Virtual Platform

Then you a working from a VMWare Virtual Machine.

Method 2:

Many WMIC commands will reveal that you are actually working on a Windows Virtual Machine, or physical machine.
For example:

C:\TEMP> wmic computersystem > info.txt

In the resultfile, If you are working from a Virtual Machine, like VMWare, you would see that name
in quite a few places. If it's a physical machine, like a Dell or so, you would see that name instead.

Note: you can use many other wmic parameters as well. Just try "wmic /?" and experiment a bit.

Method 3: some other clues

-The following is not garanteed to work, but with some Virtualization manufacturers, you might
have a registry key, which reveals the physical host that supports the VM's.
You might try to take a look at:

HKEY_LOCAL_MACHINE\Software\Microsoft\Virtual Machine (if present)

By the way, if it is indeed a VM, like a VMWare VM, in the Registry, you would find that name all over the place.

-The following is not garanteed to work, but with some Virtualization manufacturers, you might
find a directory, carrying the Manufacturer's name, in %SYSTEMROOT%, or %SYSTEMROOT%\system32.

-The following is certainly not garanteed to work, but with some Virtualization manufacturers, the MAC address
of the virtual adapter starts with "00", like in for example "00:05:69:0e:51:95"
This could be so because they use an algolrithm using the IP address and some hashing, that often returns "00:etc.."
But keep in mind that this method is very weak because also true physical adapters could use a MAC starting with "00"

23. Some "traditional" batch stuff.

If you like old dos style batch scripting, maybe you like the following .txt document(s):

Some "traditional" batch stuff (1) (cmdshell.txt)