This page is a freshly started work in progress.
On this page I'll collect (links to) sample scripts and commands
for unattended and silent software installations.
My definition of an unattended installation is any installation
that does not require user input but may display dialogs
or progress bars etc.
Silent installations are installations without any
visible interface elements.
The main focus will on installing software, drivers, etcetera in Windows (NT 4 and later, not 9*/ME), not on installing Windows itself, though some links will be provided.
I won't restrict myself to a single script language, the goal is getting the job done.
The installation commands or scripts are roughly categorized:
• A must-read if you are going to prepare unattended installations: Unattended/silent installation switches for Windows apps at sourceforge.net
• When you write scripts for unattended installations, try to assume as little as possible:
Sendkeys( ),Sendkeys( ) to enter passwords,DIR won't display hidden files,Well, you get the idea.
Just use common sense.
Verify your assumptions, or make them true.
PUSHD "%~dp0"
(don't forget the POPD command at the end of
the batch file).
This is explained on my
Clever Tricks page."%~dp0command_name.exe" if an
executable is located in a batch file's own startup directory.CSCRIPT
command, or use my
VBSAssoc.bat to
temporarily change the .VBS file type association
(don't forget to call restore_vbs_assoc.bat
at the end of the installation to restore the original
file type association).And last but not least, log the results of each action of your install scripts.
• One of my installation batch files once returned an errorlevel that seemed to be random at first.
After several days I found out that emptying an already empty environment variable (SET varname=) will result in an errorlevel 1, whereas the errorlevel will be 0 if the variable did have a value before emptying it.
If you intend to use an installation batch file in a package (Wise, SMS, MSI, ...) you may want to perform the error handling yourself, and end the batch file with the command EXIT 0 to make sure the package won't be uninstalled because of an unexpected errorlevel.
And check intermediate errorlevels using lines like this following each relevant command line:
IF NOT "%Debug%"=="" ECHO Return code: %ErrorLevel%
Now all you need to do to test the intermediate errorlevels is set environment variable %DEBUG% to any value and rerun the batch file.
• Use my GetUnins.vbs script to find uninstall commands:
CSCRIPT //NoLogo drive:\path\GetUnins.vbs /F:"filter_string"
/F:"filter_string"
restricts the returned list to software that has a description
which includes filter_string.
With the optional /R switch the filter is
interpreted as a regular expression.
Find the uninstall string for the software you want to uninstall.
In case the software was installed from an .MSI file, the uninstall
command will probably look like this
(unique_identifier
is a string that, as the name suggests, uniquely identifies
specific software):
MsiExec.exe /I{unique_identifier}
This is the command for an interactive uninstall
or repair!
Change it to an uninstall command by replacing
MSIEXEC.EXE's /I
switch by /X and append the
/qn /norestart REBOOT=ReallySuppress
switches to make it a silent uninstall without reboot:
MSIEXEC.EXE /X{unique_identifier} /qn /norestart REBOOT=ReallySuppress
• If you're lucky, you'll find the command line
switch(es) for unattended (un)installs in the documentation
or by using the /? or -? switch.
If not, you can sometimes find undocumented command line
switches using
STRINGS.
But sometimes you may just need to guess what
command line arguments will make an (un)install silent.
If all else fails, experiment with the following switches:
Try dashes instead of forward slashes too (-S instead of /S), and check both upper case and lower case.
Preparing harddisks for a new operating system is tricky, because it can be done only when you boot from another medium like a floppy disk, CD-ROM or bootable USB stick -- or another harddisk.
• Probably the most well-known tool to (re)partition
harddisks is FDISK.
FDISK is a native DOS command, so if you created a bootable DOS
diskette you probably have a copy of FDISK.EXE or FDISK.COM
available.
From my own experience, however, I would advise against using
FDISK on modern computers.
FDISK has been known to miscalculate partition sizes and create
overlapping partitions.
In most cases you wouldn't notice this until a partition is almost
completely filled with data, which will then be lost.
• If you still own a copy of an old Norton/Symantec Ghost
version, you can use GDISK to (re)partion harddisks.
Copy GDISK.EXE to your bootable medium (floppy disk, CD-ROM, USB
stick).
GDISK.EXE is for 16-bits DOS; if you boot with a 32-bits OS, like
BartPE,
use GDISK32.EXE instead.
Boot from that medium and issue the command GDISK
without any command line arguments to list all harrdisks with
their numbers.
This is especially important if you boot from a USB medium, as
this may often be recognized as harddisk 1, and the internal
harddisk as harddisk 2 (depending on the computer's BIOS and the
type of USB medium).
And we wouldn't want to accidentally repartition our bootable USB
stick or external harddisk, now would we?
Let's suppose our USB stick is listed as harddisk 1, then we can repartition the "real" harddisk (2) with the following commands:
GDISK 2 /DEL /ALL
GDISK 2 /MBR
GDISK 2 /CRE /PRI /SZ:4096 /FOR /Q /V:SYSTEM
GDISK 2 /CRE /EXT
GDISK 2 /CRE /LOG /FOR /Q /V:DATA
GDISK 2 /DEL /ALL will erase all existing partitions
on harddisk 2.
GDISK 2 /MBR will recreate a standard
MBR on harddisk
2, important if the harddisk was somehow encrypted, like (IBM)
laptops with their BIOS password set.
GDISK 2 /CRE /PRI /SZ:4096 /FOR /Q /V:SYSTEM will
create a new 4GB primary partition labeled "SYSTEM" and quick-format
it.
GDISK 2 /CRE /EXT will create an extended partion on the
rest of the disk.
GDISK 2 /CRE /LOG /FOR /Q /V:DATA will create a logical
drive using the entire extended partition, label it "DATA" and
quick-format it.
Read Symantec's detailed explanation of all GDISK command line switches.
| Caution: | As always, test these commands thorougly on
the type of computer you intend to use them for. Kids, don't try this at home! |
By default, Windows is installed with DHCP enabled for all network adapters.
However, you probably want to use static IP addresses on servers.
This is where NETSH is put to good use.
NETSH is available on Windows XP and later versions.
I won't describe all NETSH's command line parameters, as there are enough to write a book on it.
Start by typing NETSH /? on a command prompt and explore from there, if you have some time to spare.
What I will describe is how to create your own NETSH scripts.
As an example we'll use NETSH to set a static IP address for a network adapter, instead of DHCP.
First check the current settings using the command:
IPCONFIG /ALL
For a single network adapter you'll probably see something like this:
Windows IP Configuration
Host Name . . . . . . . . . . . . : mypc
Primary Dns Suffix . . . . . . . :
Node Type . . . . . . . . . . . . : Unknown
IP Routing Enabled. . . . . . . . : No
WINS Proxy Enabled. . . . . . . . : No
DNS Suffix Search List. . . . . . : lan
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . : lan
Description . . . . . . . . . . . : Realtek RTL8139/810x Family Fast Ethernet NIC
Physical Address. . . . . . . . . : 00-11-22-33-AA-BB
Dhcp Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : No
IP Address. . . . . . . . . . . . : 10.0.0.65
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 10.0.0.1
DHCP Server . . . . . . . . . . . : 10.0.0.1
DNS Servers . . . . . . . . . . . : 10.0.0.1
Lease Obtained. . . . . . . . . . : Saturday, March 13, 2010 22:00:39
Lease Expires . . . . . . . . . . : Sunday, March 14, 2010 22:00:39
| Note: | On the computer used in this example, Autoconfiguration (or APIPA) has been disabled. This is not the default setting, by default it will be enabled. My APIPA.bat and/or APIPA.vbs scripts can help you change or restore APIPA settings. |
Before we change any network setting, we'll first save the current settings to a file:
NETSH interface dump ip > netsh.dhcp.script
If we ever want to restore the current DHCP setting, all we need to do is issue the following command:
NETSH -f netsh.dhcp.script
Now we'll change the network adapter's IP settings manually.
Open the Network Connections properties, next open the network adapter's properties, and than the TCP/IP properties.
Click "Use the following IP address" and fill in all required IP addresses.
When finished, click "OK" and close the dialogs.
Type IPCONFIG /ALL again to check the new settings:
Windows IP Configuration
Host Name . . . . . . . . . . . . : mypc
Primary Dns Suffix . . . . . . . :
Node Type . . . . . . . . . . . . : Unknown
IP Routing Enabled. . . . . . . . : No
WINS Proxy Enabled. . . . . . . . : No
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Realtek RTL8139/810x Family Fast Ethernet NIC
Physical Address. . . . . . . . . : 00-11-22-33-AA-BB
Dhcp Enabled. . . . . . . . . . . : No
IP Address. . . . . . . . . . . . : 10.0.0.135
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 10.0.0.1
DNS Servers . . . . . . . . . . . : 10.0.0.1
If the settings are OK we'll save these new settings to another file:
NETSH interface dump ip > netsh.staticip.template
Open this file netsh.staticip.template in any text editor and look for the following lines:
set address name="Local Area Connection" source=static addr=10.0.0.135 mask=255.255.255.0 set address name="Local Area Connection" gateway=10.0.0.1 gwmetric=0 set dns name="Local Area Connection" source=static addr=10.0.0.1 register=PRIMARY set wins name="Local Area Connection" source=static addr=none popd # End of interface IP configuration
We could copy the template to a separate script for each server, and adapt the addresses manually.
Or we can remove these last lines shown above from the template and create a batch file that will add them on the fly:
@ECHO OFF :: This batch files requires 1 parameter: the last octet for the new static IP address IF "%~1"=="" EXIT 1 :: Check if the parameter is a number between 0 and 255 SET /A 1 * %1 2>NUL | FIND "%~1" >NUL || EXIT 1 IF %1 LSS 0 EXIT 1 IF %1 GTR 255 EXIT 1 :: Copy the template to the script for the new static IP address COPY /Y netsh.staticip.template netsh.staticip%1.script :: Append the missing lines, filling in the last octet >> netsh.staticip%1.script ECHO set address name="Local Area Connection" source=static addr=10.0.0.%1 mask=255.255.255.0 >> netsh.staticip%1.script ECHO set address name="Local Area Connection" gateway=10.0.0.1 gwmetric=0 >> netsh.staticip%1.script ECHO set dns name="Local Area Connection" source=static addr=10.0.0.1 register=PRIMARY >> netsh.staticip%1.script ECHO set wins name="Local Area Connection" source=static addr=none >> netsh.staticip%1.script ECHO. >> netsh.staticip%1.script ECHO. >> netsh.staticip%1.script ECHO popd >> netsh.staticip%1.script ECHO # End of interface IP configuration NETSH -f netsh.staticip%1.script
To set static IP address 10.0.0.156 on another server, run the batch file above with 156 as its only command line argument.
| Note: | The lines added by the batch file are the lines we removed from the template. The batch file shown here is meant as an example only. If the lines you removed from your template file were different from the lines shown here, modify your batch code accordingly. |
Windows
Server 2008 Core - Quick Installation Guide.
Many commands listed here use WMIC and aren't limited to Windows Server 2008 (Core).
Included are commands to rename a computer, join a new workgroup, and many more...
Microsoft's Remote Installation Services (RIS)
Unattended Windows, the definitive how-to guide
Unattended, A Windows deployment system at sourceforge.net
Microsoft's
NETDOM
command line tool can be used to:
As we are discussing software installations, we willl focus on
local users and groups.
However, since we'll be using the
NET command, it won't be that
hard to translate the commands to domain users and groups.
NET USER new_account new_password
creates a new user account and sets its password.
The following command will add the new command to
the local Administrators group:
NET LOCALGROUP Administrators new_account /ADD
To create a new domain administrator account, use the following commands:
NET USER new_account new_password /DOMAIN
NET GROUP "Domain Admins" new_account /ADD /DOMAIN
This works for Active Directory too, the new account
will be added to the "Users" container.
In Active Directory, the DS Tools
are the preferred tools to manage user accounts, groups,
computer accounts and OUs.
Many commands on my Useful Commands for Windows Administrators page can be useful for unattended installations too.
Permissions on files and folders can be set using
CACLS or its
Resource Kits
counterparts XCACLS or
SUBINACL.
SUBINACL can even be used to
find
and replace permissions.
To change ownership third party tools like CHOWN or SUBINACL are required.
Registry permissions have always been a pain...
Or wait a minute, is this true...?
Enter SeCEdit & MMC!
Using MMC to create custom security templates, you can use
SeCEdit to apply them unattendedly.
This way you can set permissions, inheritance and/or ownership
on files, folders, services and registry keys.
Read more on my SeCEdit page.
Or download and use Microsoft's SUBINACL.EXE, which allows a little more "detailed" permissions configuration.
For registry changes,
REGEDIT is the tool to use.
It may not be as simple to use as
REG.EXE, but at least its
command line usage has remained unchanged since Windows
NT 4.
If you plan on using REG.EXE,
on the other hand, you'll need to check its version and
modify the command line(s) accordingly.
The command you are likely to use most often is the import (or merge) command:
START /WAIT REGEDIT.EXE /S regfile.REG
REGEDIT.EXE regfile.REG imports
(or merges) regfile.REG into the registry.
/S makes this a silent import (by default
the user is prompted for confirmation, and the import
is confirmed afterwards).
START /WAIT
makes the batch file wait for REGEDIT to finish the
import.
| Note: | It is possible to use SeCEdit
to manipulate registry values, but it is not as simple to
use as REGEDIT. If you also need to set permissions in the registry, do have a look at my SeCEdit page. If you don't need to change anything but permissions in the registry, you may want to check out Microsoft's SUBINACL.EXE. |
• Use
RUNDLL32 PRINTUI.DLL,PrintUIEntry
to install and configure printers.
RUNDLL32.EXE and PRINTUI.DLL are both native in
Windows 2000 and later (as a matter of fact, RUNDLL32.EXE has
been around a lot longer, as you might guess after taking a look at my
RUNDLL page).
With PRINTUI.DLL you can add, configure and delete printers
and printer drivers, both local and remote.
The command line switches can be supplied on the command line or read from
a file.
My ExpPrnDr.bat (Export
Printer Driver) uses Microsoft's DEVCON.EXE
to list all files belonging to a specific printer driver, and PRINTUI.DLL
to install that printer driver on any computer.
• If you prefer VBScript (or actually WSH, including VBScript and JScript),
PRNADMIN.DLL
is the tool for you.
PRNADMIN.DLL is part of the
Windows
Server 2003 Resource Kit, which can be downloaded for free.
Though PRNADMIN.DLL was available in the
Windows 2000 Server Resource Kit
too, it is not available in the free
Windows
2000 Resource Kit Tools for administrative tasks download.
Unlike PRINTUI.DLL, PRNADMIN.DLL can be used to create printer ports too!
• With Microsoft's
PrintMig
tool you can create backups of your complete set of printers,
ports, drivers, print processors and print monitors.
Unfortunately there is no way to selectively backup nor
restore, so you may want to backup a clean test system
with just the printers and components you need to migrate.
If you need to migrate a single printer, use my
ExpPrnDr.bat (Export
Printer Driver) instead.
It uses Microsoft's DEVCON.EXE to list
all files belonging to a specific printer driver, and PRINTUI.DLL
to install that printer driver on any computer.
• An often overlooked way to add a network printer connection to a Windows computer is the following one-liner:
START \\servername\printername
or, if the printer name contains spaces:
START "Printer" "\\servername\printer name"
Granted, this isn't a completely unattended installation, as it will still ask for confirmation from the user. But, hey, it's simple!
• Many hardware drivers come as .MSI files, in which case you can (un)install them like any other .MSI package.
• If a driver comes as a set of (uncompressed) files including a .INF file, use:
RUNDLL32.EXE AdvPack.dll,LaunchINFSection filename.inf,,3
or:
RUNDLL32.EXE SetupAPI.dll,InstallHinfSection DefaultInstall 128 filename.inf
The number 128 in the second
RUNDLL32.EXE
command means no reboot:
| 0 | System provided INF |
| 128 | Set the default path of the installation to the location of the INF (typical setting) |
| +0 | Never reboot the computer |
| +1 | Reboot the computer in all cases |
| +2 | Always ask the users if they want to reboot |
| +3 | Reboot the computer if necessary without asking user for permission |
| +4 | If a reboot of the computer is necessary, ask the user for permission before rebooting |
If the path or file name of the .INF file contains spaces, use the short file name notation. Never use quoted long file names!
A sample using AdvPack.dll, to remove Windows Media Player (9):
RUNDLL32.EXE AdvPack.dll,LaunchINFSection %windir%\INF\wmp.inf,Uninstall
• Another way to install drivers that come with .INF
files is using DEVCON:
DEVCON.EXE [-r] install filename.inf hwid
| -r | reboot automatically if needed |
| filename.inf | .INF to use to install the device |
| hwid | hardware ID to apply to the device |
• Another use for
DEVCON is to remove
existing devices, even when still physically connected,
install new drivers and then rescan for "new" hardware to
reinstall the devices with the new drivers:
:: Remove all existing smartcard readers (modify
:: the FIND command to remove only specific devices)
FOR /F "tokens=1 delims=: " %%A IN ('DEVCON FindAll ˆ=SmartCardReader ˆ| FIND ":"') DO (
DEVCON Remove "@%%~A"
)
:: Uninstall the old driver and install the new driver(s)
•
•
•
:: Scan for new hardware
DEVCON Rescan
To use encryption we will need keys and certificates.
CERTREQ and CERTUTIL from the Windows Server 2003 Support Tools can be used to query and manage (CA) certificates without user interaction.
In Windows 2000 and later,
CRYPTEXT.DLL can be used with
RUNDLL32.EXE:
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtOpenCAT %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtAddCER %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtOpenCER %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtOpenSTR %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtAddCRL %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtOpenCRL %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtAddP7R %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtOpenP7R %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtOpenPKCS7 %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtAddPFX %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtAddSPC %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtOpenPKCS7 %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtAddCTL %1
RUNDLL32.EXE CRYPTEXT.DLL,CryptExtOpenCTL %1
| Note: | This list was generated by running the following command in Windows XP SP2: |
CSCRIPT.EXE //NoLogo GetRunDL.vbs | FIND.EXE /I "cryptext.dll" |
CryptExtAddCER will open the wizard
to add a certificate with a .CER extension,
CryptExtOpenCER will display a .CER
certificate's properties dialog.
You can use KiXtart's or
VBScript's SetFocus( )
and SendKeys( ) functions to "click"
through the wizards' dialogs.
If you use this method in automated installations, make sure
a user is logged in and understands that he/she should not
touch the mouse or keyboard until the installation is finished.
Otherwise, if the wizard's dialog looses focus the installation
will fail.
Microsoft's CAPICOM in conjunction with KiXtart, VBScript or (Object) Rexx can also be used to manage certificates.
Use Windows Installer (executable name: MSIEXEC.EXE) to install .MSI files.
The general command syntax for unattended installations of .MSI files (with verbose logging, without reboot) is:
MSIEXEC.EXE /I myfile.MSI /QN /L*V myfile.LOG /norestart REBOOT=ReallySuppress
The general uninstall command syntax (with verbose logging and without reboot) is:
MSIEXEC.EXE /X myfile.MSI /QN /L*V myfile.LOG /norestart REBOOT=ReallySuppress
or:
MSIEXEC.EXE /X {unique_identifier} /QN /L*V myfile.LOG /norestart REBOOT=ReallySuppress
The latter does not require the original .MSI file.
The unique identifier can be found in the registry under
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall,
it is the name of the subkey.
You may also want to take a look at the
UninstallString
values under each subkey.
My own GetUnins.vbs uses this technique.
More details and links are available on my MSIEXEC.EXE page.
| unique visitors since July 2007 | page last uploaded: 11 January 2010, 17:46 |