Cyclone Server Side Deployment Sytem
This is the server part of the Cyclone deployment system.
- Contains drivers and HDD images
- Database
- Web based log (info from DB)
- Creation of on-the-fly menu's for Syslinux (info from DB)
- Postscript tempplate for auto label printing
Contents
Folder structure
The cyclone/ root folder can be anywhere, everything is relative to it. (I have it as a root folder as the server is dedicated for running it.)
cyclone/ | css/ | CSS style sheets for log web page | |||
db/ | Database for images, menus, schema, log | ||||
DP/ | Driverpacks extraction/processing script | ||||
DPwin7/ | DPx/ | x64/ | Windows 7 64 bit Driverpacks | ||
x32/ | Windows 7 32 bit Driverpacks (not used) | ||||
DPwinxp/ | DPx/ | D/ | Windows XP 32 bit Driverpacks | ||
fonts/ | Fonts for syslinux GD rendered menu | ||||
img/ | Partition image files for WinXP/Win7 etc | ||||
images/ | Pictures for log web page and syslinux menu | ||||
php/ | PHP scripts for system, menu and log data post | ||||
system/ | base/ | Driverpacks BASE system files (XP) | |||
mbr/ | XP/Win7 MBR's | ||||
ps/ | PostScript label source for label printing | ||||
reg/ | Xp/Win7 registry adjustments (RunOnce/CriticalDeviceDatabase) | ||||
sysprep/ | i386/ | $OEM$/ | WinXP sysprep files | ||
win7/ | software/ | Win7 post deployment driver and software scripts | |||
Windows/ | System32/ | sysprep/ | Win7 sysprep files | ||
winxp/ | Win XP post deployment driver and software scripts |
CSS
Simple bit of CSS style sheet for the log and index page and any other pages you may wish with info on them.
This is the way they are referenced (fonts pulled from google)
<link REL=stylesheet TYPE=text/css HREF=../css/cyclone.css> <link href=http://fonts.googleapis.com/css?family=Droid+Sans rel=stylesheet type=text/css>
table {
width:90%;
border-top:1px solid #ff0000;
border-right:1px dashed #e5eff8;
margin:1em auto;
border-collapse:collapse;
border-spacing:10px;
font-smoothing:always;
}
td {
font:bold 0.7em 'Droid Sans', arial, sans-serif;
color:#678197;
border-bottom:1px dashed #e5eff8;
border-left:1px solid #ff0000;
border-spacing:10px;
padding:.3em 1em;
text-align:left;
margin-left: 10px;
margin-right: 10px;
margin-top: 5px;
margin-bottom: 5px;
}
td.t{
color:#ffffff;
}
thead{
text-align:left;
font:bold 1.5em 'Droid Sans', arial, sans-serif;
color:#a8a3d3;
}
h1 {
font:bold 1.4em 'Droid Sans', arial, sans-serif;
color:#678197
}
A {
font:bold 1.4em 'Droid Sans', arial, sans-serif;
color:#678197
}
h2 {
font:bold 1.6em 'Droid Sans', arial, sans-serif;
color:#FFFFFF
}
body { background-color:#06042A;color: #06042A;
font-smoothing:always;
}
DB sqlite3 database
The single database contains all the user configurable items for the HDD images and menu. It is broken down into 8 tables. See below link for full details about the database.
- Note the www server group (www-data) needs read/write access to the DB folder AND the actual database file
$ ls -al db total 1084 drwxrwxr-x 2 clone www-data 4096 2012-02-24 10:26 . drwxr-xr-x 13 clone clone 4096 2012-02-15 09:31 .. -rw-rw-r-- 1 clone www-data 606208 2012-02-24 10:26 cyclone.sqlite
DP/ Driverpack extraction and .inf processing
Simple script that extracts the driverpacks from the downloaded .7z into their folders, maintaining the same structure.
Any existing extracted packs are removed, except the special /CYC folder (e.g. cyclone/DPwin7/DPx/x64/CYC) that contains your custom/additional drivers.
If you have just added a custom driver to /CYC, select just "Process (i)ds only" from the menu, to re-create the DP-$os-$i.list pack<>id map.
#!/bin/bash
#extract packs
extract() {
for i in $dppath
do
#cleanup, be very careful with path as find output going to rm -rf !
[[ -d "$i/" ]] && { rm *.ini 2>/dev/null ; find "$i/" -maxdepth 1 -mindepth 1 -type d ! -name "CYC" -exec rm -rf {} + ; }
done
echo "Extracting packs from DP$os/*.7z to DP$os/DPx/"
7za x "../*.7z" -y -xr'!x??/Server*' -xr'!x??/Vista*' -ssc- > /dev/null #skips uneeded drivers with new NT6 pack format
}
#extract ids
getids() {
for i in $dppath
do
[[ -d "$i/" ]] && echo "Processing infs in $i" || { echo "Skipping $i"; continue; }
#cleanup temp
tmp="/tmp/DP-$os-$i-extract.txt" ; [[ -e "$tmp" ]] && rm "$tmp"
find "$i/" -type f -iname *.inf | while read j
do
echo "Processing $j"
cat "$j" | tr -cd '[:alnum:]\r\n-=&_\\*'\
| grep -Ei '[V][EI][ND]_[A-Z0-9]{4}&|=.*\*[A-Z0-9]{7,8}|.*ACPI\\[A-Z0-9]{7,8}'\
| sort -u \
| grep -Eio '[V][EI][ND]_[A-Z0-9]{4}&[DP][EI][VD]_[A-Z0-9]{4}|\*[a-zA-Z0-9]{7,8}|\\[A-Z0-9]{7,8}'\
| sed "s,$,#${j%/*}," >> "$tmp"
done
chmod -R a+rx "$i"
#fixup output, strip asterix and slashes , slashes from HPQ astertix from Tos
cat "$tmp" | tr -d ' \\*' | tr '&' ':' | sed -e 's/[Vv][EeIi][NnDd]_\|[DdPp][EeIi][VvDd]_//g' | sort -u > "DP-$os-$i.list"
done
}
#############
## Main Choices ##
#############
read -p "Choice 1/2, Please choose: Windows (x)P or Windows (7)" os
case "$os" in
x)
dppath="D"
os=winxp
;;
7)
dppath="x86 x64"
os=win7
;;
*)
echo "Bad choices, quitting" ; exit
;;
esac
read -p "Choice 2/2, Please choose: (e)xtract packs & process ids OR e(x)tract packs ONLY OR process (i)ds only" act
[[ -d "../DP$os/DPx/" ]] || mkdir "../DP$os/DPx/"
pushd "../DP$os/DPx/"
case "$act" in
e)
extract
getids
;;
x)
extract
;;
i)
getids
;;
*)
echo "Bad choices, quitting" ; exit
;;
esac
popd
echo "Finished"
Extraction
Extraction depends mainly on your CPU and a little on I/O, as a guide on this server (see specs here) takes about 10 mins for XP.
INF processing
In order to perform the driverpack matching during imaging, all the inf's are examined and a txt file (DP-xxx-xxx.list) is built up relating the hardware to the relative path the driver is in. Any added custom drivers in the DPxxx/CYC folder are also processed along with the standard DP's. Currently searched for are
- VEN/DEV (PCI)
- VID/PID (USB)
- ACPIxxxxx (ACPI)
- TOSxxxxx (Toshiba)
- HPxxxxxx (HP)
- PNPxxxxx (some wierd and wonderful things on laptops)
This process takes half a minute min and needs to be run anytime the driverpacks are changed. It has no bearing on imaging speed. Quite some time was spent trying to get the info processing as fast as possible!
e.g.
During imaging this list is compared to one created by the client system and the folders containing the matched drivers are copied across. Note, this could be migrated to use the DB but the speed of this matching this way is near instant, adding DB processing would only add server load and slow it down.
DPwin7
Downloaded packs should be put in the appropriate root folders e.g. cyclone/system/DPwin7/
They are extracted/processed by the cyclone/DP/DP-extract.sh script which creates the sub folders and the PCI/USB ID mapping file e.g. /cyclone/DPwin7/DPx/DP-win7-x64.list
At time of writing the packs look like this;
$ ls -l /cyclone/DPwin7/ total 924232 -rw-r--r-- 1 clone clone 21870 2011-11-11 10:00 DP_AMDfilter_wnt6-x64_1110.7z -rw-r--r-- 1 clone clone 189987308 2011-11-11 09:56 DP_Audio_wnt6-x64_1111.7z <SNIP> -rw-r--r-- 1 clone clone 10226022 2011-11-11 10:26 DP_Webcam_wnt6-x64_1103.7z -rw-r--r-- 1 clone clone 13678715 2011-07-27 09:03 DP_WLAN_wnt6-x64_1104.7z drwxr-xr-x 3 clone clone 4096 2012-02-24 11:55 DPx $ ls -l /cyclone/DPwin7/DPx/ total 228 -rw-r--r-- 1 clone clone 226923 2012-02-23 10:11 DP-win7-x64.list drwxr-xr-x 13 clone clone 4096 2010-04-12 08:21 x64 $ ls -l /cyclone/DPwin7/DPx/x64/ total 88 drwxr-xr-x 5 clone clone 4096 2011-03-07 21:01 3 drwxr-xr-x 5 clone clone 4096 2012-01-15 08:16 All drwxr-xr-x 3 clone clone 4096 2011-10-09 08:19 C -rwxr-xr-x 1 clone clone 9829 2012-02-05 12:11 Chipset_x64.txt drwxrwxr-x 11 clone clone 4096 2012-01-17 11:52 CYC <SNIP> drwxr-xr-x 10 clone clone 4096 2010-07-24 11:47 W drwxr-xr-x 5 clone clone 4096 2012-01-15 08:18 Win7
A special CYC/ folder for manually putting extra drivers exists e.g. /cyclone/DPwin7/DPx/x64/CYC , I suggest using a similar structure when organising this.
$ ls -l /cyclone/DPwin7/DPx/x64/CYC total 36 drwxrwxr-x 5 clone clone 4096 2012-01-17 11:53 BCOM drwxrwxr-x 3 clone clone 4096 2011-11-17 12:03 HP_BUT drwxrwxr-x 3 clone clone 4096 2011-11-11 14:29 HP_DG drwxrwxr-x 3 clone clone 4096 2011-11-18 08:06 HP_KEYB drwxrwxr-x 3 clone clone 4096 2011-11-16 08:56 HP_VS drwxrwxr-x 2 clone clone 4096 2011-12-15 13:42 INTEL_HECI drwxrwxr-x 2 clone clone 4096 2011-12-15 13:44 INTEL_SOL drwxrwxr-x 4 clone clone 4096 2011-11-11 14:21 INTEL_WIF drwxrwxr-x 2 clone clone 4096 2011-12-06 16:06 TOS_BT
DPwinxp
$ ls -l /cyclone/DPwinxp/ total 1075176 -rw-r--r-- 1 clone clone 74313034 2010-06-29 12:56 DP_Bluetooth_wnt5_x86-32_910.7z -rw-r--r-- 1 clone clone 4836040 2012-02-16 08:34 DP_Chipset_wnt5_x86-32_1201.7z <SNIP> -rw-r--r-- 1 clone clone 78059723 2012-02-24 12:27 DP_WebCam_wnt5_x86-32_1107.7z -rw-r--r-- 1 clone clone 30485022 2012-02-24 12:14 DP_WLAN_wnt5_x86-32_1202.7z drwxr-xr-x 3 clone clone 4096 2012-02-24 12:25 DPx $ ls -l /cyclone/DPwinxp/DPx/ total 444 drwxr-xr-x 10 clone clone 4096 2010-02-06 20:35 D -rw-r--r-- 1 clone clone 249886 2012-02-24 12:27 DP-winxp-D.list -rw-r--r-- 1 clone clone 1185 2009-10-29 14:53 DriverPack_Bluetooth_wnt5_x86-32.ini -rw-r--r-- 1 clone clone 1068 2012-01-29 16:39 DriverPack_Chipset_wnt5_x86-32.ini <SNIP> -rw-r--r-- 1 clone clone 236 2011-07-17 22:02 DriverPack_WebCam_wnt5_x86-32.ini -rw-r--r-- 1 clone clone 288 2012-02-13 16:44 DriverPack_WLAN_wnt5_x86-32.ini $ ls -l /cyclone/DPwinxp/DPx/D total 32 drwxr-xr-x 7 clone clone 4096 2011-04-22 06:00 3 drwxr-xr-x 28 clone clone 4096 2012-01-29 11:59 C drwxrwxr-x 12 clone clone 4096 2012-02-21 10:21 CYC <SNIP> drwxr-xr-x 73 clone clone 4096 2012-02-07 07:02 W
Special driver folder CYC/
$ ls -l /cyclone/DPwinxp/DPx/D/CYC total 48 drwxr-xr-x 3 clone clone 4096 2011-11-21 16:01 1 drwxr-xr-x 2 clone clone 4096 2011-11-21 16:01 2 drwxr-xr-x 3 clone clone 4096 2011-11-21 16:01 3 <SNIP> drwxr-xr-x 2 clone clone 4096 2011-11-21 15:59 RI drwxrwxr-x 2 clone clone 12288 2012-02-21 10:22 SYN
Random example of the driver match list /cyclone/DPwinxp/DPx/DP-winxp-D.list
04F2:B1C7#D/3/W/A0 04F2:B1CE#D/3/W/V11 04F2:B1CE#D/3/W/V12 04F2:B1CF#D/3/W/Sm 04F2:B1D0#D/3/W/A0 04F2:B1DA#D/3/W/V14 04F2:B1DA#D/3/W/V9 04f2:b1E5#D/3/W/SC1 04F2:B1EA#D/3/W/V11 04F2:B1FC#D/3/W/R0
fonts
Contains any fonts you wish to use, either referenced in the style sheet or used by PHP/GD library generating menu pages on the fly.
img (HDD imgages)
Contains all the HDD images,
- low bandwidth(<=100Mbit) suggest using smallest images with .xz [bandwidth limiting]
- high bandwidth (gigabit) larger but faster decompress images .gz [HDD write speed limiting]
- For absolute speed and consistancy use machine specific images with as much as possible pre-installed. (To deployed OS booting in ~2 minutes)
- For ultimate flexibility use a 'generic' image created on a VM (Virtualbox) and driverpack injection. (Seconds slower, but will need additional few mins while drivers install). This lets you image a machine blind without knowing what drivers it may need beforehand. Very useful if you deal with laptops!
images
Repository for all the images/graphics used in the system, web pages, menu, Linux kernel ppm etc.
PHP
- Generates the Syslinux menus from the DB, and the graphics/text all on the fly. Needs php compiled with GD library. (cyclone.php)
- Outputs the log on the log page (log-show.php)
- Pokes data back into the log (cyclone-post.php)
Menus - cyclone.php
About half the code here is to generate the graphics and isn't really necessary if you want something that is just functional. (Part of the reason was an experiment in the practicalities of on-the-fly generated graphical menus for syslinux/pxelinux as no one seems to have done much with it, or rather I couldnt find anything and did this from scratch)
It is somewhat complicated with three things merged together as a lot of the code is the same, I hope the commenting is good enough!
<?php
/*
This has 3 functions
1) create a pxelinux menu.cfg automatically from the database
2) create a graphical overlay Cyclone menu via modification of a menubackground PNG to represent above
3) create Cyclone Options text menu
default location: /cyclone/cyclone.php
*/
$corefile="/rmdc/isolinux";
$db = new SQLite3("../db/cyclone.sqlite");
//graphical starting points
$x=570;
$y=86;
//main background image to build from
if(isset($_GET["img"])){
$img=imagecreatefrompng("../images/cyclone.png");
}
//limit $l results per page
$l=11;
//get page offset - if more pages than $l
if(isset($_GET["offset"])){
$o=$_GET["offset"];
$otxt="&offset=$o";
} else {
$o=0;
}
//create array of menu types to form Cyclone Options menu
$result = $db->query("SELECT * from menu") or die("\nError in query $q\n");
while($row = $result->fetchArray(SQLITE3_ASSOC)) {
$menuray[]=$row;
}
//CREATE TOP of MENU CFG FILE for "Cyclone Options" main Cyclone menu
//if no menu specified retrurn the one from row 0
$menu = isset($_GET["menu"]) ? $_GET["menu"] : $menuray[0]["menu"];
if(isset($_GET["cfg"])){
echo "
MENU BACKGROUND /cyclone/php/cyclone.php?img=1$otxt&menu=$menu
DEFAULT $corefile/vesamenu.c32
MENU COLOR border 30;44 #00000000 #00000000 none
MENU WIDTH 75
MENU MARGIN 0
MENU ROWS 17
MENU TABMSGROW 21
MENU CMDLINEROW 22
MENU ENDROW 25
Label Back to Main Menu
MENU INDENT 25
kernel $corefile/vesamenu.c32
TEXT HELP
Return to main menu
ENDTEXT
MENU SEPARATOR
";
}
//CREATE TOP of MENU CFG file for Cyclone Options menu
if(isset($_GET["cfgmenu"])){
echo "
MENU BACKGROUND /cyclone/images/cyclone.png
DEFAULT $corefile/vesamenu.c32
MENU COLOR border 30;44 #00000000 #00000000 none
MENU WIDTH 68
MENU MARGIN 15
MENU ROWS 17
MENU TABMSGROW 21
MENU CMDLINEROW 22
MENU ENDROW 25
Label Back to Main Menu
kernel $corefile/vesamenu.c32
TEXT HELP
Return to main menu
ENDTEXT
";
}
//TOP MENU graphical - has to be as text is colourless
if(isset($_GET["img"])){
$back=imagecreatefrompng("../images/back.png");
list($w, $h) = getimagesize("../images/back.png");
imagecopyresampled($img,$back,$x-200,$y-30,0,0,$w,$h,$w,$h);
}
//CREATE BODY of MENU CFG FILE
//find sql query for specified menu
foreach($menuray as $k=>$v){
if($v["menu"]==$_GET["menu"]){$q=$v["sql"];$menutxt=$v["menuname"];break;}
}
//return matching sql query or if none, the query from row 0
$q = isset($q) ? $q : $menuray[0]["sql"];
//this is odd to get around fact there is no numrows facility in sqlite3/php.
if(!empty($o)){
$q.=" LIMIT -1 OFFSET $o";
$max=$o+$l;
} else {
//dont set limit in SQL here as otherwise wont know if more results exist
$max=$l;
}
$result = $db->query($q) or die("\nError in query $q\n");
//reset $yy
$yy=$y;
while($row = $result->fetchArray(SQLITE3_ASSOC)) {
//reset xx
$xx=$x;
foreach ($row as $key=>$val){
$$key = $val;
//create background img if set
if(isset($_GET["img"])){
if(file_exists("../images/$val.png")){
//echo "png exists v $val vv $$val k $key kk $$key\n";
$$val=imagecreatefrompng("../images/$val.png");
list($w, $h) = getimagesize("../images/$val.png");
imagecopyresampled($img,$$val,$xx,$yy,0,0,$w,$h,$w,$h);
//shift back 50 pixels
$xx-=50;
}
//echo "k $key kk $$key v $val vv $$val \n";
//if($key=="scheme"){imagettftext($img, 10, 0, $xx-185,$yy+15, "0x10FFFFFF", "../fonts/Verdana.ttf", "$val");}
}
}
//shift down 32 pixels (16 one line 32 two lines)
$yy+=16;
if(isset($_GET["cfg"])){
echo "
LABEL $scheme
LINUX $kernel $append spath=$spath runinit=$runinit serveraddr=$serveraddr snum=$snum imgmode=$imgmode label=$label
INITRD $initrd
TEXT HELP
[$scheme] [$imgmode] [$label]
ENDTEXT
#MENU SEPARATOR
";
}
//increment row count / offset
$o++;
//if reached limit, output a next page menu entry
if($o==$max){
if(isset($_GET["img"])){
$next=imagecreatefrompng("../images/next.png");
list($w, $h) = getimagesize("../images/next.png");
imagecopyresampled($img,$next,$x-20,$yy,0,0,$w,$h,$w,$h);
$previous=imagecreatefrompng("../images/previous.png");
list($w, $h) = getimagesize("../images/previous.png");
imagecopyresampled($img,$previous,$x-20,$yy+=16,0,0,$w,$h,$w,$h);
}
if(isset($_GET["cfg"])){
echo "
LABEL Next Page
KERNEL $corefile/vesamenu.c32
APPEND /cyclone/php/cyclone.php?cfg=1&menu=$menu&offset=$o
TEXT HELP
Next Page
ENDTEXT
LABEL Previous Page
KERNEL $corefile/vesamenu.c32
APPEND /cyclone/php/cyclone.php?cfg=1&menu=$menu&offset=".max(0,($o-$l-$l))."
TEXT HELP
Previous Page
ENDTEXT
";
}
break;
}
}
//Write out background image
if(isset($_GET["img"])){
//font size and crude scaling offsetting x from screen right
$tz=32;
$tx=$x-strlen($menutxt)*$tz*0.7;
imagettftext($img, $tz, 0, $tx, 465, "0x70FFFFFF", "../fonts/Verdana.ttf", "$menutxt");
header("Content-type: image/png");
imagepng($img);
imagedestroy($img);
}
//3
//CREATE Cyclone Options MENU CFG FILE
if(isset($_GET["cfgmenu"])){
echo "MENU SEPARATOR";
foreach ($menuray as $row){
foreach ($row as $key=>$val){
$$key = $val;
}
echo "
LABEL -> $menuname
KERNEL $corefile/vesamenu.c32
APPEND /cyclone/php/cyclone.php?cfg=1&menu=$menu
";
}
}
//DESTROP DB OBJECT
unset($db);
?>
Show log
<html>
<head>
<title>Cyclone Log</title>
<link REL=stylesheet TYPE=text/css HREF=../css/cyclone.css>
<link href=http://fonts.googleapis.com/css?family=Droid+Sans rel=stylesheet type=text/css>
</head>
<body>
<img align=right src=../images/lighthttpd.png border=0><img align=right src=../images/sqlite.png border=0>
<div align=center><h2>Cyclone Log File</h2></div>
<FORM action=<?php echo $_SERVER['PHP_SELF']; ?> method=post>
<select name="query">
<option value="SELECT date,imgtime,product,serialnum,mac,hostname from log ORDER by date DESC LIMIT 25">Last 25</option>
<option value="SELECT * from log ORDER by date DESC LIMIT 25">Last 25 Advanced</option>
<option value="SELECT date,imgtime,product,serialnum,mac,hostname from log ORDER by date DESC LIMIT 50">Last 50</option>
<option value="SELECT * from log ORDER by date DESC LIMIT 50">Last 50 Advanced</option>
<option value="SELECT date,imgtime,product,serialnum,mac,hostname from log ORDER by date DESC LIMIT 100">Last 100</option>
<option value="SELECT * from log ORDER by date DESC LIMIT 100">Last 100 Advanced</option>
<option value="SELECT date,imgtime,product,serialnum,mac,hostname from log ORDER by date DESC">ALL</option>
<option value="SELECT * from log ORDER by date DESC">ALL Advanced</option>
</select>
<input type="submit" name="Submit" value="Submit">
</FORM>
<?php
// /log/index.php
$db = new SQLite3("../db/cyclone.sqlite");
$q = isset($_POST["query"]) ? $_POST["query"] : "SELECT date,imgtime,product,serialnum,mac,hostname from log ORDER by date DESC LIMIT 20";
$result = $db->query($q) or die("Error in query");
echo "<table border=1 class=m width=95%>";
$i=0;$headers="";$cols="";
while($row = $result->fetchArray(SQLITE3_ASSOC)) {
foreach ($row as $key=>$val){
if ($i==0) { $headers.="<td class=t>$key</td>"; }
$cols.="<td>$val</td>";
}
if ($i==0) { echo "<tr>$headers</tr>\n";}
echo "<tr>$cols</tr>\n";
$i++;$headers="";$cols="";
}
echo "</table>";
// all done
// destroy database object
unset($db);
?>
<img align=right src=../images/lighthttpd.png border=0>
</BODY>
Add to log
<?php
/*
query DB: ../db/cyclone.db
return: text string and carriage return for each result
default file location: /cyclone/cyclone-post.php
*/
//debug
//print_r($_POST);
if (isset($_POST["q"])) {
$q=stripslashes($_POST["q"]);
$db = new SQLite3("../db/cyclone.sqlite");
$result=$db->query($q)or die("Error in query\r\n");
if (strpos($q,"INSERT")===false) {
while($row = $result->fetchArray(SQLITE3_ASSOC)) {
foreach($row as $k=>$v){
echo "$k=\"$v\"\n";
}
}
}
unset($db);
}
?>
system
This entire folder gets copied to the machine being imaged. Some of the paths here may look a bit odd it is just to make their final copying simpler.
system/ cyclone.sh
cyclone.sh the main script that runs on the client to control the whole imaging cycle See here for full details of the system (Client Side Deployment System)
BASE
This is mostly a finisher for Win XP, it sorts out driver conflicts using the DP ini files which are part of the packs. This is the system as put together by driverpacks.net team :)
devcon.exe DP_Install_Tool.cmd DPInst.xml DPsFnshr.exe DSPdsblr.exe mute.exe ROE.exe DevPath.exe DPINST.exe DPs_BASE.exe DPsFnshr.ini makePNF.exe pmtimer.exe setup.exe
mbr
Contains Win XP/Win 7 boot records. MBR code is less important than you may think - win7 and server 2008 use came code. Syslinux MBR could replace all of them.
<MBR(partition table)><partition1>...<partition4>
win7-mbr-446 winxp-mbr-446 server2008-mbr-446
ps
PostScript label source template for label printing ( ps/uol-label.ps) . This gets modified on the fly to create a machine label that is printed out, containing things like machine name, MAC, serial number etc. It also encodes this data into a 3D QR barcode purely in Postscript, thanks to super clever Terry Burton for this bit! The idea is if you wish to quickly audit a room of machines you can go around with a scanner and zap them all quickly to get a completely accurate data set.
This is the small snippet of the PostScript code, the HHH,SSS,MMM etc are replaced with various information gathered from the machine/dmidecode data.
GS
1.1 -1.1 scale
148 -65 M (HHHHHHHHHH,SSSSSSSSSSSSSSSS,MMMMMMMMMMMMMMMMM,DDDDDDDDDD) (version=3 eclevel=L) /qrcode /uk.co.terryburton.bwipp findresource exec
%150 -65 M (HH,SSSS,MMMMMM,DDD) (version=3 eclevel=L) /qrcode /uk.co.terryburton.bwipp findresource exec
GR
reg
Windows registry files to inject after imaging. Currently only used for winXP.
cddb.reg winxp-RunOnceEx.reg
- RunOnce, adds key to RunOnceEx to begin the Windows portion of the setup (join to domain, install software etc.)
- CriticalDeviceDatabase (CDDB), injects MassStorage drivers into the CDDB and service sections of the registry, allowing it to boot without the dreaded 0x7b stop error! This also lets AHCI mode work in XP without problem.
sysprep
WinXP sysprep
$ tree /cyclone/system/sysprep /cyclone/system/sysprep ├── i386 │ └── $OEM$ │ └── CMDLINES.TXT └── sysprep.inf
sysprep.inf
- the basic WinXP sysprep file, modified on the fly during imaging to alter HAL etc.
- HAL only gets 'try and update to...' (UpdateHAL=) from default (standard HAL) if it needs to be.
;richud.com [Unattended] OemSkipEula=Yes InstallFilesPath=C:\sysprep\i386 ;UpdateHAL= UpdateInstalledDrivers = Yes DriverSigningPolicy = Ignore NonDriverSigningPolicy = Ignore OemPreinstall=Yes [GuiUnattended] AdminPassword=* EncryptedAdminPassword=NO AutoLogon=Yes AutoLogonCount=1 OEMSkipRegional=1 TimeZone=85 OemSkipWelcome=1 [UserData] ProductKey=xxxxx-xxxxx-xxxxx-xxxxx-xxxxx FullName="*" OrgName="*" ComputerName=* [Display] AutoConfirm=1 [RegionalSettings] Language=00000809 [Identification] JoinWorkgroup=WORKGROUP [Networking] InstallDefaultComponents=Yes
cmdlines.txt
- anything needing to run as XP boots prior to most other things, currently just for PnP cleanup
- remember there is no command shell running, so any .batch script etc needs cmd /c running before it.
[COMMANDS] "C:\sysprep\sysprep -clean"
win7
Win7 post deployment driver and software scripts
- Installs software that changes a lot more than the image (Flash etc.)
$ tree /cyclone/system/win7 /cyclone/system/win7 ├── cyclone-win7.bat ├── dpinst64.exe ├── DPINST.exe ├── dpinst.xml └── software ├── AdbeRdr1012_en_US.exe ├── CertMgr.Exe ├── install_flash_player_ax_64bit.exe ├── lerootca.der ├── savw_97_sa_sfx.exe ├── sophos-97-silent.exe ├── sw_lic_full_installer.exe └── win7-eduroam.xml
cyclone-win7.bat
@echo off
TITLE CYCLONE by RMDC
IF /i "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
rem Install Drivers
%~dp0dpinst64.exe /path %SystemRoot%\inf\x64
rem Rearm and activate Office 2010
"%PROGRAMFILES(x86)%\Common Files\microsoft shared\OfficeSoftwareProtectionPlatform\OSPPREARM.EXE" >nul
"%SystemRoot%\system32\cscript.exe" "%PROGRAMFILES(x86)%\Microsoft Office\Office14\OSPP.VBS" /act >nul
)
IF /i "%PROCESSOR_ARCHITECTURE%" == "X86" (
rem Install Drivers
%~dp0dpinst.exe /path %SystemRoot%\inf\x32
rem Rearm and activate Office 2010
"%PROGRAMFILES%\Common Files\microsoft shared\OfficeSoftwareProtectionPlatform\OSPPREARM.EXE" >nul
"%SystemRoot%\system32\cscript.exe" "%PROGRAMFILES%\Microsoft Office\Office14\OSPP.VBS" /act >nul
)
rem Update all accounts to not expire
rem NET ACCOUNTS /MAXPWAGE:UNLIMITED
wmic useraccount where "Name like '%%'" SET PasswordExpires=FALSE 2>nul >nul
rem Change passwords
net user localuser xxxxxxxxx >nul
net user localadmin1 xxxxxxxxx >nul
rem Install Adobe Reader
rem http://ardownload.adobe.com/pub/adobe/reader/win/10.x/10.1.1/en_US/AdbeRdr1011_en_US.exe
%~dp0software\AdbeRdr1012_en_US.exe /sAll /rs /l /msi /qn /norestart ALLUSERS=1 EULA_ACCEPT=YES SUPPRESS_APP_LAUNCH=YES DISABLE_ARM_SERVICE_INSTALL=1
rem Install Flash
%~dp0software\install_flash_player_ax_64bit.exe -install
rem Install Shockwave
rem http://www.adobe.com/go/sw_full_exe_installer
%~dp0software\sw_lic_full_installer.exe /S
rem Setup Eduroam
%~dp0software\certmgr.exe /add %~dp0software\lerootca.der /s /r localMachine Root
netsh wlan add profile filename=%~dp0software\win7-eduroam.xml user=all
rem Sophos Install
%~dp0software\savw_97_sa_sfx.exe /S
start /wait %~dp0software\sophos-97-silent.exe
timeout /t 5
rmdir /q /s c:\savw_97_sa
dpinst.xml
This will install all 'present' hardware. Windows uses its PnP installer to choose best match if mutliple DP's support same hardware.
<?xml version="1.0"?> <dpInst> <enableNotListedLanguages/> <suppressWizard/> <quietInstall/> <suppressEulaPage/> <scanHardware/> <legacyMode/> <search> <subDirectory>*</subDirectory> </search> </dpInst>
Windows
Confusingly named, was left this way so it easily copied over from cyclone.sh keeping same path structure as what it overwrites.
Win7 sysprep file (unattend.xml)
$ tree /cyclone/system/Windows /cyclone/system/Windows └── System32 └── sysprep └── unattend.xml
unattend.xml
<ComputerName>*</ComputerName> modified on the fly by cyclone.sh post imaging, passwords or anything else could be too.
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OOBE>
<HideEULAPage>true</HideEULAPage>
<SkipMachineOOBE>true</SkipMachineOOBE>
<SkipUserOOBE>true</SkipUserOOBE>
</OOBE>
<AutoLogon>
<Password>
<Value>xxxxxxxx</Value>
<PlainText>true</PlainText>
</Password>
<Username>Administrator</Username>
<Enabled>true</Enabled>
<LogonCount>1</LogonCount>
</AutoLogon>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<Description>RMDC Post Installer</Description>
<CommandLine>cmd /C c:\win7\cyclone-win7.bat</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>2</Order>
<Description>Cleanup</Description>
<CommandLine>cmd /C rmdir /s /q c:\win7</CommandLine>
</SynchronousCommand>
</FirstLogonCommands>
</component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ComputerName>*</ComputerName>
</component>
</settings>
</unattend>
winxp
Windows XP post deployment files, replacement kernels.
$ ls /cyclone/system/winxp
AdFind.exe cyclone-winxp.bat grep.exe halacpi.dll hal.dll hwcheck.bat hwcntrl.exe NETUSER.EXE ntkrnlmp.exe sleep.exe Au3Info.exe devcon.exe halaacpi.dll halapic.dll halmacpi.dll hwcntrl.au3 netdom.exe newsid.exe sed.exe tr.exe
cyclone-winxp.bat
@echo off
COLOR 18
mode con cols=60 lines=20
SETLOCAL ENABLEDELAYEDEXPANSION
SETLOCAL ENABLEEXTENSIONS
TITLE CYCLONE by RMDC
rem stopping System Restore service to speed things up
sc stop srservice >nul
rem imaging flow
rem fimg hwchecks, no finisher , newsid, reboot, joindomain , clean
rem Domain hwchecks, finisher , joindomain , clean
rem Standard hwchecks, finisher , clean
rem using sysprep -pnp initially did or does STOP sysprep -clean working
rem hostn replaced by script
set u=joindomain
set p=%u%
set hostn=HOSTN
set runcmd=RUNCMD
rem Stripping any whitespaces
set hostn=%hostn: =%
rem ######################
rem ## non forced image ##
rem ######################
if not [%runcmd%] == [fimg] (
rem Starting HW Controller in continue mode
start "RMDC" "%~dp0\hwcntrl.exe" continue
rem Wait for any new hardware detection to start
call "%~dp0\hwcheck.bat" wait
rem Redetect PnP devices with devcon incase things missed due to dependant hardware
echo Re-scan for new devices
rem start /wait "RMDC" RunDll32.exe Syssetup.dll,UpdatePnpDeviceDrivers
rem altered 11 aug 2011 changed grep.exe -E "PCI|ACPI|USB|HDAUDIO to be ^ start line match as was mathicng USB in text on line below
FOR /F "delims=" %%d IN ('%~dp0\devcon.exe status * ^| %~dp0\grep.exe -B2 -E "has a problem|PCI Device" ^| %~dp0\grep.exe -E "^PCI|^ACPI|^USB|^HDAUDIO" ^| %~dp0\sed.exe "s/\([^\]*\)\\[0-9].*/\1/g"') DO (
echo Restarting device "%%d"
"%~dp0\devcon.exe" restart "%%d"
)
rem altered 11 aug 2011 - needed to fix non restarting USB on DQ965
start /wait "RMDC" RunDll32.exe Syssetup.dll,UpdatePnpDeviceDrivers
rem slow machines need pause here as takes a few seconds for newdev.dll to get started
"%~dp0\sleep.exe" 10
rem Wait for any new hardware detected to finish
call "%~dp0\hwcheck.bat"
rem DriverPack Finisher
"%systemdrive%\DPsFnshr.exe"
rem Wait for any new hardware detected to finish
call "%~dp0\hwcheck.bat"
rem Killing task
taskkill /F /T /IM hwcntrl.exe 2>nul >nul
)
rem #######################
rem ## forced image fimg ##
rem #######################
if [%runcmd%] == [fimg] (
if /i [%computername%]==[%hostn%] (
rem newsid will have run if this is true
goto joindomain
)
rem for domain and not sysprepped
rem Starting HW Controller in continue mode
start "RMDC" "%~dp0\hwcntrl.exe" continue
rem Wait for any new hardware detection to start
call "%~dp0\hwcheck.bat" wait
rem Rerun on reboot, must be before newsid
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\920" /V 1 /D "cmd /c \"%~dp0%~nx0\"" /f >nul
echo Generating new SID and Renaming machine to %hostn%
rem NewSID will cause AutoLogon to fail if;
rem if AutoLogonCount has reached zero , running newsid and setting it back to 1 wont work (will if not using newsid)
rem if AutoAdminlogon was set to 0 , running newsid and setting it to 1 wont work (it gets set back to 0 with reboot no matter what)
rem changing the admin password here wont work either - the DefaultPassword gets erased if wasnt a password set previously
REG ADD "HKCU\Software\Sysinternals\NewSID" /V EulaAccepted /t REG_DWORD /D 1 /f >nul
"%~dp0\newsid.exe" /a /n %hostn%
rem run newsid last as it breaks things like RunOnceEx also wont erase runonceex default as erased after key run
goto restart
)
rem ######################
rem ## universal domain ##
rem ######################
if [%runcmd%] == [Domain] (
goto joindomain
)
rem ########################
rem ## universal standard ##
rem ########################
if [%runcmd%] == [Standard] (
rem setting up generic local accounts
net user localuser xxxxxxxxxx /ADD >nul
"%~dp0\netuser.exe" "localuser" /pwnexp:y >nul
net user localadmin1 xxxxxx%hostn% /add >nul
"%~dp0\netuser.exe" "localadmin1" /pwnexp:y >nul
net localgroup Administrators localadmin1 /add >nul
goto cleanup
)
rem #################
rem ## join domain ##
rem #################
:joindomain
echo Checking for existance of %hostn% on AD
FOR /F "delims=" %%h in ('%~dp0\adfind.exe -c -u xxx\%u% -up %p% -h xxx.xx.ac.uk -b "DC=xxx,DC=xx,DC=ac,DC=uk" -f "(&(objectCategory=Computer)(name=%hostn%))" -dsq') do set adr=%%h
IF NOT [%adr%.] == [.] (
echo Found machine %adr% now joining to AD
"%~dp0\netdom.exe" join %hostn% /domain:xxx.xx.ac.uk /userd:%u% /passwordd:%p% >nul
rem Fixing remote assistance
sessmgr.exe -service
rem Adding GPO key to make sure it syncs on logon
REG ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Winlogon" /V SyncForegroundPolicy /D 1 /f >nul
rem remove Sophos entry from SMS so it will get reinstalled
REG DELETE "HKLM\SOFTWARE\Microsoft\SMS\Mobile Client\Software Distribution\Execution History\System\UL10017F" /f
rem Forcing group policy update
gpupdate /force >nul
goto cleanup
) ELSE (
echo Machine not found on AD, assuming something went wrong
echo Pressing enter now will clean up and reboot
echo If you want to try again terminate the batch with cntrl C and rerun cyclone.bat when fixed
pause
goto cleanup
)
rem #############
rem ## cleanup ##
rem #############
rem added D cleanup 14 june 2010 also with Everyone perms
:cleanup
echo Cleaning Up....
taskkill /F /T /IM hwcntrl.exe 2>nul >nul
del /q %SystemDrive%\*.exe 2>nul >nul
del /q %SystemDrive%\*.dll 2>nul >nul
del /q %SystemDrive%\*.xls 2>nul >nul
del /q %SystemDrive%\*.txt 2>nul >nul
rem STAC audio does/didnt install properly and try and run out of driverpack installation location
net stop stacsv 2>nul >nul
sc delete stacsv 2>nul >nul
rd /q /s "%SystemDrive%\D" 2>nul >nul
echo Setting local admin password to dfW2g1@S0r
net user administrator dfW2g1@S0r >nul
rem Reset DevicePath key
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion" /v DevicePath /t REG_EXPAND_SZ /d %%SystemRoot%%\Inf; /f >nul
rem Remove AutoAdminLogon
REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /V AutoAdminLogon /D 0 /f >nul
rem Remove install folder when first user login, folder has Everyone permission so deletable
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\930" /V 1 /D "cmd /c rd /q /s \"%~dp0\"" /f >nul
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\930" /V 2 /D "cmd /c rd /q /s \"%SystemDrive%\D\"" /f >nul
goto restart
rem ################
rem ## restart pc ##
rem ################
:restart
echo Restarting System
shutdown -r -f -t 1
goto end
:end
hwcheck.bat
This is called several times during the post image process. It relies on status of newdev.dll to detect what is going on. Relies on external program tr.exe for output formatting and sleep.exe for sleep. Depending on how its called it can ;
- Cause a delay until hardware starts to be installed
- Cause a delay while hardware is being installed
@echo off
COLOR 18
SETLOCAL ENABLEDELAYEDEXPANSION
rem loop count 80 is not enough on Tecra M10
set l=80
:hwalive
IF [%1]==[wait] (
rem Waiting for rundll32.exe to start
echo Waiting for new hardware detection to start
FOR /L %%t IN (1,1,!l!) DO (
"%windir%\system32\tasklist.exe" /fi "MODULES eq newdev.dll" 2>nul | "%windir%\system32\find.exe" "rundll32.exe" 2>nul > nul
IF !ERRORLEVEL! EQU 0 (
color 13
rem Detected rundll32.exe running looking at new hardware
goto hwcheck
) ELSE (
echo %%t | "%~dp0\tr.exe" -d "\n"
rem echo [%%t/!l!] Waiting 10s for hardware install to start .....
"%~dp0\sleep.exe" 10
)
)
)
rem recode with one for loop if bored oneday
:hwcheck
rem Waiting on all PnP hardware to finish detecting
echo Waiting for new hardware detection to finish
FOR /L %%t IN (1,1,!l!) DO (
"%windir%\system32\tasklist.exe" /fi "MODULES eq newdev.dll" 2>nul | "%windir%\system32\find.exe" "rundll32.exe" 2>nul > nul
IF !ERRORLEVEL! NEQ 0 (
COLOR 12
rem Detected PnP finished
goto hwend
) ELSE (
echo %%t | "%~dp0\tr.exe" -d "\n"
rem echo [%%t/!l!] Waiting 10s for hardware install to finish .....
"%~dp0\sleep.exe" 10
)
)
:hwend
hwcntrl.au3
This AutoIT script(aka Hardware Controller script) is compiled to hwcntrl.exe. Has been around several years as you can see and occasionally tweaked if anything new found. It should catch everything you are likely to come across.
It serves to do several things;
- supress dialog boxes
- go through any wizards that may pop up
- catch some wierdness various installs may throw up
; AutoIt Version: 3.0
; Author: richud.com
; hwcntrl Hardware Control
;modified from the newest one could find on hdd ghost backup dec 07
;18 march 09 - fixed CmdLine array issue that allready existed
;18 march 09 - added 8104 option to look on interwebs
;7 jun 11 added widcomm fix, rmeoved sysprep bits
;3 aug 11 added stac fix for elitebook 2540p
Dim $vr = "hwcntrl - Hardware Control"
If WinExists($vr) Then Exit ; It's already running
AutoItWinSetTitle($vr)
Dim $tit[10]
Dim $act[10]
;catch anything that didnt get a driver installed
$tit[0]="Found New Hardware Wizard"
;CANCEL
;$act[0]="[ID:2]"
;YES 8104 , NEXT (look on interweb)8104 , NO 8105
$act[0]="[ID:8104]"
;catch anything that didnt get a driver installed
$tit[1]="Found New Hardware Wizard"
;CANCEL
;$act[1]="[ID:2]"
;NEXT
$act[1]="[ID:12324]"
$tit[2]="Found New Hardware Wizard"
;FINISH
$act[2]="[ID:12325]"
;catch any non signed drivers that the dpsdsblr misses - soft inst STOP ID 5306
$tit[3]="Hardware Installation"
$act[3]="[ID:5303]"
$tit[4]="Software Installation"
$act[4]="[ID:5303]"
;GUI setup phase while KTD running - restart pc YES ID 6
$tit[5]="System Settings Change"
$act[5]="[ID:7]"
;confirm not to overwrite new files with old - 407 no to all - 6 yes 7 no
$tit[6]="Confirm File Replace"
$act[6]="[ID:407]"
;WIDCOMM bluetooth install dont run silently says admin privaledges
$tit[7]="Bluetooth Software Installer Information"
;OK
$act[7]="[ID:2286]"
$tit[8]="Bluetooth Software -"
;OK
$act[8]="[ID:2136]"
;STAC error elitebook 2540p problem
$tit[9]="STacSV.exe - Application Error"
$act[9]="[ID:1]"
If $CmdLine[0] > 0 Then
If $CmdLine[1] = "suppress" Then
$act[0]="[ID:2]"
$act[1]="[ID:2]"
EndIf
EndIf
;MsgBox(0, $CmdLine[1], $act[0])
Func hwsupres()
For $i = 0 To UBound($tit)-1
If WinExists($tit[$i]) Then
If ControlCommand($tit[$i], "",$act[$i],"IsVisible","" ) And ControlCommand($tit[$i], "",$act[$i],"IsEnabled","" ) Then
;MsgBox(0,$tit[$i],$act[$i])
ControlClick($tit[$i],"",$act[$i])
EndIf
EndIf
Next
EndFunc
Do
hwsupres()
sleep(1000)
Until 1=2