Friday, August 28, 2009

10 Things I Hate

1 - Sony / Apple / Adobe

They make shoddy crap with a pretty face on it and sell it for waaaaaay too much money.  They seem to get a pass from the media, their fans and most ignorant asswipes who don’t understand software development basics or the beginner aspects of installation packaging.  The only thing that annoys me more than these companies, is their shitty products.  The only that annoys me more than their shitty products, is their obnoxious ass-licking fans.  At least Microsoft fans know when to shut their mouth.

2 - Intolerance

I simply cannot tolerate intolerance.  Intolerant people should not be tolerated.

3 – NASCAR

A “sport” of watching cars go around a track over and over and the camera panning across the audience of rednecks, wiping Hardees grease from their chin, smoking a Marlboro and drinking a can of Coors.

4 - Democrats and Republicans

Party politics is for suckers.  People who cannot help but let their eyes follow moving shiney objects.  People who look for slight-of-hand tricks aren’t fooled by this game.

5 - Overzealous Vegans

So you don’t eat meat.  That’s nice.  Shut the fuck up.

6 - PETA and SPCA

Both talk a big game but neither do anything at all to help the planet or the well-being of animals.  They’ve become vehicles for sucking in donations and fees.

7 - SUVs

They’re big, ugly, smelly and driven by fucking morons who can’t operate them.  They can pretend to drive them as long as the sun is out and the roads are clear and dry. Once it rains or snows, forget it.  They look like pigs trying to dance.

8 - Bicyclists on the Road

I’m an avid bicyclist.  The roads were built for cars.  Period.

9 - Hidden Agendas

Anyone who can’t openly state their purpose cannot be trusted.  Ever.

10 – Idiots and Ignorance

America worships idiots.  Nature eats them.  End of story.  And: No, ignorant and naive are not the same thing.

Thursday, August 27, 2009

Enabling Windows 7 Remote Management via Group Policy

I’ve been searching for a comprehensive article/blog-post/kb, etc on this for a while but have only been able to find pieces of the overall solution I was looking for.  The challenge?

Enable remote management capabilities on Windows 7 clients within an Active Directory domain environment using Group Policy.

Which capabilities?

  1. Be able to PING clients
  2. Be able to connect to clients via Remote Desktop
  3. Be able to connect to clients via Computer Management
  4. Be able to connect to clients through Event Viewer, RegEdit, etc.

You may notice that my “solution” doesnt’ involve a great deal of security options.  That’s because I’m pretty comfortable with the boundary security on my network environment, which will not be described herein.  Suffice it to say that I am only interested in being able to enable and use these capabilities.  If you need increased security, you can configure additional options via Group Policy settings to suit your needs.

Computer Configuration \ Policies \ Administrative Templates

Network \ Network Connections \ Windows Firewall \ Domain Profile

  • Allow ICMP Exceptions:
    • ENABLED - Allow inbound echo request
  • Allow Inbound remote administration:
    • ENABLED: Enter asterisk (*) in IPv4 address box
  • Allow inbound Remote Desktop:
    • ENABLED: Enter asterisk (*) in IPv4 address box

Windows Components \ Remote Desktop Services \ Remote Desktop Session Host \ Connections:

  • Allow users to connect remotely using Remote Desktop services
    • ENABLED

Windows Components \ Windows Remote Management (WinRM) \ WinRM Service:

  • Allow automatic configuration of listeners
    • ENABLED: Enter asterisk (*) in IPv4 address box

If you need a nudge in the right direction for how to add these settings:

  1. Open Group Policy Management (aka “GPMC”)
  2. Expand Forest: <name> / Domains / <your-domain> / Group Policy Objects
  3. Right-click and select “New”
  4. Enter a name for the GPO (e.g. “Remote Management”) and click OK
  5. Right-click on the new GPO and select “Edit”
  6. Follow the guideline above to locate and enable the settings
  7. Right-click on the very top of the tree-view panel on the name of the GPO and select “Properties”
  8. Check the box “Disable User Configuration settings”
  9. Click “Yes” to accept the warning.
  10. Close the Group Policy Management Editor
  11. Right-click on the desired computer OU in the GPMC and select “Link an existing GPO” and select your new GPO.
  12. That’s it.

You can then either wait for the regular GPO refresh cycle to run (about 90 minutes on average, sometimes less) or go to a client and open a CMD console (remember to right-click and choose “Run as Administrator”) and at the command prompt, enter “GPUPDATE /FORCE” and press Enter.  You should be able to connect to that client from another client on your domain immediately after that.  If you still cannot, double-check your GPO settings and double-check where you linked the GPO (which OU) related to the computer account within AD.  You can (and should) use GPRESULT on the remote client to diagnose GPO issues.

Feedback is always welcome.  Enjoy!

Wednesday, August 26, 2009

10 Greatest Under-Rated Inventions of Mankind

1. Beer

I had to start with this one.  Where would we be today without beer?  Granted, a lot of kids would still be “here” without it.  But those of us lucky enough to still be able to drink it, it’s almost enough convince a die-hard Atheist after every gulp that there just might be a God after all.  Beer has had its hand in almost every single major event throughout human history.  Would Alexander have persevered across Europe, Asia and Africa totally sober?  No way.  Would Nicola Tesla have spent that much time in his dungeon lab without something to get a buzz (besides his experiments)?  Nope.  Sure, it’s probably helped get a few wars started, but think of the bright side: It gave the survivors something to do afterwards.  The most amazing aspect of beer is how it was simultaneously invented (or discovered) in so many cultures without having direct contact: Japan, Africa, Europe, South America, the Caucasus, the Mongolian Steppe, the Ganges River delta, and now even in your local 7-11 cooler.  Ben Franklin summed it up best: “Beer is proof that God loves us all.”

2. Air Conditioning

This is one of those things we’re happy to greet us when coming in from 90 degree heat, yet we almost never think to appreciate it on a more spiritual level.  When it breaks during a heat wave, you never stop being thankful for it after it’s repaired.  You kiss the hands and feet of the sweaty repair guys as they pack their tools.  You ask if they want to marry your daughter.  You start letting your butt crack show as a sign of homage to their mastery of the trade.

3. Plastic

I started to pick out individual plastic items until I realized that it was plastic itself that was the wunderkind of it all.  Just pause right now and scan your surroundings to identify everything that contains plastic.  Yes.  Pretty damn amazing.  And where would it be without all the imported oil we depend on to make those wonderful things?  Cars, Clothes, Electronics, Sports Gear, Medical supplies, Aircraft, even building construction.  Imagine picking up dog crap with leather gloves?  No way.  Plastic, throw-away gloves are mandated.  Same for changing disc brake pads and performing routine prostate exams.

4. Ice

I’ll bet you’ve never once stopped and said “Thank God for ice.”  If you have, you’re probably just weird anyway.  But regardless, now is the time to stop and be thankful for it.  Every time your kid got popped in the face with a baseball or kicked in the chest by soccer cleats, or jumped off the roof into an empty swimming pool… ice was there to make it all better.  Your warm beer.  Your fizzless soda.  Your warm shrimp cocktail.  Yes, it was always there making things right.  Yet we never stop to appreciate it.  Ice Ice baby.  Doh!  One guy ruins it all.  Damn him!

5. Microwave Ovens

Anyone age 40 or older should remember how long it used to take to heat up a “quick meal” on the stove.  It sucked ass.  Kids today bitch about 5 or 6 minutes being too long.  We just stare at them slackjawed in total disbelief, and they stare back with that “whatev” look in return.  The bain of pace makers for years, yet the life-saving mechanism for bachelors and single moms everywhere.  So many wrong things have been put into them only to never come back alive, but whatever.  Kids won’t be happy until we arrive at the Jetsons or old Star Trek meal generator devices.  But for now, be thankful for your trusty Microwave oven.

6. Coffee

More than beer, nothing has touched more historical textbook material than coffee.  Without coffee Sun Tsu couldn’t have found the Art in War.  Jackson Pollack would have passed out on his tricycle in the middle of a canvas. Nothing in the business world would have ever been accomplished. Nothing.  Even if you’re not a coffee drinker, someone above you most certainly is.  So whether you like it or not, it’s involved with your career, your company, and your future.  Whenever there’s a bidding war, it’s the guy that doesn’t drink coffee that gets dumped on his face, and hence, his company loses the contract, sending shockwaves across his company: layoffs, cutbacks, closures.  All because this stupid bastard didn’t feel it was important enough to get juiced up to do battle against his enemies.  As Sponge Bob said: “Good luck with that”.

7. Digital Cameras

When you think about it, digital photography isn’t just about convenience.  It’s about efficiency and speed.  It’s also about reach and pervasiveness.  Think of all the things you’ve seen and learned from viewing digital images that, had they been on paper, you might have never seen.  FlickR, Picasa, PhotoBucket, and so on, wouldn’t even exist.  Think of all the first-hand, Johnny-on-the-spot images we’ve seen that wouldn’t be possible if someone had to say “hey, did you change the film roll and put a new flash bulb in?”  Meanwhile, their buddy had already crashed his motorcycle into the bus and they missed the chance to post it online.  This goes into cell phones of course, which are even more ubiquitous than traditional cameras.  Every teenager has one.  They keep it ready for when the next fat slob rent-a-cop hassles them for skateboarding.  Be thankful for digital photography and video capturing.  It’s changed our world immensely.

8. The Charcoal Grill

Sure, gas is easier.  But charcoal just flat-out tastes better.  If you can’t tell, you’re too stupid to be eating at all and should be fed by tube.  If you have functioning taste buds, even if you’re a vegan, anything grilled on charcoal is just the way to go.  Anything that can be eaten tastes better when grilled over charcoal.  Hamburgers, Steaks, Fish, Chicken, Squid, Eel, Squirrel, Dog, Cat, Solicitors (with Farva beans and a nice Cianti). 

9. Velcro

Sure, it’s annoying as hell every time you rip apart the bond.  But the bond itself is what’s so incredible.  Who would have thought the NASA space program of the 1960’s would have brought back something so amazing and that it would find its way into so many common things around us.  Shoes.  Coats.  Bags.  Now, if only someone could invent silent Velcro.  That would be the bomb.

10. Origami

Yeah, sure, go ahead a scoff.  But it got you through hours of dull school work and fork-in-the-eye staff meetings.  Raise your hand if you read the heading and at first thought it said Orgasm?  Yeah, right.

Honorable Mentions

11. Porn (need I say more?)

12. Explosives

13. Martial Arts

14. Computers (why not)

15. Nitrous Oxide (not the kind used in cars either)

16. Power Tools

This has been the 17th installement of Cranium Drainium.  Enjoy!

Tuesday, August 25, 2009

Web Report of SQL Table and View Structures via ASP

Here’s a fairly basic ASP example for displaying the table and view structures in a SQL database.  I have only tested this with MS SQL Server 2005 and 2008, so I can’t vouch for other database platforms.  Be sure to edit the variables at the top (in red) carefully.


'****************************************************************
' Filename..: sqlschema.asp
' Author....: skatterbrainz (skatterbrainz.blogspot.com)
' Date......: 08/04/2009
' Purpose...: display tables and views
' SQL.......: SERVER\INSTANCE, DatabaseName
'****************************************************************

Response.Expires = -1

Const schema_name = "dbo"
Const db_server = "SERVERNAME\INSTANCE"
Const db_name = "DatabaseName"
Const db_user = "UserName"
Const db_pwd = "Pa$$worD"


dsn = "DRIVER=SQL Server;SERVER="&db_server&";database="&db_name&";UID="&db_user&";PWD="&db_pwd&";"

'----------------------------------------------------------------


Const adOpenStatic = 3
Const adLockReadOnly = 1
Const adUseClient = 3
Const adCmdText = &H0001

'----------------------------------------------------------------
' function: trap and display error and stop processing
'----------------------------------------------------------------


Sub ErrTrap(s)
If err.Number <> 0 Then
wscript.echo "error: " & err.Number & " / " & err.Description
wscript.echo "reason: " & s
Response.End
End If
End Sub

On Error Resume Next

Set conn = Server.CreateObject("ADODB.Connection")
Set cmd = Server.CreateObject("ADODB.Command")
Set rs = Server.CreateObject("ADODB.Recordset")

query = "SELECT table_name, table_type " & _
"FROM information_schema.tables " & _
"WHERE table_schema='" & schema_name & "' " & _
"ORDER BY table_name"

conn.Open dsn
ErrTrap "fail: ado-conn-open"

rs.CursorLocation = adUseClient
rs.CursorType = adOpenStatic
rs.LockType = adLockReadOnly

Set cmd.ActiveConnection = conn

cmd.CommandType = adCmdText
cmd.CommandText = query
rs.Open cmd
ErrTrap "fail: ado-rs-open"

If rs.BOF And rs.EOF Then
rs.Close
conn.Close
Set rs = Nothing
Set cmd = Nothing
Set conn = Nothing
Response.Write "<strong>No records found</strong>"
Response.End
End If

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


Sub TableColumns(tableName)
Dim conn, cmd, rs, query
On Error Resume Next

Set conn = Server.CreateObject("ADODB.Connection")
Set cmd = Server.CreateObject("ADODB.Command")
Set rs = Server.CreateObject("ADODB.Recordset")

query = "SELECT column_name, data_type, ordinal_position, column_default, " & _
"character_maximum_length AS maxlen, is_nullable, numeric_precision " & _
"FROM information_schema.columns " & _
"WHERE table_schema='" & schema_name & "' AND table_name='" & tableName & "'"

conn.Open dsn
ErrTrap "fail: ado-conn-open columns"

rs.CursorLocation = adUseClient
rs.CursorType = adOpenStatic
rs.LockType = adLockReadOnly

Set cmd.ActiveConnection = conn

cmd.CommandType = adCmdText
cmd.CommandText = query
rs.Open cmd
ErrTrap "fail: ado-rs-open columns"

If Not(rs.BOF And rs.EOF) Then
Response.Write "<table width=100% border=1 cellpadding=4 cellspacing=1>"
Response.Write "<tr><td>Field</td><td>Ordinal</td>"
Response.Write "<td>Type</td><td>Size</td><td>Null</td>"
Response.Write "<td>Default</td><td>Prec</td>"
Response.Write "</tr>" & vbCRLF
Do Until rs.EOF
ordinal = rs("ordinal_position").value
colname = rs("column_name").value
datatype = rs("data_type").value
maxlen = rs("maxlen").value
nullable = rs("is_nullable").value
numprec = rs("numeric_precision").value
coldef = rs("column_default").value
Response.Write "<tr>" & vbCRLF
Response.Write "<td style=width:180px>" & rs("column_name").value & "</td>"
Response.Write "<td style=width:60px>" & rs("ordinal_position").value & "</td>"
Response.Write "<td style=width:120px>" & rs("data_type").value & "</td>"
Response.Write "<td style=width:120px>"
If Not(IsNull(rs("maxlen").value)) Then
Response.Write rs("maxlen").value
End If
Response.Write "</td>" & vbCRLF
Response.Write "<td class=v8w style=width:120px>"
If rs("is_nullable").value = "YES" Then
Response.Write " [Null]"
End If
Response.Write "</td>" & vbCRLF
Response.Write "<td style=width:120px>" & rs("column_default").value & "</td>" & vbCRLF
Response.Write "<td>" & rs("numeric_precision").value & "</td>" & vbCRLF
Response.Write "</tr>" & vbCRLF
rs.MoveNext
Loop
Response.Write "</table>" & vbCRLF
rs.Close
conn.Close
Set rs = Nothing
Set cmd = Nothing
Set conn = Nothing
End If
End Sub

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


Sub ViewTables(vName)
Dim conn, cmd, rs, query
On Error Resume Next

Set conn = Server.CreateObject("ADODB.Connection")
Set cmd = Server.CreateObject("ADODB.Command")
Set rs = Server.CreateObject("ADODB.Recordset")

query = "SELECT table_name, column_name " & _
"FROM information_schema.view_column_usage " & _
"WHERE table_schema='" & schema_name & "' AND view_name='" & vName & "'"

conn.Open dsn
ErrTrap "fail: ado-conn-open columns"

rs.CursorLocation = adUseClient
rs.CursorType = adOpenStatic
rs.LockType = adLockReadOnly

Set cmd.ActiveConnection = conn

cmd.CommandType = adCmdText
cmd.CommandText = query
rs.Open cmd
ErrTrap "fail: ado-rs-open columns"

If Not(rs.BOF And rs.EOF) Then
Response.Write "<table width=100% border=1 cellpadding=4 cellspacing=1>"
Response.Write "<tr><td>Table</td><td>Column</td>"
Response.Write "</tr>" & vbCRLF
Do Until rs.EOF
ordinal = rs("ordinal_position").value
colname = rs("column_name").value
datatype = rs("data_type").value
maxlen = rs("maxlen").value
nullable = rs("is_nullable").value
numprec = rs("numeric_precision").value
coldef = rs("column_default").value
Response.Write "<tr>" & vbCRLF
Response.Write "<td style=width:180px>'" & rs("table_name").value & "</td>"
Response.Write "<td>" & rs("column_name").value & "</td>"
Response.Write "</tr>" & vbCRLF
rs.MoveNext
Loop
Response.Write "</table>" & vbCRLF
rs.Close
conn.Close
Set rs = Nothing
Set cmd = Nothing
Set conn = Nothing
End If
End Sub

'----------------------------------------------------------------

Do Until rs.EOF
If rs("table_type").value = "BASE TABLE" Then
Response.Write "<h4>" & rs("table_name").Value & "</h4>" & vbCRLF
TableColumns rs("table_name").Value
End If
rs.MoveNext
Loop

rs.MoveFirst
Do Until rs.EOF
If rs("table_type").value = "VIEW" Then
Response.Write "<h4>" & rs("table_name").Value & "</h4gt;" & vbCRLF
TableColumns rs("table_name").value
ViewTables rs("table_name").value
Response.Write "<br/>"
End If
rs.MoveNext
Loop

rs.Close
conn.Close
Set rs = Nothing
Set cmd = Nothing
Set conn = Nothing

10 Unexpectedly Cool Places I Remember Well

1. Sam Ash Music Center in Manhattan NYC

If you love playing music as much as me, or just love music history memorabilia, this is it.

2. Parasailing off the shore of Virginia Beach, Virginia

If you live here, you should do it at least once.  If you’re visiting, do it anyway.

3. The Smithsonian Institute Museum of ____ (just pick one)

Need I really say more?

4. Monk’s Cafe in Philadelphia

One of the best dining and beer experiences I’ve ever enjoyed.

5. Maymont Park in Richmond, Virginia

A fantastic park in the heart of Richmond near the James River.

6. Fall River Pass, Colorado

Thin air, clear view, excellent drive.

7. Saugatuck Dune Ride, near Saugatuck, Michigan

The dunes are amazing.  The dune buggy ride will blow your mind.  Saugatuck is like a mix of a college town, an entrepreneur haven and a relaxed summer home town all wrapped in one.

8. Prospect Hill Bed & Breakfast, near Charlottesville, Virginia

My wife and honeymooned there in 1988.  The place is amazing.  Worth every penny.

9. MacKay Island NWR, North Carolina

40 minutes drive from my house and I can’t get there enough.  Peace and quiet.  Nature left alone.  Fishing, flat-land hiking, kayaking or just bird watching.

10. The top floor of ____

The World Trade Center towers in NYC (RIP)

The Empire State Building, NYC

The Chrysler Building, NYC

The (former) Sears Tower, Chicago

The Statue of Liberty, NYC

The Washington Monument, DC

Monday, August 24, 2009

10 Useful Group Policy Features in Windows 7 for Small Businesses

Windows 7 builds on top of the improvements made with Windows Vista, and arguably improves upon Vista by cleaning up some of the mess it added over XP.  However, one aspect of the evolution of Windows that hasn’t taken any steps backwards is Group Policy.  Vista added Group Policy Preferences (with Windows Server 2008 Active Directory), as well as a boat-load of new GPO settings and options.  Windows 7 adds even more settings and options and improvements to Group Policy Preferences as well, and if you have some flavor of Windows Server 2008 in your AD environment, even in mixed mode, the better.

This article is focused on using Group Policy settings in an Active Directory environment.  Whether you use Windows Small Business Server or Windows Server Essentials doesn’t matter.

What I’ve tried to do here is put on my small business IT manager hat and focus on a top-10 settings list that would likely come in handy for such environments.  These may not apply to every small business environment, nor would they likely fit into a large, enterprise environment.  But at least it should give you a place to start, if nothing else.  Remember: User Configuration settings apply to users not computers, so be mindful of where your user account resides in AD (which OU or container) and where your other users’ accounts reside.  Computer settings depend on where the computer itself resides in AD.  Just a reminder.

1. Hiding/Showing Things on the users’ Start Menu and Desktop

User Configuration / Administrative Templates / Start Menu and Taskbar
User Configuration / Administrative Templates / Desktop

2. Turn AutoPlay On or Off

User Configuration / Administrative Templates / Windows Components / AutoPlay Policies

3. Enable / Disable Desktop Gadgets

User Configuration / Administrative Templates / Windows Components / Desktop Gadgets

4. Control Access to CD/DVD, and other Removable Media Devices

User Configuration / Administrative Templates / System / Removable Storage Access

5. Turn off Anytime Upgrade

User Configuration / Administrative Templates / Windows Components / Windows Anytime Upgrade

6. Configure Windows Explorer Features

User Configuration / Administrative Templates / Windows Components / Windows Explorer

7. Configure Event Forwarding to a Server (for centralized monitoring and reporting)

Computer Configuration / Administrative Templates / Windows Components / Event Forwarding

8. Disable InPrivate Browsing in Internet Explorer 8

Computer Configuration / Administrative Templates / Windows Components / Internet Explorer / InPrivate

9. Enable Parental Controls while in Domain environment

Computer Configuration / Administrative Templates / Windows Components / Parental Controls

and my personal Favorite is a long-awaited feature…

10. Force Disconnect, Lock or Logoff When Logon Hours Expire

Note: This is NOT the same as it was with Windows XP, etc.  You can now tell Windows what to do when the user’s logon hour expires.  You can choose to force a disconnect, a lock or a logoff.

User Configuration / Administrative Templates / Windows Components / Windows Logon Options

Sunday, August 23, 2009

Script to Import MS-Access 2007 data into SQL Server 2005 table

Before you start throwing your hands in the air and exclaiming “see? I told you!  This guy is a dumbass!  Anyone with any experience using SQL 2005 knows you use SSIS to do this!”, I know.  And I agree: it is the way to go.  But (yes, there is a but) you may be forced to deal with this situation without having SSIS at your disposal.  I won’t get into reasons why this could be, but suffice it to say it does happen.  So there are options a-plenty for you to pull this off.  One of them is using a script.  Any script.  It doesn’t matter what language really, as long as you can connect the pieces together and move data across.

This is just ONE example, using VBScript and ADO to connect to a Microsoft Access 2007 database file, fetch the results of a query, connect to a SQL 2005 instance, truncate a temp table, copy over the query record data, then roll that over into a final table.

Why the temp table?  Because it adds a buffer layer of safety and performance in the middle.  On the safety side, it helps to ensure you get valid results from the source query before doing anything more.  If that fails, you exit and notify that the source shit the bed for some reason.  If it succeeds, you pull the data over into a temp table first, then copy it from there to the final table.  This last step provides a boost in performance.  If you have applications or other SQL views relying on the final table data, you want to keep the window of time during the import as short as possible to avoid interrupting those other services.  It’s much faster to copy from one SQL table to another, especially within the same database schema, than it is to bring them over from a remote Access query.  So, in short, you bring it over into a temporary place, making sure you got it all, then you swap it into the final location.

There are DBA’s that will disagree with this, and those that will agree.  I side with the latter.  So, I’ll shut up and drop the code below.  Remember: as always, this is for example only.  No garantees are given of any kind.  Be sure to modify to suit your needs and test test test test before using in any production environment.

'****************************************************************
' Filename..: access_2_sql.vbs
' Author....: David Stein
' Date......: 08/18/2009
' Purpose...: import ms-access 2007 data into a sql 2005 table
' SQL.......: (source) MS Access 2007 .accdb file
' SQL.......: (target) SERVER\INSTANCE:DatabaseName
'****************************************************************

Option Explicit

Const sourceDB = "\\server\sharename\folder\ms_acces_data.accdb"
Const sourceTable = "qry_MyQuery"
Const targetSrv = "SERVER2\SQL_INSTANCE"
Const targetDB = "SQL_Database_Name"
Const tempTable = "dbo.tbl_TempTable"
Const finalTable = "dbo.tbl_FinalTable"

' required if using SQL security (if you use AD/Trusted, modify the dsn below)
Const dbuser = "SQL_USERNAME"
Const dbpwd = "SQL_PASSWORD"

Const adOpenForwardOnly = 0
Const adOpenKeyset = 1
Const adOpenDynamic = 2
Const adOpenStatic = 3
Const adLockReadOnly = 1
Const adLockPessimistic = 2
Const adLockOptimistic = 3
Const adLockBatchOptimistic = 4
Const adUseServer = 2
Const adUseClient = 3
Const adCmdText = &H0001
Const adCmdTable = &H0002
Const adCmdFile = &H0100
Const adStateClosed = &H00000000
Const adStateOpen = &H00000001

Dim sourceDSN, targetDSN, conn1, cmd1, rs1, rs2, query1, conn2, icount, query

sourceDSN = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sourceDB
targetDSN = "DRIVER=SQL Server;SERVER="&targetSrv&";database="&targetDB&";UID="&dbuser&";PWD="&dbpwd&";"

On Error Resume Next

'----------------------------------------------------------------

wscript.echo "info: processing initiated at " & Now

'----------------------------------------------------------------
' truncate destination (target) table
'----------------------------------------------------------------


wscript.echo "info: truncating table..."
Set conn2 = CreateObject("ADODB.Connection")
conn2.Open targetDSN
conn2.Execute "TRUNCATE TABLE " & tempTable & ""
conn2.Close
Set conn2 = Nothing
wscript.echo "info: table has been truncated"

'----------------------------------------------------------------
' open connection to source database
'----------------------------------------------------------------


Set conn1 = CreateObject("ADODB.Connection")
Set cmd1 = CreateObject("ADODB.Command")
Set rs1 = CreateObject("ADODB.Recordset")

query1 = "SELECT * FROM [" & sourceTable & "]"

wscript.echo "info: opening connection to source..."
wscript.echo "info: source database is " & sourceDB
wscript.echo "info: source table is " & sourceTable

conn1.Open sourceDSN

rs1.CursorLocation = adUseClient
rs1.CursorType = adOpenStatic
rs1.LockType = adLockReadOnly

Set cmd1.ActiveConnection = conn1

cmd1.CommandType = adCmdText
cmd1.CommandText = query1
rs1.Open cmd1

wscript.echo "info: sending query to source..."

If rs1.BOF And rs1.EOF Then
rs1.Close
conn1.Close
Set rs1 = Nothing
Set cmd1 = Nothing
Set conn1 = Nothing
wscript.echo "fail: no records found"
wscript.quit(1)
Else
cols = rs1.Fields.Count
rows = rs1.RecordCount
wscript.echo "info: " & rows & " records were returned"
End If

'----------------------------------------------------------------
' open connection to target database
'----------------------------------------------------------------

wscript.echo "info: opening connection to destination..."

Set rs2 = CreateObject("ADODB.Recordset")
On Error Resume Next

rs2.Open tempTable, targetDSN, adOpenDynamic, adLockOptimistic, adCmdTable

If err.Number <> 0 Then
rs2.Close
Set rs2 = Nothing
wscript.echo "fail: unable to connect to destination..."
wscript.echo "fail: rs2 (" & err.Number & "): " & err.Description
err.Clear
wscript.quit(2)
End If

'----------------------------------------------------------------
' SOURCE column names
'----------------------------------------------------------------
' EmpID
' FirstName
' LastName
' Department
' ManagerID
' Email
' WorkPhone
' HireDate
'----------------------------------------------------------------

'----------------------------------------------------------------
' DESTINATION and FINAL column names
'----------------------------------------------------------------
' emp_id
' f_name
' l_name
' dept
' mgr_id
' email
' work_phone
' hire_date
'----------------------------------------------------------------


wscript.echo "info: importing source records..."

icount = 0

Do Until rs1.EOF
rs2.AddNew
rs2("emp_id").value = rs1("EmpID").value
rs2("f_name").value = rs1("FirstName").value
rs2("l_name").value = rs1("LastName").value
rs2("dept").value = rs1("Department").value
rs2("mgr_id").value = rs1("ManagerID").value
rs2("email").value = rs1("Email").value
rs2("work_phone").value = rs1("WorkPhone").value
rs2("hire_date").value = rs1("HireDate").value
rs2("date_added").value = Now
rs2("comment").value = ""
rs2.Update
rs1.MoveNext
icount = icount + 1
Loop

wscript.echo "info: " & icount & " records were imported"

'----------------------------------------------------------------
' close transfer connections and release objects
'----------------------------------------------------------------


rs1.Close
conn1.Close
Set rs1 = Nothing
Set cmd1 = Nothing
Set conn1 = Nothing

rs2.Close
Set rs2 = Nothing

'----------------------------------------------------------------
' truncate final table and import from temp table
'----------------------------------------------------------------


If icount > 0 Then
wscript.echo "info: truncating final destination table for rollover..."
Set conn2 = CreateObject("ADODB.Connection")
conn2.Open targetDSN
conn2.Execute "TRUNCATE TABLE " & finalTable & ""

wscript.echo "info: table [" & finalTable & "] has been truncated"

query = "INSERT INTO " & finalTable & " (" & _
"emp_id, f_name, l_name, dept, mgr_id, email, work_phone, hire_date," & _
"date_added, comment) " & _
"(SELECT emp_id, f_name, l_name, dept, mgr_id, email, work_phone, " & _
"hire_date, date_added, comment FROM " & tempTable & ")"

wscript.echo "info: rolling data from temp to final..."
conn2.Execute query, , adCmdText

conn2.Close
Set conn2 = Nothing
wscript.echo "info: rollover completed"

Else
wscript.echo "warn: no data was imported so temp was not rolled into final"
End If

'----------------------------------------------------------------

wscript.echo "info: processing completed at " & Now

Saturday, August 22, 2009

Friday, August 21, 2009

10 Ways to Know If You’re a Douche Face (a new installment of Cranium Drainium)

1. You Have a Celtic Tattoo on Your Arms

Message: I’ve run completely out of fresh ideas, so I’m copying every other drunk dumbass.  Getting the gage/piercing kit as a bundle package is even douchier on the douche scale.

Douchivity Score: 8

Saving Graces: You actually consider getting them removed by LASER.

2. You Own a New Red Ford Mustang, or Dodge Charger

Message: After I got drunk and spent my welfare check on the celtic tattoos, I took the rest and bought a Red ______ just like my friends, neighbors, co-workers and guys on TV all bought.  Nothing says “I’m different” like doing the same (or driving the same) shit as everyone else.

Douchometer Score: 9

Saving Graces: You work for Ford or Chrysler

3. You Drive in the Left Lane and Never Exceed the Posted Speed Limit

Message: I’m a fucking dumbass and I’m going to keep you from getting where you’re trying to go.  You feel it’s your duty to keep the rest of traveling safe.  So you piss us off the point where we drop gear, punch it and try to pass your lethargic ass and end up causing a five car pile-up.  Thanks.

Douchberg Score: 10 (fuck you)

Saving Graces: None.  You should be pushed off the road, drug from your car and beaten to death by an angry mob.  The video should be posted on YouTube also.

4. You Toss Cigarettes or Other Trash Out of Your Car Window

Message: America, Love it Or Leave It - is your motto.  Leave it in Ruins - is your practice.  You’re so proud of your country you can’t wait to shit and piss all over it.  After all, this is the greatest country on Earth, and you’re simply paying homage by decorating it with Bush beer cans and Michelob bottles.

Douchbreath Score: 10

Saving Graces: None. You should share the same fate as the #3 guy.  Or have your rectum swaged by the jaws of life.

5. You have Truck Nuts

Message: These are the only testicles I’m allowed to have or display.  Your wife owns the smaller, real ones.  If you were a REAL man, you’d hang your own REAL sack on the back bumper.  Try that, you sissy!

Douchbrain Score: 10

Saving Graces: Someone cuts them off and hangs them from your antenna.

6. You Have the Stupid, Tired Calvin Kid Pissing Sticker (pissing on Ford or Chevy, etc.)

Message: You got in line to buy this sticker because it’s cool and (guess what?): everyone else got one that couldn’t pass the fourth grade.  When you point at it and laugh you snort like Baby Huey and think it’s the most clever thing ever invented.

Douchonomy Score: 7 (not worth an 8, sorry)

Saving Graces: You bought the truck for $400 from a guy named Earl and it was already on it.

7. You are a Die-Hard Republican or Democrat

Message: You seriously believe your Congressman/woman/ Senator/ whatever, really cares what you think, as opposed to just caring for your vote.  You think they’re actually working, when they’re actually on sabbatical (like they are this very week, actually).  You think they’re not golfing together and laughing about how thoroughly they’re screwing you, your family, your retirement, and your children’s future, but are actually arguing over ethical differences like Federal vs State’s rights.

Douchatorium Score: 11 (you’re so hopelessly fucktarded it’s pathetic.  And: NO, Being a Libertarian does not give you a pass here.  LaRouche?  Seriously?  Are you kidding?!)

Saving Graces: You vote, but you cherry pick by candidate agenda, not along party lines.

8. You Dress Up Special to Ride Your Harley

Message:  By day, you’re mild-mannered car/furniture/siding/insurance salesguy.  Wife and kids.  Soccer practice, golfing with the buddies.  By weekend: You tie a scarf around your balding head and leave a tail to mimick having long hair (as if?!).  You get your ripped up, worn out chaps on, with your best Jack Daniels black T-shirt with holes, and your yard-sale worn riding boots, and finally add the biker chain wallet and wrist bands.  Suit up, jump on, turn the key (dead giveaway), and ride with a poker face on.  It screams “I’m a closet douchbag”.

Iron Douch Score: 9

Saving Graces: If you just ride with normal clothes on and don’t pretend to be something you’re not, you get a pass.  If you actually do manual labor for a job and come home covered in dirt, grease and can’t afford nice clothes and your bike is held together with duct tape, bailing wire and spare parts: you get a pass.

9. Stupid-Ass Bumper Stickers

Message: You love sharing your thoughts with the general public.  But you don’t want to hear back from the general public.  It’s a one-way trip.  You desperately want us all to read your obnoxious shit and all the idiots you voted for that couldn’t win the election (but you still want us all to know you voted for the loser anyway).

Douchativity Score: 8

Saving Graces: You have stickers with jokes on them that NOBODY else has.  If it’s original you get a pass.

10. Walking Around with a Bluetooth Earphone in Public

Message: You are a self-absorbed piece of decaying shit who thinks we’re all impressed with your conversation with someone you think is “plugged-in” and “connected” with the “in crowd”.  Sure. We all assume you’re talking to Will Smith or Steve Jobs.  You bark out “buy low and sell high!” while sitting on the bleachers at your son’s T-ball game.  You talk out loud wandering the aisles in a library or the (otherwise silent) Barnes & Noble store.  While they are admirable for driving safety, they are a complete head-dunk into the vats of douche juices when worn in public.

Da-da-da-da-Douchebag Score: 11

Saving Graces: If you are an EMT or EOD (bomb disposal guy) you get a pass.  If you’re doing brain surgery you get a 3/4 pass.  If you’re in Barnes & Noble: ass-beating is approved – proceed.

Honorable Mentions:

11. Brand-Name Ball Cap with Oakley Shades Pinned on Top

12. Fingerless Leather Gloves

13. Making Special Trips to Buy Red Bull or Monster drinks

14. Leaving Your Dog outdoors 24x7 Without Ever Bringing Them Inside

15. You Think T.O. is a Nice Guy

16. You Think Charles Manson is just Misunderstood

17. You Disagree that Xe (formerly Blackwater USA) is a mercenary force

18. You’re on Welfare and Buying Cigarettes

19. You Ardently Defend Apple and Steve Jobs without Question

20. You Read moronic blogs like this one.

Bicycling Around Virginia Beach

I live in Virginia Beach, Virginia.  The highest populated city in the state with approximately 430,000 residents, at last count.  It’s a city that has long prided itself on being “outdoorsy” and has a lot of parks, creeks, shores, and recreation centers compared to most other metropolitan areas around the state; not to mention along the East coast.  It is a nice place to live in many respects.  You can find a large number of joggers, walkers, bicyclers, boaters, swimmers, and so on.  Being on the coastline with plenty of beach areas you will also likely find surfers, kayakers and fishermen, but you will find kayakers just as often inland on one of the many creeks and lakes around the area.

I used to do a fair amount of running until last year when my knees finally gave out and I had to find another hobby.  I’ve always enjoyed bicycling, so now I’ve become more “into” it as a way to stay in shape and avoid boredom.  There are a lot of trails and pathways that the city touts as making it “bike friendly”, but they really should add an asterisk with a footnote.  There are quite a few decent trails for biking around the city, but biking *across* the city is another challenge entirely.  I do this fairly often, so I’m pretty familiar with the good and bad and where the chokepoints are for bicycling.

From my house near Mount Trashmore Park, which is located in the northern central area of the city, I can bike to the ocean front (to the East), to the bay shore (to the North), to a few places South and West as well.  Not as many interesting places to ride South and West however.  Most of the interesting places are North and East of where I live.  The beach is about 8 miles as the crow flies.  The North shore near Chick’s beach is about 6 miles and Princess Anne Park is about 4 miles South/West of here.  Of these three paths, the simplest and safest is by far going to Princess Anne Park (where the Sportsplex is located) which is also the MOST BORING of all places to ride.  Other than moving my legs it’s about as exciting as sitting on the bike on my driveway and making “vroomm!!!” sounds like a kid with a toy motorcycle.

Riding to the beach is the most daunting but not terribly difficult.  The main routes are either along Virginia Beach Blvd, or along Dam Neck Road.  Getting to Virginia Beach Blvd from my house is only feasible by one route: Plaza Trail.  Trying to take Rosemont Road or Independence Blvd under the I-264 interchanges is suicidal.  It’s possible, but the city needs to do something as I constantly see bikers and walkers almost killed by cars flying on or off the on/off ramps without looking for anything but other cars.  It’s deadly.  Taking Dam Neck Road is a much longer path as it adds another 4 miles of riding to get to the beach itself by way of General Booth Blvd.  The stretch along General Booth is actually a nice ride, especially passing the Virginia Acquarium and the woods along the bike path.  Riding up Rudee Inlet bridge at the end is a special treat designed to stress test your quads after pumping for almost 12 miles already. 

The Dam Neck route is about 13 miles in all.  The Virginia Beach Blvd route is about 8 miles in all.  Both distances are one-way, so a round-trip is 26 or 16 respectively.  I most often do the latter route since it’s a little more interesting.  Another option is taking Virginia Beach Blvd to Laskin and following that to 30th street, which is at the North end of the boardwalk.  Regardless of the route to the beach, I usually ride the length of the boardwalk from Rudee Inlet to 40th street a few times and then head back home.  If the weather is nice I usually bring my camera to catch the freaks in public and cars and bikes, etc.

As for riding to the North shore, along the bay, there are really only two paths.  One is Independence to Pleasure House Road.  And the other is Virginia Beach Blvd to N. Great Neck Road.  The Independence route ends in the Chick’s Beach area, which is where the Chesapeake Bay Bridge-Tunnel connects to the mainland in Virginia Beach.  That route is just a hair under 8 miles.  The Great Neck Road path is longer at about 10 miles.  That ends in a rather boring area of small houses on Shore Drive, so I usually continue West to the Chick’s Beach area again, which is another 2 miles West.  The biggest challenge is the Lesner Bridge, crossing over the Lynnhaven Inlet.  Not a bike friendly bridge, as there is almost nothing between the traffic, you, and the concrete railing.  One texting, distracted or drunk driver and you’re gone.

Caution Areas

Tough Crossings include Independence at I-264.  Rosemont at I-264. Virginia Beach Blvd at Great Neck Rd.  London Bridge to Great Neck (across Virginia Beach Blvd).  Laskin at the I-264 split.  Indpendence at Pleasure House.  General Booth at Rudee Inlet (if you forget to cross early on).

Other notable paths to ride your bike along:

Cape Henry Trail, near First Landing State Park.  This is located in the North-East corner of the city and connects from the Northern end of N. Great Neck Road over to the 64th Street park entrance off of Atlantic Avenue.  One quarter of the trail is asphalt and goes through a quiet neighborhood.  The rest is hard packed dirt under tree cover and fairly straight with minor hills and bumps.  Very easy.  Total distance is about 6 miles one way.

Ferrell Parkway, which connects from Princess Anne Road over to Indian River Road in the middle West end of the city.  Only 2.5 miles by itself, it makes a good connector for adding a longer path along Indian River Road and Princess Anne Road.

Dam Neck Road, runs along the middle of the city going East to West.  It ends at General Booth Blvd (sort of, but it crosses over into a neighborhood and dead-ends in the back), and goes West beyond Salem Road becoming Elbow Road in the process.  Total distance (sort of) is about 8 miles one-way.

London Bridge Road, runs from Virginia Beach Blvd at the intersection with Great Neck Road (it becomes Great Neck as it crosses) and continues down to Dam Neck Road.  Total boring ride distance is about 4 miles.

I’m still exploring other trails and routes around the city, but suffice it to say it can be a bit hair-raising crossing some interesections along the way.

Thursday, August 20, 2009

Creating Windows Event Log Entries with Scripting

KixTart: LOGEVENT

LOGEVENT (type, ID, message, target, source)

Examples:

$=LogEvent(4, 1, “This is just a user-defined event”, “”, “CustomEvent”)

$=LogEvent(1, 1, “Login script failed on client @wksta”, @LSERVER, “KixTart”)

Limitations:  You can only write to the Application log.
Advantages: You can invoke this without having elevated permissions.  You can submit events to remote computers (if permissions allow)

Windows Vista/7: EVENTCREATE

EVENTCREATE [/S system [/U username [/P [password]]]] /ID eventid
            [/L logname] [/SO srcname] /T type /D description

Examples:

EVENTCREATE /T ERROR /ID 100  /L APPLICATION /D "This is just a user-defined event"

EVENTCREATE /S Server123 /T ERROR /L APPLICATION /D “This is a custom event”

Limitations: It must be invoked with administrative permissions.  It requires the command shell, which is minimal overhead.
Advantages: Can write to all of the event logs (System, Application, etc.).  It can write to local and remote event logs (if permissions allow)

VBScript: LOGEVENT

object.LogEvent(intType, strMessage [,strTarget])

Examples:

Set objShell = CreateObject(“Wscript.Shell”)
cn = objShell.ExpandEnvironmentStrings(“%computername%”)
objShell.LogEvent 1, “This is a custom ERROR message”
objShell.LogEvent 1, “Error on computer “ & cn, “MyServer”

Limitations: It can only write to the Application log
Advantages: Compared to the other options available: none.

PowerShell: WriteEntry

$evtLog = New-Object –type System.Diagnostics.Eventlog –argumentlist Application
$evtLog.Source = “Custom Event”
$evtLog.WriteEntry(“This is a custom Error even”, “Error”)

$cn = [environment]::GetEnvironmentVariable(“computername”)
$evtLog = New-Object –type System.Diagnostics.Eventlog –argumentlist Application, MyServer
$evtLog.Source = $cn
$evtLog.WriteEntry(“Error occurred on $cn”, “Error”)

The Death of Individuality

Back in the 1970’s I can still recall quite a few things that stand out from today.  Cars were much more distinguishable.  TV shows were more distinguishable.  Bikers were bikers.  As for cars, you could tell a Corvette, Mustang, Camaro, El Camino, Chevelle, GTO or Barracuda from almost a mile away.  If you could make out the body shape that far, you could identify it without question.  I can’t tell most cars today while standing right in front of them unless I see the name on the side somewhere.  TV shows like All In the Family, MASH, Gilligan’s Island, The Munsters, and The Beverly Hillbillies were unique.  Now every show is a clone of another.  Like Friends, or Seinfeld, or any one of the bazillion Disney Channel shows with kids making their parents look like complete idiots and disrespecting them at every turn.  Bikers in the 1970’s rode bikes that they, for the most part, assembled themselves.  And they looked it.  Parts borrowed from other models, worked, as long as they fit.  The people that rode them looked like they actually worked for a living.  Usually a shitty Godforsaken job of some kind, but a real manual labor job nonetheless.

Today we have shiny showroom Harleys being ridden by people that look like day traders or retirees.  Nothing wrong with that, but if you’re going call yourself a “Harley rider” or a “biker” you need to stop shaving and rub some grease on you and your bike to be more convincing.

This all came back to me today while taking note of the cars and people I see each day as I make my 64 mile roundtrip commute to and from work.  I counted, roughly, about 20 to 22 red Ford Mustangs.  Brand new models, not older ones.  I also counted about 8 to 10 of those brand spanking new Harleys with well-dressed riders, and about 6 or 7 Red Dodge Chargers, a few silver ones, a few black ones, and so on.  They all look alike to me.  And the quantity of them is disturbing.  It screams “I want to be like everyone else”.  America was never like this before.  Prior to this past decade, we were known around the world for individuality and uniqueness.  It’s what fueled innovation and creativity.  It’s why we led the world in so many diverse areas from entertainment, to technology, to art and arguably literature.  We’ve devolved into a soup of blandness and corporate molding.  It’s really sad and I hope to do whatever I can to instill in my kids the ability to see that and work around it.  Don’t be another clone.  Be yourself.  Be different.  Don’t drink a cold one and get another lame-ass Celtic tattoo on your arm.

Wednesday, August 19, 2009

Querying Active Directory vs SQL Server

Warning: This is a meandering rant.  Drink plenty of caffeine to avoid crashing into a guard rail.

I’ve had a few friends/co-workers hit me up about this subject recently.  For what reason – I don’t know.  Why me?  I’m only guessing it’s something to do with my extensive work gluing together web services and web apps using SQL Server, Active Directory and plumbing in things like WMI/SWBEM/WQL and so on.  My background is more in software development than in systems engineering, so I look at something like Active Directory and immediately want to take it apart and see what makes it tick.  Kerberos, KCC topology, links and replication processes, DFSR, events and logs, WMI and ADSI, and LDP.  Everything in the software world looks like Legos to me.  Microsoft really doesn’t get the credit they deserve for, as Paul Thurrott says: building a business of building platforms.  They are the king of platforms.  And nobody goes to the extent they do to document their numerous platforms.

Where was I?  Oh yeah, sorry.  I was blabbering about myself, as if anyone cares.

So, the issue is what are the concerns and what are the trade-offs between querying Active Directory directly as opposed to using SQL Server as a middle man (between the data and the consuming service or application).  The answer is (drum roll please):  it depends.

For most general information gathering, it’s fine to query AD directly.  The AD schema and various tentacles into it are actually tuned more for read/fetch operations than for write/modify operations.  That’s because the nature of AD is authentication and look-up.  Both of those chores involve far more reading than writing.  Don’t believe me?  Just think about how often you logon to you network as opposed to how often you change your password or some property within your user account.  Think about how often you boot up a computer as opposed to how often you join it to the domain.  That’s one of the reasons Microsoft didn’t push harder to move the AD partition suite into a relational database.  Some argued for doing that, but really, the cost factor just doesn’t offset the gains in performance or capability.

That said (yes, all of that… phew!) there are times when it makes sense to introduce a data store in the middle.  This can be XML, SQL, or just about anything.  Why?  Because maybe you want to maintain a faster performing cache with a subset of the overall data store.  You can dynamically filter LDAP, WMI, and so on, sure.  But sometimes it helps to at least tape things together a bit.  An example?  Ok.  One project I worked on involved pulling aggregate information about employees from several data stores, including AD.  The end result needed to be able to instantly display employee data, as well as AD and Exchange data, and things about the computer that employee uses.  Rather than having the web app reach out and query all of the domain controllers (to get the last logon data, for example), I used a SQL process to fetch and update that periodically and that allowed the web application to fetch the end result much quicker and with more reliability.

A relational database is also great for storing historical information in ways that are often cumbersome to do with native platform APIs.  One example is monitoring AD replication status.  A project I worked on involved running REPADMIN, NETDIAG and DCDIAG, on each of the clients domain controllers and feeding parsed results into a SQL database on a recurring schedule.  This is very similar to what MOM/SCOM does obviously, but you can do much of the same yourself with a little elbow grease (and much cheaper).  The EVENTTRIGGERS command also helps in this regard.  When collected into one data store like this, it is much more efficient to analyze it, query it and run secondary processes from it (alerts, reports, automated diagnostics and repair, etc.).

As I said, this article is really a frame of thought about how to approach these two avenues, more than giving discrete examples.  I may post some real examples if anyone is interested.  Some of them might take some serious prep work to shoehorn into a blog post.

Tuesday, August 18, 2009

The Perils of Using Twitter for SysAdmin Automation

In the simplest terms:  Twitter is just too unreliable.  It suffers from performance problems and periodic outages and hiccups which make it risky to rely on for use as a system events notification tool.  The examples I posted on this blog for Sending Direct Messages, Fetching Direct Messages , and incorporating EventTriggers via VBscript and KiXtart were meant to show that this idea is indeed possible and feasible.  However, it is not very practical.  I’m sure many Twitter users would agree with this view, while others may not, but my experiences support this view as far as I’m concerned.  I love Twitter and use it heavily, and the API is impressive and surprisingly good.  But this falls into the old saying: Never confuse “could” with “should”.

Monday, August 17, 2009

Busting Another Myth: Dog Poo is Destroying our World

Myth: Dog Feces is Bad for the Environment

I would have thought this was obviously dumb, but I suppose I need to digress into this and flesh out the rationale behind why this is just flat-out stupid.

Assuming that before mankind arrived in high numbers to this wonderful land of “ours” (translation: the piece of land we stole from the Indians), there were likely a much higher population of wildlife than there are today.  A MUCH higher population.  That would also imply more wildlife fecal matter.  Before the East Coast was settled, there were large numbers of deer, bear, foxes and wolves and all sorts of furry mammal critters living all over the place.  Did their poop destroy the forests?  Did it destroy the fish with the runoff?  Now we have VASTLY fewer animals per square mile in 2009 than were here in 1809, with the remainder filled (or over-filled) with humans (the other dumb mammal that does stupid shit).  Given that humans, for the most part, do their dirty business into a toilet, and that the byproduct is routed by sewer lines to a treatment plant, that means there is much less fecal matter laying around per square mile than one hundred years ago.  Much less.  If every dog alive did a doody on their owner’s front lawn, it wouldn’t come close to 1/100th of the total volume of doody from back then.  Yet, somehow, it DESTROYS the environment.  If you still believe that, you suck at math.

Part 2 – If you live near a park with a lake or a pond, you may have come to see a Goose or two.  If so, you may also notice just how much poo a Goose tends to drop as they walk around acting as stupid as a typical human car driver.  Just in the park across the street from our house, on an average day, there will be about two dozen Canadian or white geese grazing and pooping like little doody machines.  The size and mass of their droppings is about the same as that of a small dog.  However, they doody at about 1000 times the rate of a small dog.  If you have a small dog and it poops every minute, it has serious problems.  However, this is normal for a Goose.  Does Goose fecal matter destroy the environment?  Are there actually people that walk behind them and scoop their poop?  I sure hope not.

Sure, Geese eat grass and vegetation, while dogs eat meat and vegetation.  Foxes, beer and other animals eat meat too.

Granted, nobody wants dog poo everywhere.  It sucks to step in it, and it smells bad.  I’m not saying you shouldn’t “curb your dog”, but let’s be honest about the logic behind it.  Pick up because it’s the decent thing to do.  Not because of some bullshit “green” storyline.  If this dumbass P.C. mindset continues on, I would expect to see a law passed that requires dog owners to attach a poop sensor on their dogs.  It would count the poops and transmit the location of the drop and date/time.  Automatically sending a bill to the owner for carbon footprint damage to the environment.  Think I’m kidding?  Think again.

Apparently, the approach of asking people to pick up just to be nice wasn’t working.  So they have to pin another reason on it: The environment.  That’s right.  Animals pooping destory the world.  So don’t forget to pick up after your racoon, squirrel, rabbit, fox, deer, bear, and so on.  After all: wildlife has now become Nature’s enemy.

Sunday, August 16, 2009

Changing the Windows 7 Start Menu Power Button Default

Windows 7 has a really nice, yet often ignored, feature for setting the default for the Power button on the Start Menu.  By default, this is set to “Shutdown”, but in many situations it works better to be set to something else, such as “Log off” or “Hibernate”, etc.  The good news for those working within an Active Directory environment is that you have Group Policy services to help enforce this on a large scale, without having to walk around (or remote into) a lot of machines.

Note: I’m a HUGE proponent of scripting, so anytime I suggest you can forego scripting it’s not a trivial statement.

If you’re not familiar with what I’m talking about, the image below should clarify this a bit. When you click on the Start Menu button (or “Orb” or whatever the hell it’s called now), you will see a button to the bottom right that normally says “Shutdown”.  This is the “Power button”.  In this example you can see it is set to “Log off”.

blog1

If you Right-Click on the Power button and choose “Properties”, you can set this default manually.  To do this, click on the “Start Menu” tab of the “Taskbar and Start Menu Properties” dialog form.  In the upper part of this form panel is a listbox with the label “Power button action:”  Simply change it to whatever you prefer (see figure below):

blog4

The available options are:

“Shutdown”

“Log off”

“Lock”

“Restart”

“Switch User”

“Sleep”

 

For desktop computers, you might not want “Sleep”, but you might want that as the default for mobile devices such as Laptops and Netbooks, etc.  Setting his manually is easy enough.  But what if you want to make this setting the default on 500 or 5,000 computers?  Fortunately, there is a very simple solution.

You can use Group Policy services.  You can either remote into one of your Windows Server 2008 (WS08) domain controllers, or use RSAT from one of your Windows 7 clients.  Either way, click on the Start Menu and click “Administrative Tools”, and select “Group Policy Management”.  If you’ve used GPMC in the past, this will look very familiar, because it is essentially the same thing (with some minor improvements).

Note: This particular setting is only available if you have at least one WS08 domain controller in your Active Directory environment.  It will only apply to Windows 7, or WS08 R2 computers, and later.  It has no effect on Windows XP, Windows Vista, Windows Server 2003 or Windows Server 2008 computers.

You can either modify an existing Group Policy Object (GPO) or create a new one.  I always recommend keeping settings isolated within GPO’s to avoid confusion and allow for easier troubleshooting and management.  For example, I create a “Desktop Settings” GPO to store my settings for Desktop, Task Bar and Start Menu settings.  This isn’t a requirement, but simply a recommendation.  Once you have a GPO ready, right-click on it and select “Edit”.  Then expand the “User Configuration” tree, and expand “Policies” / “Start menu and Taskbar” and double-click on “Start Menu power button” (see figure below).

blog2

This setting has a fairly simple dialog form for setting the desired power button option.

blog3

Simply change the setting from “Not Configured” to “Enabled” and then select the desired option from the listbox in the lower-left panel (e.g. “Log off”).  Then click “Apply” and “Ok”.  All of your Windows 7 and Windows Server 2008 R2 computers that are within scope of this GPO will acquire this setting on their next refresh cycle (on next user logon, or by default every 90 minutes thereafter).  You can use the GPUPDATE command to force the update sooner if you like, which is a good idea for testing.

Note: There are many other GPO settings you can use to configure related features on the Start Menu and Taskbar.  This is only one example.

I hope you find this helpful.

Saturday, August 15, 2009

And the Crap Award for Windows Software Goes to…

Focusing exclusively on consumer-oriented products, not enterprise/business products...

Most Over-Bloated Software Product

Winner: Adobe Acrobat Reader

Runner-Up: Apple iTunes

Runner-Up: Apple QuickTime Player

Most Over-Priced Software Product

Winner: Adobe PhotoShop

Runner-Up: Autodesk AutoCAD

Runner-Up: Adobe Dreamweaver

Most Needlessly Abandoned Technology

Winner: Microsoft Windows Mobile

Runner-Up: Apple AppleTV

Runner-Up: Microsoft Windows Movie Maker (now “Live Movie Maker”)

Most Badly-Aimed Software Strategy

Winner: Google Orkut

Runner-Up: Autodesk Actrix

Runner-Up: Opera (web browser)

Worst Named Software Product

Winner: Almost Every FOSS App for Linux

Runner-Up: Almost Every FOSS App for Linux

Runner-Up: Almost Every FOSS App for Linux

Ugliest/Clunkiest Piece of Shit Software Product

Winner: Apple iTunes

Runner-Up: Apple iTunes

Runner-Up: Apple iTunes

Note: Choices were based solely on anecdotal experience. These are my personal picks. There was no scientific methodology involved.

Friday, August 14, 2009

What if the South rose Again?

I was born, and have lived, in the South all my life.  Since I was very young, I’ve seen the changes occur over time that have impacted how people interact, behave and communicate.  A lot of that is along racial lines of course, but with the increased transience of everyone these days, the line is blurred now.  The economic demographic has overlapped the racial demographic in a cross pattern.  Rich, middle class, struggling and poor.  Yes, I count four distinct classes, regardless of what the official experts insist.

One of the most common sentiments I see and hear along the struggling and poor side of the white demographic is the clinging onto southern traditions.  Or what they think are southern traditions: most of them don’t “live” on hog jowls, grits and scrapple anymore.  They live on Hardees, Red Bull, Budweiser and Bar-B-Que chicken wings.  I haven’t seen anyone in Virginia walking around eating a pickled pig’s foot since I was six or seven years old.  I’m 45 now.  But the age-old Confederate flag symbols lives on.  The Confederat solder hats live on.  The Jack Daniels/Southern Comfort mindset lives on.  Lynyrd Skynyrd lives on as well.  And the most humorous artifact in existence remains alive and well: the bumper sticker that says “The South Will Rise Again”.

Normally, I just shake my head and move on.  But while cutting the lawn and meditating (something I do a lot together) I wondered: just what if the South were to secede and “rise” again?  What would that look like?

What would this new “country” be like?

The national anthem:  Free Bird

The national bird: A middle finger

The Pledge of Allegiance: The fine print on the Budweiser can, or “Git ‘er Done!”

Sports: Fishing, Golf, Hunting, Boat Racing, NASCAR, Grilling, Bingo, Square Dancing (maybe)

(they wouldn’t have a winning baseball, football, basketball, swimming, or hockey team)

Cable channels:  Hunting Channel, Fishing Channel, Boating channel, NASCAR channel, Comedy Central (all Larry the Cable Guy, and Bill Engval 24x7), Cooking Channel (for the wives)

Daily Nutrition Guidelines: 10,000 calories.  500 grams of saturated fat, 500 grams of sugar, 5000 mg of caffeine, a box of fiber pills and a carton of cigarettes.

No Universities: No time for that egghead sissy stuff.  We got work and hunting and fishing to do.

No sports cars: Only Trucks allowed.  4x4 Diesels with lift kits, step rails and fog lights.  Shotgun rack is mandatory.  Power winch and fishing pole tubes optional.

School uniforms:  Flannel shirts with the sleevs cut off.  Torn jeans.  Case or John Deere baseball cap.  Same for girls, but they can cut their jeans to pretend to be Daisy Duke.  Hiking or Steel-Toe boots.

Theaters would show Larry the Cable Guy, Die Hard, Rocky, or Steven Segal movies only.  On weeknights they would show girly movies like Steel Magnolias, the Lake House or My Sister’s Keeper.

Libraries would only keep books on Larry the Cable Guy, Hunting, Fishing, Boating or NASCAR.  Maybe a women’s section with sewing, cooking and how to be a pregnant wife.

Average life expectancy: Men = 40.  Women-folk = 50 (high fat diet, Red Bull, Mountain Dew, and cigarettes)

Just imagine how hefty the electric carts at Wal-Mart would have to be in order to haul these fat slobs around?  They would need a hybrid engine with a turbo-charged 427ci, DOHC V-8 and a 500 foot power cable, because the number of batteries that would require would involve so much Lead they couldn’t physically move.  Crawling at 5mph up and down the aisles with a can of Red Bull in one hand and a cigarette in the other.  Grabbing Enquirer magazines, boss bottles of Pepsi, Fried Pork Rinds, and cases of Bud Lite on the way to the front checkout.

Tatoos will only be allowed if they are of a brand name or ensignia for a well-known truck maker, Budweiser, Coors, Miller, or some other shitty watered-down American beer-ish product, a hunting and fishing supplier, a sports team (see above), “Momma”, or “Git ‘er Done!”  No tramp stamps or butterflies allowed.

Outlawed thangs:  Vegans, Homosexuals, Cats, Jews, Arabs, Blacks (except for Tiger Woods and Bryant Gumble), Liberals, the Dixie Chicks, Poodles and Shitzus, Rap Music, Rock Music, New Age Music, small sporty cars, Health Food, Tennis, Roller-Blades, and other forms of expression that might threaten a pseudo-macho redneck lifestyle.  Boys will always be named Butch, Jake, Bill, Hank, Bubba or Skeeter.  Girls will always be named Daisy, Betty, Suzy, Sally or Barbara.  No boys with girly names and no girls with boy-ish names allowed.

Conclusion – With all that said, and thinking about the constraints such a territory would endure (oil, lumber, livestock, textile manufacturing, foreign relations, national defense, intelligence… ho ho ho… and so on) I would expect this “nation” to implode into complete chaos and disarray within a few years.  If the South did rise again, I would move out of Virginia most likely.  But I don’t think I have to worry about that anytime soon.

Wednesday, August 12, 2009

Painful Product Packaging Points

Four “P”s I wish were less painful, doh! – that makes five now.  Oh well.

So my day job involves packaging software for mass deployment.  We use Wise Scripting to tie everything together and compile the goo into an EXE which is shot out of an Altiris canon to several thousand computers.  We do this for very small applications, and very large applications.  One of them, which I specialize in is bundling multiple Autodesk products.  Usually, this consists of AutoCAD, Raster Design, Inventor Series (including Mechanical and Mechanical Desktop), but also the little leech products like DWG TrueView, Design Review, Vault Client, as well as numerous third-party products that ride on top of, or along side of, these Autodesk products.

The joy comes when moving to Windows XP Pro 64-bit clients.  This is when things get downright stupid.

With the Autodesk 2008 suite of products, x64 was a complete afterthought.  Yes, it works, sort of, except for Raster Design, but there are a lot of places where I went bald pulling hair out dealing with registry stupidity, folder path stupidity, services and processes stupidity and so on.  You might think: Well, why not just use their “wonderful” Deployment tool to do the heavy lifting?

Well, the Deployment tool is a heroic effort and does wonders for producing a packaged installation that almost gets you to the goal line.  There are some issues it does not handle well however.  There are some issues it doesn’t even touch, which is where we have to step in and pour our own concrete to make this bridge work.

Warning: Deeply Stupid Geek Jargon Follows

For starters, you cannot push the setup.exe and the .MST and .INI parameters via SMS, System Center Configuration Manager, or Altiris because the setup.exe spawns child processes and exits before the children are done playing.  The result is that you get NO result at all.  Imagine this:  You build a package and push it out with your favorite deployment tool (SMS, ConfigMgr, Altiris, etc.) to 10,000 computers.  When you come in the next day, you look at the status results and find that all 10,000 report “Failed”, even though most (not all) will have installed just fine.  The problem is that no matter what you do to force the calling process to wait for the entire tree of sub-processes spawned by setup.exe, the setup.exe still won’t wait and once it has given birth to all it’s children, it closes the door, and goes home.  The net result is nothing.  Meanwhile, the individual installation processes (for each product and component) continue running. 

Let’s say you added a request line to force a reboot at the end of the installation, which is a VERY common situation.  But you need to capture the result codes from all of the installation goodies to ensure they all returned a zero (0) indicating successful completion.  Or also a 3010 code, indicating success, but an in-service swap needs to occur following a reboot.  What happens is setup.exe launches, then it spawns another msiexec process and maybe some other processes and then setup.exe closes, leaving those processes to finish on their own.  Age-old parameters like /SMS and START /WAIT have zero impact on this.  So your 2nd line of instruction, the reboot, is initiated and guess what?  Yep.  The client gets kicked in the face and reboots in the middle of installing one of the products.  The net result is an incomplete installation which is a complete waste of time to diagnose and repair.  You end up manually removing each one, cleaning up leftovers and doing another installation manually.

Now, the correct way to do this:

You dive inside the .INI file which the deployment tool creates and you extract from this the list, and (very important) the sequence, of each component and product it installs.  This usually breaks down into the following:

  • Microsoft DirectX
  • Microsoft .NET Framework
  • Microsoft Visual C++ 2005 Runtime
  • Microsoft Visual C++ 2008 Runtime
  • Microsoft WSE 3.0
  • Microsoft MSXML 6.0 SP2
  • Microsoft VBA6 Runtime
  • Various KB hotfixes (optionally, depending upon conditions)

In addition to these prerequisite items, you need to also be careful to stop certain processes and services (to allow DLL’s to be removed and folders and files to be deleted cleanly), and so on.

After the carpet bombing, the ground forces can finally move in.  This is when you install the base products, the various language packs, the service packs and hotfixes (and OH BOY - I will get to that in a moment), and finally, following behind to mop up things like registry keys and values, modifying shortcuts, and so on.

  • Design Review + service packs + hotfixes
  • Inventor Suite + service packs + hotfixes
  • Mechanical Desktop / Mechanical + service packs + hotfixes
  • AutoCAD + service packs + hotfixes
  • Raster Design + service packs + hotfixes
  • DWG TrueView + service packs + hotfixes
  • Third-Party apps + service packs + hotfixes
  • Replace shortcuts to add /p profile arguments, etc.

Sound like fun?  Nah.

So, what was the comment about hotfixes above?  (hold on, I’m laughing pretty hard right now and might have to change my underwear…. hold on… um.. uhhhh…. ok) I’m back.  To be fair, Autodesk is not that much different from other software vendors when it comes to releasing updates to customers.  Microsoft has made impressive strides to standardize on the Windows Installer framework and MSIEXEC services.  This usually consists of a .MSI package for installing a product, and optional .MST (aka “Transform”) files for encapsulating custom instructions and settings, and finally .MSP (aka “Patch”) files for installing hotfixes, service packs and various updates.  The problem with many vendors is that they respect the .MSI and .MST guidelines but fall off the wagon and down a hill when it comes to standardizing on an update packaging scheme.  Autodesk (like many others) releases updates as .ZIP files, .EXE files, .MSP files and even individual data files (e.g. DLL, XML, and so on).  PAINFUL to package, test and deploy consistently.  Each of those form factors incurs its own unique methodology for installing on each client.  Long story short: I really wish Autodesk would make *all* updates as .MSP or .MSI packages, nothing else.

Back to the roadshow…

So, aside from this rather linear set of challenges is another aspect: x86 or x64.  You might think that when you whip out a disk that says “64-bit” or “x64” that it follows the appropriate guidelines cleanly.  Nope.  And again, to be fair, neither does Microsoft.  But it is improving overall.  The problem with the Autodesk 2008 suite is that half the applications dump their goods under %PROGRAM_FILES% and the other half under %PROGRAM_FILES(X86)%.  The same holds true for the registry, where some go under HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall, and the rest under HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall.  The real fun comes when Wise scripting environment translates %PROGRAM_FILES% into “C:\Program Files (x86)”, but has no counterpart to “C:\Program Files” on a 64-bit client. You have to derive that explicitly using “%SYSDRIVE%:\Program Files”

I need a beer…

So, with Autodesk 2008 suite, it was a painful mess, but we sorted it out and got both the installation and uninstall packages working very well and consistently.  Now we’re on to building the 2010 suite.  At first things looked like they were almost completely cleaned up, but then comes Design Review 2010.  It still writes everything in 32-bit mode, so it’s files get placed under “C:\Program Files (x86)” and its registry keys under HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall.  But that’s not all.  Next comes a new set of “Language Packs” for each product (or most products, not all of them), even if you’re on an English-US platform (0409 codeset, en-us). 

The weirdness comes when you try to hotwire this mess in Wise Script and you call the AcadLP.msi installer (for example) and think you can use the TRANSFORMS=acad.mst (because that acad.mst) happens to be sitting in the same folder with the AcadLP.msi), but that doesn’t work.  You have to invoke the .MST in the parent folder, which is the same one used for the main acad.msi installation (which has to come first by the way).  So, because the .MSI and .MST are in different paths, you have to specify the full path in the TRANSFORMS= statement.  Be careful of the 256-character limit on execution statements.  Doh!

Case in point: UNC server path:

\ \ Server1\Packages\ADSK2010\ACAD2010\AdminImage\x64\acad\acad.msi TRANSFORMS=acad2010.mst /qb! /l*v %TEMP%\Acad2010.log

Ho ho ho!  AhhhhhH!!!  (sip…  Hoegaarden is very good beer.  And it’s raining outside).

Conclusion

I really don’t have a conclusion.  I don’t know where I was going with this as much as it felt like a cathartic dumping of frustration on a rainy day.

Holy crap one of my daughters is grilling bar-b-que chicken and it gets me more pumped up than a case of Red Bulls.  I’m serious.  My leg won’t stop twitching.  The smell….  where was I?  Oh yeah…

I don’t want to pick on Autodesk unilaterally here.  They have made enormous strides in the area of packaging and deployment automation.  Compared to what we had to do to “push out” AutoCAD R12 years ago, this is a dream.  Somewhat like bitching about how long it takes to microwave a can of soup, when it used to take 30 minutes on the stove years earlier.  But still, they need to know these pains from customers in order to plan ahead.  I hope they get this in the context it was intended, which isn’t that they make a bad product, or even a bad deployment tool, just that it needs a few improvements and it could be state of the art.  For example, if it could bundle all products into a single installation and do a proper job of encapsulating the entire collection of sub-processes, threads and forks, then it could effectively return a comprehensive result to an infrastructure management product like ConfigMgr or Altiris, etc.  That would be HUGE.  Almost as huge as the hunger I have right now for bbq chicken.  Gotta go.

Thanks!