Mr. Script

Fancy Filework

Applying registration keys en masse via scripting.

Our interrogation abilities become somewhat more refined as we get older. We tend to ask more intelligent questions, such as the one I received from Wilfredo Santiago: Do you know of a script that would apply three Registry keys? I have them as .REG files that I could install by putting the file on each computer and double-clicking the .REG file on each one. However, since I have to make this registry change on 30 systems, I would prefer NOT to have to be going from machine to machine running them from a floppy.

We discussed this very topic—albeit from a somewhat different perspective—in last month’s online column (www.mcpmag.com/columns/article.asp?editorialsid=718). So, in answer to Wilfredo’s question: “Why not?” Why not, indeed! After all, the Registry is huge. Demonstrating different approaches for accomplishing a variety of tasks is what makes the world go around.

In addition to taking a closer look at modifying the Registry, we’re also going to explore a different (and arguably superior) method for getting data out of text files: ActiveX Data Objects (ADO). In the past, whenever we needed to pass data to a script, we would either put it into an Excel spreadsheet and read the data using the Excel type library or put the data into a simple text file and access it using the FileSystemObject. Several times over the years I’ve attempted to impress upon you the power and versatility of the FSO. "It’s worth plodding through the object model," I’d say. "You’ll find yourself relying on it often." That remains true. However, on those occasions when we need to extract data from a text file, it makes sense to do so with a tool designed for data. Enter ADO.

Without going into a great deal of detail about how ADO connections and recordsets work, let me just say that viewing a recordset with ADO provides increased functionality and flexibility. Why, just the power to go back to the beginning of the recordset or to choose specific records is worth the price of admission. That price, by the way, is free. ADO comes with Windows—just like the FSO.

To make this point clearly, I’ve taken the script from last month and substituted ADO for the FSO. Let’s take a look at the script and then discuss some of the ways in which ADO has helped to improve it.

<package>
<comment>
ChangeRegKey.wsf
Change a registry entry
pointing to a resource
</comment>

   <job>
   <runtime>
      <named

      name="List"
      helpstring="File containing list of computers"
      type="string"
      required="true"
      />
      <description>

      This script changes a value in the registry
      </description>
      <example>

      C:\cscript ChangeRegKey.wsf /List:C:\list.txt
      </example>
   </runtime>
   <object
id="objConn" progid="ADODB.Connection" Reference/>
   <object
id="objRS" progid="ADODB.Recordset" Reference/>
      <script
language="VBScript">
      Option Explicit
      Dim
objRegistry, strList
      Dim strValue, strKeyPath, strValueName
      const HKLM = &H80000002

      objConn.Open _
         "Provider=Microsoft.Jet.OLEDB.4.0;"&
         "Data Source=C:\;" & _
         "Extended Properties=""text;HDR=YES;FMT=Delimited"""

      strList=WScript.Arguments.Named("List")
      objRS.Open "SELECT * FROM " & strList, objConn, _
         adOpenStatic, adLockOptimistic, adCmdText

      objRS.MoveFirst
      Do Until objRS.EOF
      strComputer=objRS.Fields.Item("Computer")
      Set objRegistry=GetObject _
         (
"winmgmts:{impersonationLevel=impersonate}!\\" _
         & strComputer & "\root\default:StdRegProv")
      strKeyPath = "SOFTWARE\InventorySys\Connection"
      strValueName = "ServerURL"
      'Check the current value
      objRegistry.GetStringValue _
         HKLM, strKeyPath, strValueName, strValue
      If strValue="URLForNewServer" Then
      WScript.Echo "Value already set."
      WScript.Quit
      Else
      strValue="URLForNewServer"
      'Write the new value
      objRegistry.SetStringValue _
         HKLM, strKeyPath, strValueName, strValue
      WScript.Echo "Value successfully changed."
      End If
      objRS.MoveNext
      Loop
      objRS.Close
      objConn.Close
      WScript.Quit
      </script>
   </job>
</package>

You should notice a few undeclared variables used when I opened the Recordset. These are actually constants that I avoided having to declare by setting a reference to the object (note the “reference” keyword in the <object> tag). Don’t worry about the (apparently) convoluted code in the objConn.Open line. Most of this is boilerplate. However, take note that we’ve added a header labeled Computer to our list of computers in the List file. Make sure to do this in your list, or your query will return nothing.

From a functionality standpoint, we haven’t really added a lot. The script does the same thing it did using the FSO. However, by using ADO, we’ve opened up a world of opportunity vis-à-vis scripting flexibility. Here are a few examples:

  • Because the text file we’re reading is a list of computers that the script connects to, we could put in error handling to note any failed connections and try them again before the script terminates.
  • We can create a header row if the text file contains multiple columns (such as a comma-delimited file).
  • We can use these headers to filter the results by issuing SQL-style queries: "Select * From rsList Where Completed = 'False'" (or any other criteria). With the FSO, we’d have to write custom logic to parse the entire line.
  • We can make scripts that are interchangeable with data sources.

With the FSO, you point to a file. ADO can point to a file in a connection string or point to a DSN (Data Source Name). If we were to change the script to point to a DSN, then the script could remain unchanged regardless of the data source. We discussed this “open” aspect of ODBC a bit last month.

comments powered by Disqus
Most   Popular