DOS Batch File Error Level Checking Tricks…

2012-06-27T23:01:24+00:00 June 27th, 2012|Uncategorized|

Fellow Coreteker Paul and I were chatting today about capturing post-execution error codes in Windows.  Paul was looking to grab the error code resulting from a script (VBscript, if I recall), and he was looking for the best way.  He found a handy way to handle it (pun intended); but it left me thinking about how one might capture error codes *within* a DOS batch file, and how that might be tricky.  So I tossed a few notes together and I thought I’d pass them along to you… 

First things first: the DOS post-execution error code is stored in the dynamic variable %errorlevel%

One of the important things to remember when trying to grab error codes from DOS batch files is that each executed line of the batch file will produce its own error code result, as well as the fact that you have the capability to grab the error code of the script as a whole (by issuing an EXIT /B command).  Note that one must never hard-set an error level, as you’ll break the shell’s ability to dynamically manage the variable.

 So, if you have multiple lines in your script and wish to capture the error codes from some of the lines, here are a few suggestions…

IF %ERRORLEVEL% EQU 0 SET RESULT=YUUUP

…this will grab your error code and just for fun set your %RESULT% to the now-famous trademarked “Storage Wars” catch phrase (minus the exclamation point for legal).  You’d typically run this line after the previous line from which you wanted to capture the code.  Error code of zero almost always means that it is operating as intended. 

However, to catch unintended errors in either of these cases,

IF %ERRORLEVEL% NEQ 0 SET RESULT=%ERRORLEVEL%
IF %ERRORLEVEL% EQU 1 SET RESULT=%ERRORLEVEL%

…they will both will grab the error code, check to see if it’s not equal to zero, and set the %RESULT% variable with the code it grabbed.  Note that the second line — while checking for a value of 1 — is actually checking for 1 or more; this is default behavior.

After grabbing the error code and evaluating it, you can have the script have success/failure-specific condition statements act upon the condition (send notice, add to the event log, exit, etc.).

I hope that helps!

 

How to check the VMware Tools version across your Windows Server 2008 R2 farm…

2012-06-20T22:40:00+00:00 June 20th, 2012|Uncategorized|

I was on a conference call today where someone asked if the server administration team could quickly get a “read” on the VMware Tools version across the server farm.  An ESXi upgrade was being deployed and the team wanted a quick way to see what VMs needed to catch up with the deployment.

Fortunately, I had a bunch of PowerShell snippets lying about that would fit the bill nicely.  Of course, there are a few different ways to accomplish this, depending upon which resources that you are permitted to access; but using PowerShell in a loop with a list of your server names is a quick and easy way to get it done.

So first, a little set up…  Imagine that we are inside a PowerShell script, in a foreach loop (or a function called by that loop) that is calling each computer (our Windows 2008 R2 servers) in a list.  At the time you hit this snippet of code, the current server name in the loop is in the variable $ComputerName, and the output file for the report is $outfile

 

    write "" | Out-File $outfile -append
    $vmtoolstatus = Get-WmiObject -class Win32_Product -computername $ComputerName | Where-Object {$_.Name -match "VMWare Tools"} |select Name,version
    if ("X$vmtoolstatus" -eq "X")
    {
      write "VMware Tools **NOT** found." | Out-File $outfile -append
    }
    else
    {
      write "WMware tools presence/version info:" | Out-File $outfile -append
      $vmtoolstatus | Out-File $outfile -append
    } 

 

All we’re really doing here is to query the product list for the tools, and if present report the version. And the result look something like this for each item in the loop:

WMware tools presence/version info:
Name                                                        version                                                  
----                                                        -------                                                    
VMware Tools                                                8.3.2.1593

Simple, but effective and functional. 

I hope it helps!

 

 

The Modify or Alter Column Statements, and MS SQL 2008…

2017-07-27T00:01:07+00:00 June 13th, 2012|Uncategorized|

(…with technical guidance from Avi Moskovitz…)

Recently, I needed to change the width of a column in the SQL Server portion of one of our Databases using MS Management Studio 2008.  And while this meant changing data type, you’d think it would be as easy as simply changing the properties within the table in the same manner that you can within Access 2010; normally, less than one minute to get ‘er done.  And in organizations where it is permissible to un-check the “Prevent saving changes that require table re-creation” on production systems, this might well be the case  (as in the graphic below).

 

The "Prevent saving changes that require table re-creation" option

The "Prevent saving changes that require table re-creation" option

 

But, in my situation, I had to find another route; this was going to require scripting…

1 – A Wild Goose Chase

A few quick searches of things like, “How do you change the width of a column in SQL”, and the results put a big grin across my face — I found reference to a MODIFY statement with an example of a column width change:

ALTER TABLE my_table MODIFY this_column VARCHAR2(50);

My problem was solved!  Or, so I thought.  After trying a few times and getting error messages, I almost started to suspect a conspiracy — or at least a concerted effort was in place to confuse and befuddle…

Luckily, Coretek is staffed with experts on a wide variety of software and hardware platforms.  I reached out to our resident SQL guru, Avi Moskovitz, who informed me the “solution” I found referencing the  MODIFY statement WAS accurate – if used in an Oracle environment – but MS SQL 2008 does not support it. 

2 – Drastic, Dangerous, but Legitimate

One possible option is to create a new column and delete the old column; something you should not be in a hurry to do if you have data in the column as you need to think about how the data will be repopulated within the column (will it affect links, relationships, etc., or will it be truncated or corrupted?).  I have found that creating a new column in the SQL backend (with the correct parameters) and then going to the front end (if you happen to have something like an Access front-end) to copy the information from the old column and pasting into the new column will work; but beware of deleting a key or a linked field. 

3 – More Drastic, Less Desirable

Another, more drastic and less desirable option is to re-create the entire table in the SQL backend with the correct parameters.  This is a multi-step process that, depending on the size of the table, can take 5 to 30 minutes (or more, if there are hiccups along the way).  In doing this, you are effectively manually re-creating what SQL does when changing a data type for a field.  Not necessarily recommended, but I am keeping these steps provided by Avi in case I ever need them:

  1. Create a temporary table which will host your data (let’s call it MyTempTable).
  2. Copy the data from the original table (MyFirstTable) to MyTempTable, making sure that you set Identity_Insert “ON” so that it keeps the Key Field intact when the data gets copied in.
  3. Delete MyFirstTable. 
  4. Recreate the original table (a duplicate if you will of MyFirstTable…MySecondTable)
  5. Copy the data from the MyTempTable to the New MySecondTable making sure that you set Identity_Insert “ON” so that it keeps the Key Field intact when the data gets copied in.

4 – There’s a Right Way

But perhaps the best way of all, is to use a variant of the first thing mentioned above, correctly formatted for MS SQL 2008 with ALTER COLUMN instead of MODIFY, as follows:

 ALTER TABLE my_table ALTER COLUMN this_column NVARCHAR(50);

Execute this command into the query analyzer, and in an instant the problem is solved; the data type is changed (as in the graphic below)! 

SQL ALTER COLUMN Command - Successful!

SQL ALTER COLUMN Command – Successful!

Fortunately, the query analyzer will fail to execute if it detect data that does not fit the new type.  So what’s the lesson?  Internet searches are not a fool-proof way to explore scripting options; without the experience to understand the ramifications, the options can sometimes do as much harm as good…

 

Thinking Outside The Bundle…

2017-07-27T00:01:07+00:00 June 6th, 2012|Uncategorized|

Once you’ve honed your packaging skills, and created some cool application bundles; you’re not done yet.
 
Having a great bundle installation without the ability to cleanly remove that bundle is like having a powerful engine in a motorcycle… with no brakes.  Oh sure; it’s great as long as you’re going forward, but if you need to stop and make changes (for example, if you have to change enterprise mail system clients), you just might have no choice but to re-image every motorcycle.  Okay, that’s where the metaphor breaks down a bit, but you get my point.
 
Anyway, here are a couple issues that I see as important that — if left unattended — could really grow into larger problems.
 
The bundle “Uninstall” – one should put as much effort in testing and implementing “best practices” for the bundle UNinstall as we do for the install.  By default, a bundle’s uninstall actions are simply the Install actions in reverse; this is OK for simple bundles, like a bundle that installs only one .MSI.  However, many bundles are more complex.  Ensuring your bundle uninstalls without error is also important.
 
I disable the default “Uninstall” action for most of my bundles and add custom uninstall actions to avoid errors, especially for bundles that install dependent bundles (I generally leave dependent bundles installed).  This leads me to…
 
Dependent bundles – I think most packagers are aware that it is a best practice to determine an application’s dependencies and, whenever possible, bundle the dependencies as standalone bundles to allow the software deployment/management system (for example, ZCM) to manage them.  This will reduce errors when an application attempts to install a package that is already installed or uninstall a shared dependency; it also saves time.
 
If you keep these things in mind, you can get on your bad motorbundle and ride…  and stop when you want…
🙂