Winter Scripting Games: Profiles in Perfection

Eric Payne


As part of the 2008 Winter Scripting Games the Script Center is profiling competitors who recorded a perfect score in the 2007 Scripting Games. Here, in his own words, is a little something about Eric Payne, who received a perfect score in the VBScript Advanced division.


Check out more Profiles in Perfection from the 2007 Scripting Games.

*

Eric Payne

Eric Payne

I have been working for CDW-Berbee as a Microsoft Engineer since May of 2004. My current responsibilities keep me very busy with scripting. Since most companies have far too few resources and too many servers to manage, I spend most of the day turning many daily administration tasks into scripts, thereby saving countless hours for other IT staff. I have created scripts for changing local administrator passwords; getting computer details; changing subnet masks; checking free disk space; keeping count on licenses; identifying AD service account lockouts; and many other tasks.  My specialty is customizing scripts that generate events to the Windows application event log where Microsoft Operations Manager (MOM) is configured to monitor for specific events. When these events occur MOM will send out an email to alert the administrators there is a problem. 

Check out some of my submitted scripts here: http://www.microsoft.com/technet/scriptcenter/csc/scripts/servers/mom/index.mspx.

Eric's Scripting Tips

Create and use a shell template script. A shell template script is a base script you start with that will save you time when you need to write a script quickly. Your shell script should contain commonly used subroutines and functions. Once you have a shell script created it is very quick and easy to write new scripts based on this shell script. To start, open the shell script, save it with a new name, and start coding. Your shell script should  have all of your common functions which you know already work so you can spend your time on the task at hand instead of worrying about all the specifics, like how to write to a log file, or how to handle errors.

Some things I think all scripts should do are part of my shell script:

Writing to the EventLlog. I have a small basic subroutine which writes an event to the Windows Application event log. Events I write to the event log are:

Script start up, including who\what\where.

Script completion including total time.

All soft and hard errors during script execution.

Writing events to the Application log is very handy to help troubleshoot any issues you come across. In addition, if you have Microsoft Operations Manager (MOM) it is a great way to generate alert messages.

Writing to Log Files.  This might seem obvious, but I see many scripts doing random things but not keeping track of what they are doing.  I have a complex logfile class containing many functions I typically use for log files.

CreateLog, a subroutine to create a new log file using the format ScriptName_YYYYMMDDHHMMSS.log. This subroutine first checks to see if a log file exists and, if one does (meaning a script is being run more than once per second), the subroutine will pause one second, then check again with the new time.  The log file is created in the script root path \logs folder. If the logs folder does not already exist, the sub routine will create it. It is helpful to keep all log files together with the scripts. The CreateLog sub will also add a header line to the log containing important information. Example:

==============================================================================
 MyScript.vbs was started by Eric on Eric's Computer at 10/29/2007 10:20:59 AM          
==============================================================================

Logit. Once the log file is created the class uses the logit subroutine to write text to the log. This subroutine uses three parameters: strLogMessage, bolToScreen, and bolTimeStamp.strLogMessage is what you actually want to type in the log file; bolToScreen is a Boolean option to output what you are typing to the screen; and bolTimeStamp optional adds a datetime stamp to the beginning of the line (commonly used in Microsoft log files).

CustomDateTime. A subroutine that generates the log file name’s datetime format of YYYYMMDDHHMMSS

CopyLog. Used to copy the log file (once written) to a new location. This is often a network location where others can view it.

CleanUpOldLogs. Every time you write a script which writes a file out to a hard drive you should have a routine to clean up old log files. I have seen too many times when a hard drive crashes due to old log files filling up the drive. This routine loops through the logs folder looking for any log file older than XX days and purges them.

CloseLog. A subroutine that writes out the footer of the script and close the log file. An example of the footer is this:

===================================================================
MyScript.vbs (v1.00) completed in 0:30:03                             
===================================================================

Every step of the way I try to output what the script is doing so that, later on, I can go back and get a full understanding of any issues or problems might have come up. With the header and footer information I can find out what was run, who ran it, where it was run from, what time it started, how long the script took to run, and what version of the script it was.

ErrorHandling. I like to handle all of my errors; allowing the script to just bomb with some cryptic message doesn't help very much. My error handling routine consists of writing a comment to the screen as well as the typical Err.number\source\description. This allows you to place one simple ErrorHandling line in your code anywhere you could possibly generate an error, giving you the ability to pass in an argument containing your own custom comment.

Here is the syntax:

If err <> 0 Then ErrorHandler "An Error Occurred Here",write_to_event_log,stop_script

As you can see, I check to see if an error has been generated.  If an error has been generated, the ErrorHandler routing is called and you can pass in your custom comment and optionally write an error to the event log and stop the script.

Here is an example of a typical error message I generate and write to the log file:

******************************************************************************
*** Comment: ERROR: An error occurred trying to connect to SERVER01
*** Number (Dec): -2147024891
*** Number (Hex): 80070005
*** Source: SWbemLocator
*** Description: Access is denied. 
******************************************************************************

Credentials. Rather than passing credentials in a script, create a scheduled task and configure it to run under administrator credentials.  If the administrator has access to whatever you are trying to do, the task will run under those credentials and you don't have to worry about passing in clear text passwords.


Top of pageTop of page