Saturday, August 28, 2010

Stop Saying "America is Number 1"! It's Killing Us!

I'm so sick of everyone walking around saying "America is Number One!" "We're number 1" "this is the BEST country on Earth".  Not that I don't love it.  I do.  I love this country.

BUT.

When all our kids hear is that they're the best; they're number one, it means they don't need to try harder.  They don't need to do better.  They're already at the top.

We're not.

By any measure America has fallen behind other countries in education, health care, safety and security, shit, even Internet service.  We are only number one in all the wrong places like obesity, Diabetes, Crime and deaths from car accidents.  You are statistically more likely to contract a deadly infection in a U.S. hospital than to die from a highway car accident.  That's a solid, indisputable fact.  Look it up yourself.

In our grandparents youth, they did NOT go around saying that America was number one.  I've spoken to more elderly folks than I will ever be able to count.  They all say the same thing: They were always told they were not the best and to try harder.  They were told to work hard, study hard, innovate, in order to make America better.  The best.  That's how they accomplished so many incredible things like the space program, Hoover Dam, the interstate highway systems, sky scrapers, aircraft, ships, trains and submarines.  They didn't get motivated to think up those things by patting themselves on the back and saying "We're already the best.  Why try harder?"  That's just stupid.

So stop.  Think about what we are telling our kids.  Tell them we are NOT number 1.  We need to try harder to get back to the top.  And even when we do get back there, don't rest on that.  Keep trying.

Thursday, August 26, 2010

Part 2–Contractual Mumbo-Jumbo

If you bothered to read "Part 1" of this, then I can go ahead and say that this article is "Part 2".  Amazing, isn't it?  No.  But here goes.

NOTE: Although this article, and the other parts to it, are focused on web development projects, most of this applies to all aspects of technical services.  Take from it what you like, ignore the rest.

So you've spent many a late night building this dream of yours: a web site.  You've got your notes, sketches, templates, facts and figures, budget plans, timelines, and maybe even drawn up a business plan (or business case, etc.).  Maybe you've built a prototype or two in WordPress, Ning, SquareSpace or KickApps, and some of them do things the way you like, some do not.  Maybe one of them is 95 percent of what you want, but you can't figure out the last 5 percent.  No problem.

Now you're ready to meet with a web developer (or five or six).  If you feel that your idea and your plans are sensitive enough to protect from someone else stealing them, you probably should consider getting some basic protection in place.  By that, I mean legal matters.  This doesn't have to cost you anything except a little time.  If you have a friend who is an attorney, by all means ask them for advice.  If you're not fortunate (or unfortunate) enough to know an attorney, fear not, there are free options available.

Non-Disclosure Agreements

A Non-Disclosure Agreement, or "NDA", is a document that states that all parties (legal term for all persons who agree to the document by signing it) must abide by the terms it provides.  Those terms are usually focused around limiting what the involved parties can say about the project, or certain aspects related to it, to other people.  There may be penalties stated for breaking the terms. There may be time limits and other special conditions.  They can be vague and general, or particular and specialized.  The terms can be tailored to suit your needs, and the concerns of all others involved.

Regardless, the purpose of the NDA is to prevent people from blabbering, stealing, sharing your sensitive ideas and planning.  They often go both ways as well.  In many cases, the NDA will also protect the other party against you telling other potential bidders about how they estimate projects, or what resources they can leverage, and so on.  It protects ideas, capabilities, goals, and material works as well.  There are plenty of free NDA templates available on the Internet for you to download and modify to suit your needs.  You can also consult an attorney, which is usually a better option if you can afford it.

Before you sit down to discuss your ideas with developers, even for preliminary estimates, don't forget to decide whether an NDA is worth including.  Have them sign it before you discuss your project.  They may want some time to review it before signing it, which is always a good idea.  The goal is to protect your idea.  But make sure you really need it before you spend a lot of time on it.

TIP: Search the web for "non disclosure agreement template" for links to sites with free and low-cost templates to get started with.

Statement of Work

A Statement of Work, or "SOW" is a shopping list of what the developer will provide to you as part of your agreement.  It should include an itemized list of each and every task, key dates or time frames, milestone terms, materials to be delivered (source and/or final), and so on.  They should be detailed.

Don't just say "develop customer registration page".  The item should either describe what that page will look like, what it will do (functionally), and even refer to figures (sketches) or screen shots.  Describe workflows as well.  Write down the workflow process for things like registrations, subscriptions to mailing lists, unsubscribing, opting out, privacy agreements, and so on.   A good web developer can help you work this out, but you should understand it fully so you don't feel confused and frustrated later on.

Most arguments and disagreements I've seen were born out of vaguely worded SOW's.  It's amazing that some customers actually get frustrated when I ask questions to help nail down the details.  They assume that by discussing and agreeing "now" will be understood the same context six months later. "I thought you said…" or "I thought that meant…" are common phrases that indicate someone is confused and upset.  They feel let down.  They feel cheated.  That's not good for business.

Nail down everything early on.  Shapes.  Colors.  Fonts.  Pages.  Graphics.  Workflows.  Titles and sub-titles.  Table borders.  Margins.  Footers.  Get the specifics and put them into the SOW.

Here's how I look at a SOW: Think of it as though you were asking someone for instructions on how to build the site, and then you were going to hand it to a complete stranger with no knowledge about the project beforehand.  Will the SOW have enough detail to guide them to build it properly?

TIP: If the developer doesn't insist on specifics, or gets irritated by your insistence, walk way and find another developer.

Service Agreement

A Service Agreement is simply another name for a contract.  It's a written agreement that states who is doing what for whom.  It also states conditions, limitations, liabilities, responsibilities, exclusions, warranties, assumptions and expectations, important dates, deliverable items, ownership issues, copyright and trademark issues, legal jurisdiction, arbitration terms, invoicing and payments and so on.  Lot's of legal mumbo-jumbo, but it's good.  Yes, it is GOOD.  It protects YOU.  It protects THEM also.

While there are plenty of free contract templates available on the Internet and at retail stores (yes, they too have them for sale), this is one piece of the puzzle that I always recommend getting from a qualified attorney.  They shouldn't charge a lot for this if they're reasonable.  If you know an attorney, ask them what their fees are for either drawing up an agreement or reviewing an agreement you draft on your own.  Make sure they are familiar with service agreements involving consulting or technical services.  An attorney that only works with building contractors or retail contracts is not a good choice unless you can't find anyone else.

This is part one of the Agreement preparation.  Next…

Next, you will give it to the developer/consultant for them to review.  This is still considered a draft at this point.  They will likely want to take to their attorney to have it reviewed and they may request some modifications as well.  That's normal.  It's why we have attorneys.  They look things over and catch the loopholes we don't see, and plug them to protect us.  It's a good thing.

A reputable web developer will often have a prepared agreement from previous projects which has been reviewed many times and should be fairly good.  Always ask how many times that same agreement has been used in the past.  The more the better.  But even so, have it reviewed by your attorney to make sure it fits YOUR needs as well.

TIP: Consult an Attorney when developing a Service Agreement.  If the developer provides the Agreement, have it reviewed before signing it.

Invoicing

Your Service Agreement should include instructions on how and when invoices will be submitted, how they will be paid and how long it should take to process them.  It should also describe how to resolve discrepancies between delivered services/materials and invoiced claims.  There are two kinds of invoices in my book: Intermediate and Final.

An Intermediate Invoice is one that is submitted for partial delivery of items requested on the SOW.  There may be multiple such invoices before the project is completed.

A Final Invoice is just that: Final.  Some projects will only require a final invoice.  Some will involve intermediate invoices. Some will involve both.  It typically varies by how large, and complex the project is.  It can also vary by how the customer handles invoicing (that would be you, in this case).

A Final Invoice can just state something simple like "services and deliverables as requested by SOW ___" and an associated amount requested for payment.

An Intermediate Invoice should always be more detailed.  It should describe EXACTLY what tasks were performed.  It can break them apart with sub-totalled amounts, or just itemize the tasks and provide a total amount.  That is something you should discuss with the developer AHEAD of beginning work on the project.

TIP: Ask for a sample invoice so you don't get caught by surprise.

Summary

I hope this helps.  It may seem scarry, but it's really not.  These are important aspects of getting involved in any project that requires hiring someone else to do work for you.  If the work involves something sensitive or precious to you, it's worth protecting.  It's worth protecting at the beginning, in the middle and at the end as well.  Don't rush through it, and don't let anyone rush you either.

So You Want to Hire a Web Developer?

I've been doing web development work for quite a few years and have compiled a list of the top things customers should do BEFORE they go looking for a web developer.  I mean BEFORE. As in BEFORE you even talk to one of them.  BEFORE you email or IM or strike up conversation at a party with one of them.  This is PART 1 of more to come.

Things to Do:

  1. Do Your Homework
  2. Decide What Exactly you Want Your Web Site to Do
  3. Determine How Much You Are Willing to Spend
  4. Determine How Much Time You Can and WILL Devote to Running the Site
  5. What is the Business Plan?

Things to Avoid Until Later in the Planning:

  1. Search Engine Bullshit
  2. Ads and Advertisement Sales
  3. Selling Stuff and Shopping Carts

Do Your Homework

What other web sites will you be competing with?  Don't you DARE say "None!  I have a unique idea!"  Bullshit!  There are no more unique ideas on the Internet.  Innovation is dead.  You have to find a niche and exploit it.  Even if it's very close to someone else's niche, figure out (exactly) how and what you can do different and (more importantly) BETTER.

Decide What Exactly you Want Your Web Site to Do

If you can't describe what your site will do in one short sentence, you have no direction or idea what you're doing.  Narrow it down.  Focus.  "I'm going to sell stuff" is a start.  Sell what?  To whom?  Where?  How?  Do you have the means to handle packing, shipping, order tracking, returns and customer support?  "I'm going to start a ___ community."  For whom?  Why?  Why would they drop the other sites to use yours?  You have to ask the hard questions up front to avoid dumping an enormous amount of money and time into a bad idea.

Determine How Much You Are Willing to Spend

If you can't invest more than a few hundred bucks in this idea, it's probably going to have to take the low road for phase 1.  Maybe rely on a canned, do-it-yourself path like WordPress, KickApps, Ning or whatever.  Whatever you do, do not just run out and buy a domain and hosting plan before you know what you're getting into.  It may end up bleeding you dry and you won't have enough left over to hire someone to help you dig your way out (and up).

Determine How Much Time You Can and WILL Devote to Running the Site

Almost everyone I sit down with to discuss helping them bring their ideas to life overlooks this key aspect.  I really don't understand why this is.  Standing up a web site is the START of the dream, not the end of it.  To me, this is like practicing for years to get drafted into the major leagues, only to get up for the first at-bat and then say "you mean I have to actually hit a ball now?!" (yes.  you do.)

Ask any person that owns their own business how much time they devote to it, especially during the first year.  They will almost always tell you 24x7.  Making a web site work is no different.  You can't casually throw it out there and expect it to draw in tons of followers.  If you have brand recognition already, then maybe you can.  But if you're starting from square one, you will need to make this project (your dream web site) priority #1 for at least a few months.  If after six months of serious effort and labor invested into this you don't see results, re-evaluate and adjust.

So, Now What? : Step 2 / Compiling Your Ideas

If you've already done all this homework and have your idea honed and you're still pumped and excited, there's still more planning and preparation to do.  This will save you a BIG ASS amount of wasted time and money hashing things out with a developer.

Sketch Out Your Ideas – Get a pad of graph paper (yes, you remember that stuff from Geometry class, don't you?).  Use a pencil and sketch out the rough layout of your imaginary web site home page.  Figure out where the navigation links will go.  Horizontal?  Vertical?  Static or dynamic?  Top or Bottom? Left or Right?  Somewhere unusual or diagonal?  Flash or HTML5 animation?  Keep in mind your budget limits.  The more fancy your animation and graphic, the more time and cost.  It will grow fast.

Suggestion: Keep it simple for the first phase.  Don't get mired down in animation crap.  Focus on making the idea work.  If the idea is selling a product or a service, and you waste all your time and money on dynamic whiz-bang menu graphics, you will almost certainly fuck up the main goal of your site because you're getting distracted.  Build the function first.  Then make it pretty.

Do users have to sign up?  Do you need to protect privacy?  Have you checked on the legal issues?  Will there be any minors using your site?  Just adults?  Will you need to support multiple languages?  Will you need to sell something in multiple currencies?  If there's a discussion forum, who will moderate the comments and keep the kids playing nice in the chat groups?  If there's a blog, who will be posting to it and how often?  A blog that gets updated once a year gets ignored.

After you scratch together all these ideas and concerns, stop and ask the questions again:  Why is this different?  What makes it different?  Why will this work better than other sites?  Who are my biggest competitors?  What are they doing?

Step 3 / Finding The Right Tools

So, all that's done and you have a pile of sketches and clips and prints, and you have notes and you know what you're aiming for.  The next step is finding a web developer.

Stop.

Do you really need one?  Did you really look at WordPress?  Did you check out SquareSpace, KickApps and Ning?  If not, do it now.  And you better take at least a full day (if not several) to really dig into them and use their free trial services to feel them out.

If WordPress is what you like, now you can focus your search on a web developer that has experience with customizing WordPress sites and plug-ins.  Same goes for KickApps, SquareSpace, Ning or whatever.  The main point here is that you may not need to build a web site completely from scratch.  If you have zero experience building one that way, it might be best to consider one of these other options instead.

But if you decide you really need to build your site from scratch, or maybe you have someone that knows how to build sites from scratch, you still need to keep your ideas focused and guided.  Nail everything down as much as you can early on.  The more you change things during the building phase, the more delays you will cause, which equates to more cost and frustration.  You may think it's great to change the shapes from squares to ovals, or the colors from purples to blues, or change the text fonts and sizes, but the developer is going to run out of patience eventually.  Remember that this is YOUR dream.  For the developer it's a project.  A job.

Summary

I have no intention of shooting down your dreams of building a wonderful web site.  But so many people come to me without having thought through their ideas.  If you can't hone and optimize your ideas, how can anyone else?  Especially a complete stranger.  You need to do some homework and piece your idea together.  You will amass a pile of crumpled paper and break some pencils.  You will fill folders with scratched ideas drawn up in Microsoft PowerPoint, Paint, PhotoShop, Visio, and just about any application you doodle with.  You will give up and start over.  Again and again.  But if you have a good idea and it survives your own research and planning, chances are it's worth pursuing.  But don't sit down with a web developer until you know what you want.  It will save you a lot of frustration and keep your costs and expectations reasonable.

Wednesday, August 25, 2010

Skinning Cats the Nerd Way

Today I got a walk-up request: "We need to put a unique INI file on 500 machines and then invoke a client-side utility to import the INI into a client-side database which is part of a client-side application that uses that configuration data to establish secure connections to a remote server.  The clients are running inside Microsoft MED-V.  We have a spreadsheet with the unique ID-pairs for each of the 500 computers, but there's no names.  We need to fetch the names from AD and populate the spreadsheet to match them up and then use that to generate the INI files."

Piece of cake.  Um… ok…

  1. Add a column to the spreadsheet for the computer names
  2. Run a query to collect the computer names from a specific OU in our AD environment and push the names into the column in the spreadsheet.  Save the spreadsheet (it doesn't change ever again after this point, except to add future names… maybe).
  3. Obtain a template of the INI format.  Replace the unique values with sentinel strings (e.g. "PID1" and "PID2", etc.)
  4. Read the INI template into memory
  5. Read the spreadsheet rows, and for each row, create a copy of the INI template cache by substituting the sentinel values with actual values.  Save the copy to a unique INI file in a designated folder.
  6. Run a PSEXEC (Sysinternals) remote process to invoke the client-side .exe utility to import the INI data from a specific INI file from the shared folder across the network.

Questions: 

  1. How many scripts will it (did it) take to accomplish this?
  2. How long will it (did it) take to write it / them?

Answers:

  1. Whatever works for you.  For me it was three scripts:  One to query AD and populate the spreadsheet column.  Another to read the spreadsheet and generate the INI files.  And another to iterate through each of the INI file names and execute PsExec with the appropriate command syntax for the utility and the unique INI file and path.
  2. Who cares.  I can (and will) say that if it takes anyone more than 2 hours they're taking too long.

Tid-bits:  MED-V runs a virtual client which is joined to the domain as its own unique name, so you can access it like any other computer provided you have sufficient permissions and the access gateways are opened up (firewalls, services, etc.)  So the PsExec script is aimed at the MED-V clients, not the physical clients.

Saturday, August 21, 2010

Why Americans Can't Drive for Shit and What Can Be Done to Fix It


The real reason Americans can't drive is that they hold NO value for a driver's license.  They are way to easy and cheap to obtain, so they have no value.  It takes too many violations to suspend or revoke one also.  How many times do we all hear the news report about a drunk driver killing someone and then they tell us the driver had a history of drunk driving?

How this dilemna can be fixed:
  • Make a driver's license more expensive to obtain.  Maybe $500
  • Make the driver's test much more difficult and lengthy.
  • Make it a moving violation to toss trash from any vehicle (moving or not)
  • Issue them on a one year probationary period.  ANY moving violation revokes them.
  • Allow ten (10) non-moving and (3) moving violations per driver lifetime.  Revoke the license when either limit is reached
This will absolutely NEVER happen.  Why?  Because car manufacturers, car dealers, gas stations, oil companies, tire companies, auto parts vendors, would all stand to lose money.  It's in their interest to keep the roads filled with drivers, no matter how badly they operate deadly machinery.

Thursday, August 19, 2010

I was Finally Reimbursed for my College Tuition

It's taken almost exactly ten (10) years to happen, but my former employer finally mailed me a check to cover the tuition and book costs they negelected to pay in full when I went to college from 1996 to 1999.  Based on my approximations, with an average tuition of $1,100.00 per semester (full time with labs), and $300-$400 in books, and using the grade scale they used back then where an A earned 100%, B earned 90% and C earned 80%, I averaged an A- (or GPA 3.46), and having skipped one Summer (1998), that would come to somewhere around 7 full semesters and 2 half-time Summer semesters (at roughly $600 each).  That would equate roughly to (7 x ($1,100+300)) + (2 x ($600 + $150)) or around $11,300 for the whole joy ride.  In actuality, they paid me roughly $600 to $800 per full semester, citing a justification that most of my CS/IS degree "required" courses weren't related to my job in IT.

Here's my check…

IMG_8981_clean

Ok, so it's not really for tuition reimbursement.  It is actually not related to anything prior to 2008 at all.  It's just the balance of adjusted withholdings for insurance benefits from my final paycheck when I left the company this past July.  Oh well.  I'm going to pretend it's tuitition reimbursement.

Monday, August 16, 2010

An Important Note about the SCCM Scripts

The scripts I posted recently for uninstalling AutoCAD LT 2011 and AutoCAD Civil 3D 2011 are for 32-bit Windows operating systems.  If you are working with 64-bit clients, you may need to add more code to check for 32-bit application registry keys under HKLM\SOFTWARE\Wow6432node, rather than just looking under HKLM\SOFTWARE.  I'm not going to waste my breath explaining why this is, just trust me: it is what it is.  And boy do I hate that overused phrase.

Here is an example of what I'm talking about…

Const strComputer = "."
Const HKLM = &H80000002

Set oShell = CreateObject("Wscript.Shell")

If RegKeyExists("HKLM\Software\Autodesk\DWF Viewer\") Then
wscript.echo "found!"
Else
wscript.echo "not found"
End If

If RegKeyExists("HKLM\Software\Autodesk\AutoCAD\") Then
wscript.echo "found!"
Else
wscript.echo "not found"
End If

If RegKeyExists64("Software\Autodesk", "AutoCAD") Then
wscript.echo "found!"
Else
wscript.echo "not found"
End If

Function RegKeyExists(key)
Dim bKey
On Error Resume Next
bKey = oShell.RegRead(key)
If err.Number = 0 Then
RegKeyExists = True
End If
End Function


Function RegKeyExists64(key, valueName)
Dim objRegistry, strValue
On Error Resume Next
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
objRegistry.GetStringValue HKLM, key, valueName, strValue
If err.Number = 0 Then
RegKeyExists64 = True
End If
End Function

Uninstalling AutoCAD Civil 3D 2011 with SCCM 2007

As promised, here is part 2 of my previous post about removing AutoCAD 2011 products using System Center Configuration Manager (SCCM).  I use a script to herd all the 3-legged cats together and remove them at once, silently.  Kind of like stealth kitty extraction.  Or something like that.

BEGIN VBSCRIPT…

'****************************************************************
' Filename..: uninstall_2011_civil3d.vbs
' Author....: David M. Stein
' Date......: 08/16/2010
' Purpose...: uninstall autocad civil 3d 2011
' SQL.......: N/A
'****************************************************************
Option Explicit

wscript.echo "info: initialized " & Now
wscript.echo "info: script executed from " & wscript.ScriptFullName

Dim oShell, oFSO, progfiles, sysdrive, counter : counter = 0

Set oShell = CreateObject("Wscript.Shell")
Set oFSO = CreateObject("Scripting.FileSystemObject")

progfiles = oShell.ExpandEnvironmentStrings("%programfiles%")
sysdrive = oShell.ExpandEnvironmentStrings("%systemdrive%")

wscript.echo "info: product installation was found."

CleanApp "DirectX 9.0c for Civil 3D 2011", "{0B8F69E3-5983-4B2B-B464-5D833C76773D}"

CleanApp "Autodesk Material Library 2011", "{9DEABCB6-B759-4D52-92F8-51B34A2B4D40}"

CleanApp "Autodesk Material Library 2011 Base Image library", "{CD1E078C-A6B9-47DA-B035-6365C85C7832}"

CleanApp "AutoCAD Civil 3D 2011", "{5783F2D7-9000-0409-0002-0060B0CE6BBA}"

CleanApp "AutoCAD Civil 3D 2011 Language Pack - English", "{5783F2D7-9000-0409-1002-0060B0CE6BBA}"

CleanApp "Autodesk Design Review 2011", "{8D20B4D7-3422-4099-9332-39F27E617A6F}"

CleanApp "FARO LS 1.1.406.58", "{951B0F30-9F1A-4BF6-B3DA-99EB0E917B1C}"

If counter > 0 Then
CleanFolder progfiles & "\Autodesk\AutoCAD Civil 3D 2011"
CleanFolder progfiles & "\Autodesk\LandXML Reporting 8"
CleanFolder sysdrive & "\Civil 3D Project Templates"
CleanFolder sysdrive & "\Civil 3D Projects"
End If

wscript.echo "info: " & counter & " applications removed"
wscript.echo "info: completed at " & Now

'----------------------------------------------------------------
' function: check if reg key exists under Uninstall tree
'----------------------------------------------------------------

Function IsInstalled(keyname)
Dim basekey
basekey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
If RegKeyExists(basekey & keyname & "\") Then
IsInstalled = True
End If
End Function

'----------------------------------------------------------------
' function: return True if registry key exists
' EXAMPLE: If RegKeyExists("HKLM\Sofwtare\ACME\TestKey\Value1") Then
'----------------------------------------------------------------

Function RegKeyExists(key)
Dim bKey
On Error Resume Next
bKey = oShell.RegRead(key)
If err.Number = 0 Then
RegKeyExists = True
End If
End Function

'----------------------------------------------------------------
' function: run MSIEXEC to uninstall a GUID-based app
'----------------------------------------------------------------

Sub Uninstall(key)
oShell.Run "msiexec.exe /x " & key & " /qn", 7, True
End Sub

'----------------------------------------------------------------
' function: macro to check for app and remove it
'----------------------------------------------------------------

Sub CleanApp(name, keyname)
wscript.echo "info: searching for " & name
If IsInstalled(keyname) Then
wscript.echo "info: removing " & name
Uninstall keyname
counter = counter + 1
Else
wscript.echo "info: " & name & " is not installed"
End If
End Sub

'----------------------------------------------------------------
' function:
'----------------------------------------------------------------

Sub CleanFolder(path)
Dim retval
If oFSO.FolderExists(path) Then
On Error Resume Next
retval = oFSO.DeleteFolder(path, True)
If err.Number = 0 Then
wscript.echo "info: folder deleted = " & path
Else
wscript.echo "warn: folder not deleted = " & path
End If
Else
wscript.echo "warn: folder not found = " & path
End If
End Sub

'----------------------------------------------------------------
' function:
'----------------------------------------------------------------

Function ScriptPath()
ScriptPath = Replace(wscript.ScriptFullName, _
"\" & wscript.ScriptName, "")
End Function

Uninstalling AutoCAD LT 2011 with SCCM 2007

Autodesk makes a pretty bold effort to get their products blasted onto desktops in large quantities.  It's not a perfect effort, and requires some hand-holding and customization here and there, but it's bold.  However, the uninstall effort is non-existent.  After all, why would they want to help you remove their products?  You can do that via Add or Remove Programs, right?  Yeah.  Sure.  On 5,000 computers by tomorrow.  Good luck with that.

Fear not.  They do leave enough crumbs behind to allow you to whip out your scripting dog and follow the scent back home to a clean desktop configuration.  Ok, cleanER more than clean.  Here's a script that you can call from SCCM to remove AutoCAD LT 2011.  I prefer to wrap the call inside a .BAT or .CMD script so I can pipe the echo statements to a client-side log file for troubleshooting.  But you can do whatever you like.

To wrap inside a .BAT/.CMD script, try this…

cscript <path>\uninstall_2011_acadlt.vbs >%TMP%\acadlt2011_uninstall.log


(where <path> is the UNC path to where you share the script file)



BEGIN VBSCRIPT…



'****************************************************************
' Filename..: uninstall_2011_acadlt.vbs
' Author....: David M. Stein
' Date......: 08/16/2010
' Purpose...: uninstall autocad lt 2011
' SQL.......: N/A
'****************************************************************
Option Explicit

wscript.echo "info: initialized " & Now
wscript.echo "info: script executed from " & wscript.ScriptFullName

Dim oShell, oFSO, progfiles, sysdrive, counter : counter = 0

Set oShell = CreateObject("Wscript.Shell")
Set oFSO = CreateObject("Scripting.FileSystemObject")

progfiles = oShell.ExpandEnvironmentStrings("%programfiles%")
sysdrive = oShell.ExpandEnvironmentStrings("%systemdrive%")

wscript.echo "info: product installation was found."

CleanApp "Autodesk Material Library 2011", "{9DEABCB6-B759-4D52-92F8-51B34A2B4D40}"

CleanApp "AutoCAD LT 2011", "{5783F2D7-9009-0409-0002-0060B0CE6BBA}"

CleanApp "AutoCAD LT 2011 Language Pack - English", "{5783F2D7-9009-0409-1002-0060B0CE6BBA}"

CleanApp "Autodesk Design Review 2011", "{8D20B4D7-3422-4099-9332-39F27E617A6F}"

If counter > 0 Then
CleanFolder progfiles & "\Autodesk\AutoCAD LT 2011"
Else
wscript.echo "warn: no applications were removed"
End If

wscript.echo "info: " & counter & " applications removed"
wscript.echo "info: completed at " & Now

'----------------------------------------------------------------
' function: check if reg key exists under Uninstall tree
'----------------------------------------------------------------

Function IsInstalled(keyname)
Dim basekey
basekey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
If RegKeyExists(basekey & keyname & "\") Then
IsInstalled = True
End If
End Function

'----------------------------------------------------------------
' function: return True if registry key exists
' EXAMPLE: If RegKeyExists("HKLM\Sofwtare\ACME\TestKey\Value1") Then
'----------------------------------------------------------------

Function RegKeyExists(key)
Dim bKey
On Error Resume Next
bKey = oShell.RegRead(key)
If err.Number = 0 Then
RegKeyExists = True
End If
End Function

'----------------------------------------------------------------
' function: run MSIEXEC to uninstall a GUID-based app
'----------------------------------------------------------------

Sub Uninstall(key)
oShell.Run "msiexec.exe /x " & key & " /qn", 7, True
End Sub

'----------------------------------------------------------------
' function: macro to check for app and remove it
'----------------------------------------------------------------

Sub CleanApp(name, keyname)
wscript.echo "info: searching for " & name
If IsInstalled(keyname) Then
wscript.echo "info: removing " & name
Uninstall keyname
counter = counter + 1
Else
wscript.echo "info: " & name & " is not installed"
End If
End Sub

'----------------------------------------------------------------
' function:
'----------------------------------------------------------------

Sub CleanFolder(path)
Dim retval
If oFSO.FolderExists(path) Then
On Error Resume Next
retval = oFSO.DeleteFolder(path, True)
If err.Number = 0 Then
wscript.echo "info: folder deleted = " & path
Else
wscript.echo "warn: folder not deleted = " & path
End If
Else
wscript.echo "warn: folder not found = " & path
End If
End Sub

'----------------------------------------------------------------
' function:
'----------------------------------------------------------------

Function ScriptPath()
ScriptPath = Replace(wscript.ScriptFullName, _
"\" & wscript.ScriptName, "")
End Function


I'll post another version of this for AutoCAD Civil 3D 2011 sometime soon.

Saturday, August 14, 2010

Packaging & Deployment Autodesk 2011 Products with System Center Configuration Manager 2007

That may be one of the longest titles I've used yet.  Phew!  My fingers hurt already.

So, my current job has me packaging (actually, more correctly: re-packaging) software applications for mass deployment in a WAN environment.  This time around I'm using Microsoft System Center Configuration Manager 2007 (aka "SCCM" or some prefer "ConfigMgr", whatever).  It's a real mixed bag of experiences and results with all the various MSI and non-MSI applications we deploy.  Messy, painful stuff, but it has to be done.

Because there is a known issue with pushing the AdminImage bundle of DirectX 9.0c within the deployment installer with SCCM, you have to package (or run) the DirectX bundle separately and ahead of the actual product installation.  If you don’t, the retarded result will be it fails but returns a "successful" code to SCCM and it appears to have installed correctly, when it didn’t.  Even the client and network logs won’t clearly state that a missing DirectX install caused it to fail and will look as if it worked just fine.  The only physical trace of the failure will be in the Windows Application event log.

In addition, if you don’t have Internet Explorer 7 or later installed on your Windows XP clients, it will abort the installation of Design Review 2011 without causing the entire package to fail.  So the package will still return a "successful" result to SCCM, even though only Civil 3D 2011 or AutoCAD 2011, etc. is actually installed.  So be careful to lay down IE7 or IE8 prior to deploying the full package if you intend to include Design Review 2011.

So, what about Direct X 9.0c?

The problem is many people are confused to death about how vendors use DirectX installers.  There is no "one" DirectX 9.0c.  It’s an API framework.  The vendors use it to develop their own custom bundles to get their applications to work with the DirectX layer on the client.  The proof is to look at the DirectX folder tree under different Autodesk AdminImage deployment shares and compare the contents.  No two will be identical.  For example, the contents under 3DS Max 2011 and AutoCAD Civil 3D 2011 are entirely different.  The only common pieces will be DXSETUP.EXE and a few DLL files.  The end result is that you need to run the appropriate DirectX 9.0c installation for each product.  You can’t run just one bundle for all products.  It won’t work.  It doesn’t matter how many DirectX 9.0c bundles you have already installed for whatever products are on the clients already, you have to install the one for the product it goes with.

For more wonderful sleepy-time reading on DirectX go to http://msdn.microsoft.com/en-us/library/ee416994(v=VS.85).aspx

I see so many admins deploying Inventor, Mechanical, and expect 3DS Max to install fine without also installing the DirectX that comes with 3DS Max (when they try to automate an unattended deployment, that is).  If you’re doing "manual" installations this is not an issue because the installation wizard walks through and takes care of whatever it needs along the way.  But when you push a silent installation through SCCM, it won’t push DirectX with it.  Doh!!

(Dear Autodesk: It would be nice if you could develop a universal DirectX bundle for all your products to share and make it a prepared MSI installation as well.  Thanks!)

Step 1 - Package or Prepare the DirectX bundle

I use Wise Package Studio and create a new MSI package for the installation.  I add the DirectX folder contents from the AdminImage\support\DirectX folder on the deployment share into the WINDOWS\TEMP folder in the package.  Then I go to the MSI Script tab and edit the "Execute Deferred" tab to insert an "Execute Program from Installation Files" action just above "InstallFinalize".  Configure it to execute the "DXSETUP.EXE" from the files collection in the package.  Set the arguments to "/SILENT".  On the Properties tab, set the In-Script option to "Deferred execution - System Context" and set Processing to "Synchronous, ignore exit code"
Save the package and compile it to a name like "Civil3D2011_DirectX9"
Now you should have an installer named "Civil3D2011_DirectX9.msi" that you can deploy silently using /qn or whatever you prefer.

Step 2 - Create the SCCM deployment for the DirectX Package

Prepare and Package, Program and Advertisement for the DirectX installer you created to target the computers which will get the Autodesk product it goes with (e.g. AutoCAD Civil 3D 2011).  You don't need to add any special command line parameters to this package since they are done inside the Wise package (e.g. "/SILENT") so you can deploy it silently using msiexec.exe /i <packagefile> /qn or whatever.  Advertise the package to your target collection and test with a few computers (direct membership is easiest here).

Step 3 - Create the SCCM deployment for the Autodesk Product

Prepare the Package, Program and Advertisement for the Autodesk product as outlined in their deployment documentation.  In most cases the program statement will execute the AdminImage "SETUP.EXE" using the /W /Q /I parameters followed by the .INI file for the deployment and the language parameter.  So if you created a deployment named "2011network" and your deployment share is on server "Server1" under a shared folder named "Apps\Autodesk" it might look like this…

\Server1\Apps\Autodesk\Civil3D2011\AdminImage\setup.exe /W /Q /I \Server1\Apps\Autodesk\Civil3D2011\AdminImage\2011network.ini /Lang en-US

Deploy to your test collection and fine-tune as necessary.  I always use "Whether or not a user is logged on" and "suppress program notifications" since we deploy unattended to everything.

IMPORTANT: Be sure to first make sure the DirectX package deploys successfully before you deploy the rest of it.  If you don't, the Autodesk deployment will fail but will still return "Successful" to SCCM.  The same is true for Design Review failing within the package because a client doesn't have IE7 yet.  It will still say everything deployed successfully.  This is boneheaded and seriously flawed, but it has been reported to Autodesk so time will tell how they handle this.

MORE: I have also asked Autodesk if they would consider developing a single, universal DirectX package for all of their products and provide it in MSI form so that it can deploy with their AdminImage bundles through tools like SCCM.  It would also reduce the stress packagers and admins already endure on a daily basis.

Step 4 – Drink

As if you need an excuse to drink. Go for it. You deserve it. Autodesk and SCCM have delivered you to the doorstep of insobriety so you might as well take advantage of the opportunity

Glass_of_beer_with_bottles_in_the_background[1]

Dear Mr. Prez-o-dent

Politically speaking, because I once read something with the word "politics" in it years ago, it seems like a very bad idea for a president to endorse a Mosque at ground zero for two reasons: it only helps polarize and anger an already divided constituency, and it doesn't help already-strained relations with Israel, one of our only real allies in the Middle East.  At best, I would think he should have stayed clear of the whole issue.  


But regardless, I say again: Is this the most important issue we have to face right now?  I mean, is the economy all patched up and looking good?  Are we safe from terrorism yet?  Are we driving electric cars and trucks yet and giving the middle finger to OPEC?  Are our kids graduating from school at pace or ahead of other countries?


All of this stupid concern over gay marriage, health care and bank bail-outs seems to give the message that all of the other issues are done.  There's nothing else more important, or even AS important to address?  Really?!


Don't get me wrong. I'm sure gay marriage and health care are important to a lot of people.  But when there's not enough jobs to keep us moving forward it seems like we're worrying about a split toenail when we have a gaping wound and losing blood.  Let's fix the BIG issues FIRST, and THEN move on to the lesser issues.  It seems we are letting the news media dictate what WE feel is top priority, rather than assessing the issues OURSELVES and making this determination.  Our priorities are upside down.

Wednesday, August 11, 2010

George Carlin – Cats and Dogs

Wise Packaging: Whooo boy, this is a doozy

Hang on to your tampons girls, this is going to be a rambling post, but I have a lot of constipated brain cells that need a detox flush, so here goes…

I'll spare you the usual blabber about how long I've been writing code and doing this and doing that, you can scan my mindless jabbering and figure that out on your own.  I will say that I first ran into Wise packaging when I was doing software development with Visual LISP on Autodesk (ahhh, the good ole ADN days, breath in….. ahhh….).  That was using the GUI to package "new" software for other people to install and suffer with while I ran away counting the money they paid for it.  Good times those 90's were.  If only they actually paid money for it.  I can dream can't I?

Then I went in other directions and ended up relearning Wise from the Scripting side.  I'm talking PURE scripting.  NO GUI.  That isn't as scarry or bad as most that only use the GUI would think.  It's actually much more flexible and understandable, once you get over the learning hump, and consume a few stiff drinks.

Now I'm back to the GUI, but in a very different way than before.  This time it's re-packaging apps (which I did with scripting, by the way) but this is using the full-blown suite, with the software manager database server and shared repositories, checking-in and all that jazz.

Here comes the fun part.  I needed to add some code to a repackaged application to check for some existing conditions before proceeding.  If the conditions are not met, the install exits.  This is constructed from essentially 3 steps.  Getting that simple 3-step list was a complete pain in the ass. 

Why?  Because Wise, then Altiris, and now Symantec have GIGANTIC GAPING-ASS HOLES IN THEIR DOCUMENTATION.  But that's not the worst part.  It gets better.  I jump into their support forums, which are (at least I thought) were intended for customers to request help from "peers" for things they can't seem to figure out on their own or from Google searches.  Well, I didn't realize that Symantec farms out the moderation to "experts" that don't necessarily work for them.  One in particular (no names) is a bit of a prick.  His standard response is "did you read the docs?  have you turned on verbose logging?" and so on.  Nevermind that the question was "can you point me to how to do ____?"

After a day of wasted time dealing with his fly-smacking antics, I searched through their site and low-and-behold I found an article dealing EXACTLY with what I needed.  Google didn't find it for some reason, but their own search did. 

Here's what I needed to do…

  1. Create a public property named "APP_INSTALLED" set to "FALSE"
  2. Create a System Search for the uninstall registry key (you know that one)
  3. Create a Launch Condition that checks if "APP_INSTALLED = "FALSE"" then terminate the installation

There's another semi-documented step that is crucial to making this work:  You have to shuffle the "AppSearch" action above the "LaunchConditions" action in the MSI Script editor on both the "User Interface" and "Execute Immediate" tabs.  This is murky stuff since some people say the way to do this is to go into the Property tables and assign the AppSearch action entry a lower value then the LaunchConditions in the InstallExecute and InstallUIExecute tables.  The default value for LaunchConditions is like 100 or 101 so you make AppSearch like 99 or whatever, but that didn't work for me.  The other method of shuffling the order in the MSI Script editor worked for me (tip: Press CTRL+UP or CTRL+DOWN to move rows around)

So, here's a tip for anyone just getting into this wonderful crack-smoking face-smacking hair-pulling world of software repackaging:  Read the docs.  Search Google. Search the Symantec How-To articles.  Search AppDeploy.com.  Search MyITForum.com  Just don't post a newbie question on the Symantec forums.  They will treat you like shit.  Save yourself the pain.

Friday, August 6, 2010

In Spite of Technology: These Things have NOT Improved

Things that have not improved at all, in spite of technological advances over the past 5 decades:

  1. Making toast
  2. Boiling water
  3. Brushing teeth
  4. Treating Jellyfish stings
  5. Mowing the lawn
  6. Bathing a dog
  7. Rush hour traffic
  8. Combating insects
  9. Changing car oil
  10. Dealing with "customer service"
  11. Painting the inside of a house yourself
  12. Roofing
  13. Patching holes in asphalt roads
  14. Wiping your ____
  15. Delivering the mail

Tuesday, August 3, 2010

Headaches: Windows Server 2008 R2 + WSUS + zzzzz

No sleep.  Been up beating my head against a wall but finally found some relief.

My lone WS08R2 domain controller/WSUS host was having issues.  It would go into perpetual "downloading updates" when doing either manual update check against MS-Updates, but the status always said 0%.  I could let it run for days and it wouldn't get beyond that.  So I ran across this article, and it helped.

Basically: Stop the BITS and Crypto services, then stop Update Service.  Then rename \Windows\catroot2 to catroot2.old and SoftwareUpdates to SoftwareUpdates.old.  Then restart the services and run an update check.  Ba-da-bing!  It worked!

However, I'm still having an issue with the Server Manager failing to display Roles or Features.  It tries to enumerate them and fails with a useless error.  The Windows Modules Installer service keeps stopping also for no apparent reason.   Still digging.  But I'm going to bed for now.  Screw this.

Sunday, August 1, 2010

The New Chargers, Challengers, Mustangs and Camaros

In a word: yawn

I'm sorry, but there's nothing amazing or impressive about them. They all look alike.  They scream "I am trying to be like every other guy with the same car".  Even the colors are too common.  I can't drive five miles without passing six red Mustangs, six orange Challengers, or six black Camaros.  Bo-ring!

I am 46 years old.  I can remember when people in America relished the idea of being different.  Being unique. Expressing individuality.  Those days are DEAD.  Every guy in his 20's has the same tired barbed wire tattoo.  The same hair cut.  The same piercings and gauging of the ears.  The same everything.  It's worn out!  Tatoos used to mean something.  They used to spark a tiny sense of danger and interest in those that saw them, because they were UN-common.  Now they simply mean the person had $300 and some time to spare.  Period.  The same is now true for cars.

In the 1970's and 1980's every neighborhood had at least two guys that would tear-down and rebuild muscle cars.  They'd put their own unique touch on it.  From the engine to the drive train, the interior and most definitely the paint job.  That is a vanishing art.  The new trend is buying it off the showroom floor.  Factory stamped "custom" crap that feeds an apetite like a plate of hot wings at Hooters.

I saw a Lotus Elise pass me in Town Center, Virginia Beach.  Not the most powerful or fastest car, but damn if it's not sexy looking.  Tangerine orange too.  Not utility truck orange like Dodge uses.  And no stupid-ass black "racing" stripe either.  Just a sweet looking car, and an un-common car at that.  And what really hit me was watching how even the most car-ignorant passers-by reacted to the sight of it by the curb.  Women in particular were just blown away.  I have NEVER seen reactions like that for even a mint '62 Corvette.