Wednesday, August 02, 2006

Utilizing WinPE in deployments

Browsing the web I found a good page highlighting some advantages of WinPE.

The article is a little old and WinPE is now available to downlad from MS sites and will be available with Vista. As well there is now a way to load the whole WINPE CD image into RAM so you don't require a CD drive.

In my environment I use WinPE to help with the deployment process and it does it's job wonderfully. I've modified it to use Windows Post Installer (WPI) to give an interface for the apps that should be deployed to the target system.

My current environment is setup as follows:

1) WinPE boots and logs the IP address of the present machine onto a network share. Our company has a site license for RAdmin so that is installed on WinPE. This logging of its IP Address allows me to RAdmin into it and administer the WinPE environment without being physically present.

2) WinPE presents a batch file "choices" screen, Reimaging is one of the options.

Choosing reimage causes the following to happen:

3) WinPE prompts for your user name, password and computer name which are stored in text files on a RAM drive in WinPE.

4) WinPE opens up WPI with a list of programs.

5) Clicking "Begin install" causes WPI to output the programs selected into a text file on the WinPE RAM Drive.

6) RDeploy is then called to image the drive with the corporate standard image (I've learned I may need to add a choice to select between Tablet, MultiProcessor or Single Processor soon. I've thought another way around it I'll describe later).

7) After imaging the drive, FIRM.EXE (File System Independent Resource Management) copies over the approriate sysprep.inf while which contains your user name, password and parses the computer name you entered earlier to determine the correct OU that the system will be placed under. With this information the sysprep file contains enough information to join the machine to the domain without user intervention.

FIRM also copies over all the text files that contain your user name and password onto the machine for parsing later (this later is to map file shares and execute commands under a domain account).

8) The machine reboots and joins to the domain as per the sysprep script.

More to come later.

Filter orders down to the hardware level

So we have basic detection based on customer orders but there is a way to do it based on hardware configuration. I consider hardware configuration to be a poor way of filtering, but it is sometimes necessary as a company won't always update SKU's or the file that we filter fast enough (bad business process in that case). Sometimes though, it's required if you want to limit installs to useful software. If you were an OEM and shipped NERO with every system, NERO may not be useful to users who have only CD drives (non-writeable). To filter thourgh to ensure usefullness, it now becomes a two stage process:

Find the SKU or customer order to ensure he gets, say, NERO.

--------------------------------
:Customer order file
:responses.txt
NERO-Y
--------------------------------

So we check to ensure that the client/customer has requested NERO:

------------------------------
:Check for NERO
findstr /I /C:"NERO-Y" responses.txtIF '%ERRORLEVEL%' == '0' (
SET NERO-FOUND=1
ECHO Nero was found!
) ELSE (
SET NERO-FOUND=0
ECHO Nero was NOT found!
)
------------------------------
And now we filter for the hardware ID using DevCon:

------------------------------
:Find the CD Burning Hardware ID
Devcon findall hwids * > "%userprofile%\desktop\HWIDS.TXT"

IF '%NERO-FOUND%' == '1' (
findstr /I /C:"IDE\CDROMSONY_CD-RW__CRX230ED" HWIDS.TXT
)
IF '%ERRORLEVEL%' == '0' (
:run silent setup command
NERO.EXE /S
ECHO Nero was installed!
)
---------------------------------

We don't need an "ELSE" in the above as we expect it to fail gracefully and not require more code to tell it to simply continue as it will do so anyways.

And now the OEM or corporation won't install useless software unless hardware that can take advantage of it is present. :)

Tuesday, August 01, 2006

Failing Gracefully is the essence of life

To someone like myself whose never taken a programming course, this is revitalizing stuff:

I am very much in awe of the guy who invented barcodes; they are incredibly elegant. One trick is to notice that every digit in a barcode is two black stripes and two white stripes, so if you've read black-white-black-white you know you have a digit, no matter how quickly it happened. (If it happened too quickly, you can decide you're reading garbage and just bail.)
One of the rules of writing algorithms that I've recently been sort of toying with is that we (as programmers) spend too much time trying to find provably correct solutions, when what we need to do is write really fast heuristics that fail incredibly gracefully.
This is almost always how nature works. You don't have to have every cell in your eye working perfectly to be able to see. We can put together images with an incredible amount of damage to the mechanism, because it fails so gracefully and organically.
This is, I am convinced, the next generation of programming, and it's something we're already starting to see: for instance, vision algorithms today are modeled much more closely after the workings of the eye, and are much more successful than they were twenty years ago.
Wait wait wait, can you elaborate on this heuristics bit being the next big thing, because you just bent some people's brains. When I normally think of heuristics in computer science, I think of either "an educated guess" or "good enough".
I.E., a game programmer doesn't have to run out Pi to the Nth degree to calculate the slope of a hill in a physics engine, because they can get something 'good enough' for the screen using a rougher calculation... but hasn't it always been like that out of necessity?

Heuristics (the way I'm using them) are basically algorithms that are not guaranteed to get the right answer all the time. Sometimes you can have a heuristic that gets you something close to the answer, and you (as the programmer) say, "This is close enough for government work."
This is a very old trick of programming, and it's a very powerful one on its own. Trying to make algorithms that never fail, and proving that they can never fail, is an entire branch of computer science and frankly one that I think is a dead end. Because that's not the way the world works.
When you look at biological systems, they are usually perfect machines; they have all these heuristics to deal with a variety of situations (hey, our core temperature is too hot, let's release sweat, which should cool us off) but none of them are anywhere near provably correct in all circumstances (hey, we're actually submerged in hot water, so sweat isn't effective in cooling us off). But they're good enough, and they fail gracefully.
You don't die immediately if sweating fails to cool you; you just grow uncomfortable and have to make a conscious reponse (hey, I think I'll get out of this hot tub now).
Programs need to be written this way. In the case of reading bar codes, you don't care if you read garbage a thousand times a second. It doesn't hurt you. If you write an algorithm that looks for barcodes everywhere in the image, even in the sky or in a face or a cup of coffee, it's not going to hurt anything. Eventually the user will hold up a valid barcode, it'll read it, the checksum will verify, and you're in business.
And the barcode recognizer doesn't have to understand every conceivable way a barcode can be screwed up. If the lighting is totally wrong, or the barcode is moving, the user has to take conscious action and, like, tilt the book differently or hold it still. But this kind of feedback is immediately evident, and it's totally natural.
Because I can try 1,000 times a second, I can give immediate feedback on whether I have a good enough image or not, so the user doesn't, like, take a picture, hold her breath for four seconds, have the software go "WRONG," try adjusting the book, take another picture, hold her breath...
Humans are incredibly good at trying new and random things when they get instant feedback. It's the basis of all learning for us, and it's an absolutely fundamental rule of UI design. (This is also the basis of the movement away from having modal dialogs that pop up and say, "Hey, you pressed a bad key!" If you have to pause and read and dismiss the dialog, the lesson you get is, "Stop trying to learn this program," not, "Try a different key."
The Mac and NeXTstep were pioneers in getting this right -- just beep if the user hits a wrong key, so if she wants she can lean on the whole keyboard and see if ANY keys are valid, and there's no punishment phase for it.)


Failing gracefully... That's key. It's in our blood ;)

Flexibility and accomdating clients

Last entry I covered the differences between flexible and static methods of deployment and the conclusion at the end was a mix of the two. It has been my experience that the best way to mix the two is ensure all variable information is gathered from the start. This does two things:

1) Eliminates technician wait time in that you shouldn't have to wait for a task to "catch up" till you can respond to it
2) Removes pauses that can extend the length of time an unsupervised process

To accomplish this we need ways of storing data from the client when they order the machine and a system of pulling the data out and configuring the machine.

STORING DATA:

Data can be stored in various fashions, a text-file is the fashion I use the most as it's simple, quick, and easy to parse. To generate a text file from a user's response we can use a simple batch script:
---------------------------
@ECHO OFF
set /p NAME=What is your name?
set /p OFFICE=Do you want MS OFFICE [y/n]?

ECHO %NAME% > "%userprofile%\desktop\responses.txt"
ECHO OFFICE-%OFFICE% >> "%userprofile%\desktop\responses.txt"
----------------------------

This will generate a text file that we can parse. The text file should look like this:

----------------------------
Trentent
OFFICE-y
----------------------------

We've now recorded some essential information to store for later when the time is required to utilize those responses.

To parse the file we can use tools such as find.exe the command FOR or IF.

Examples:
cd /d "%userprofile%\desktop"
for /f "tokens=*" %A IN (responses.txt) DO ECHO %A

This will bring two responses:
ECHO Trentent
ECHO OFFICE y

If we parse the file for known static "headers" (such as OFFICE) we can set variables for the stored responses.

FOR /F "TOKENS=* DELIMS= EOL=" %A IN ('findstr.exe /I "OFFICE" "%userprofile%\desktop\responses.txt"') DO SET OFFICE=%A

Now we can compare that value to determine if Office should be installed:
if /i '%OFFICE%' == 'OFFICE-y' (
ECHO Found Office
) ELSE (
ECHO Office NOT found
)

So if Office is found we can install it via a silent install command line.

So this lesson taught us to store reponses to be retrieved later. Stored responses can happen at any time -- when a user configures a system off a website, off a spreadsheet. These responses need to be stored in a known location such as a file share, in a database or downloaded off a webpage (wget.exe).

Monday, July 31, 2006

Working oneself out of a job

While working at Voodoo I've befriended an extremely bright individual, Trevor K. I dont' believe he has a blog but he is an extermely interesting person with the way he is able to describe situations. He puts into words a very simple explanation of a complex idea. One of his ideas that he has told me I've put into a personal mission of mine:

To work myself out of my current job.

Now, it may sound crazy but if I can do that, I'll must have done something amazing. Staples takes this concept and runs with it a little bit with their easy button concept. If you could develop your job into something so easy to do that all you had to do was push a button, wouldn't that be incredible. Now, offer that up to companies and see what they'll say. I'm sure they'd jump at the chance to take on someone with such a vision. Truly, I'm blessed to have such a visionary friend :)

Anyways, this takes me to my current post and my current topic of discussion. At Voodoo I developed a software and testing system that would completely software a machine based on the SKU's you ordered and then run a whole suite of applications and games to test the machines. It did this all based on your order number. All the technician had to do was type the number in and he was done. As a customer you could change your order and software mix right up to the day of testing and the technician didn't have to worry about double or triple checking each and every order to ensure it was correct, the system did it for you. Even better was ensuring each machine was softwared the same way excluding the variations between orders. After softwaring all scores and hardware were recorded with future plans to give the sales people that information to better make a sale.

Anyways, I've now moved on from Voodoo but am bringing my skills with me to help push for a flexible automated system of deployment in a corporate environment. My ideal system of deployment would be as such:

1. Client orders a system
2. System is ordered
3. System arrives, plug system into network
4. System is softwared automatically with the clients choices

At Voodoo I got very close to accomplishing this before I left. At Haworth it is an interesting challenge to get Haworth up to and hopefully surpass this.

So, lets look at some methods of softwaring (which, BTW is NOT a word as I learned very rudely one day) systems.

Starting from the very beginning is the plain jane off a CD. It's very slow and time consuming having to manually enter and install each piece of software, but it's EXTERMELY flexible.

There are ways of speeding it up, though that usually takes away flexibility. Going along with it for now, some low-hanging fruit is to automate the entry of common data. In Windows this is most easily done by using unattend.txt files or sysprep.inf files which contain answers to those annoying dialog boxes. So that's low-hanging fruit number one. The other is to automate duplicated procedures. This is having to install the same application over and over and over again. In Windows you can automate this process with silent installs. Differing installers have different ways of automating (or silencing) installs. Some have no way of being silent at all! Those that don't have a way of being automated require tools such as AutoIt.

So what do we have thus far? A very static way of doing installations. Flexibilty is a premium (if lean has taught me anything) and should be strived for as much as possible. There will always be information that will be the same across systems, but at the same time there will almost always be one thing that is different. So the best method is a mix of the two.

How can we mix the two? Well, we should start with some scenarios to help illustrate some pretty basic but creative ways of resolving this issue.

Corporation Fubar has two lines of desktop and a line of laptops they use in their organization. The desktops are completely different, ones an AMD with NVidia chipset and graphics while the other is an Intel with an Intel chipset and ATI graphics. The laptop is a basic intel system that requires special software.

Some corporations will use 3 base images for each of the three systems (very static) and update them as different hardware and software come in. Eventually, problems arise because one version gets of sync, a alot of effort is required to maintain them or different hardware requires even more images (say, the Intel desktop now comes with an Nvidia chipset and graphics).

What can you do? You could restrict employees to only use certain computers and start taking away their choices (but flexibility is a good thing right?) or we can come up with an IT solution that will give them their choice and make life equally easy (or dare I say easier) for us.

More for tomorrow, it's bed time right now ;)