Mr. Script

Directing Traffic

This script can be altered to read/write any kind of Registry entry.

In most areas of IT, there are mechanisms in place that allow for the possibility of moving resources. For instance, the Domain Name System (DNS) allows for CNAME records that point to other records. Thus, you can have a generic URL, such as www.mycoolwebsite.com, that remains the same for all eternity—even though you’ve hosted the Web site on several different servers with different IP addresses over the years. Another example is ODBC Data Source Names (DSN). An application can be connected to its database by using a standard DSN. As the application evolves, the data may move from “flat file” to Access to SQL. Throughout it all, you connect via the same DSN. Nice.

While this type of generic pointing works well in many cases, there are times when you still have to manually direct traffic to other resources. Just the other day, I had to reconfigure my component reuse software to point to a different SOAP server as I moved one of my repositories from the test environment into production.

Such was the case with the reader who provided this month’s question. Brandon Roberson is a PC Technician for Cartersville Medical Center. Brandon has an internal inventory application that points to a collection server. The location of this server is stored in the local Registry of every computer where the application is installed. They’ve moved the server, and he now needs to update nearly 130 machines to point to the new server. Already off to a good start, Brandon was looking into a Kixtart script to update the pointer as part of the logon process. While this isn’t necessarily a bad approach, it does leave the status of the update up in the air, as it’s dependent upon a user logging into each machine. Let’s see…a lot of machines, we only need to change one Registry entry, the entry will be the same for all machines. What shall we do? WMI!

<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="objFSO" progid="Scripting.FileSystemObject"/>
   <script language="VBScript">
   Option Explicit
   Dim
objRegistry, clsFile
   Dim strComputer,strValue,strKeyPath,strValueName
   const HKLM = &H80000002
   Set objFile=objFSO.OpenTextFile_
    WScript.Arguments.Named("List")
   Do Until objFile.AtEndOfStream
   strComputer=objFile.ReadLine
   Set objRegistry=GetObject _
    ("winmgmts:{impersonationLevel=impersonate}!\\"_
    & strComputer & "\root\default:StdRegProv")
   strKeyPath="SOFTWARE\InventorySys\Connection"
   strValue="URLForNewServer"
   'Write the new value
   objRegistry.SetStringValue _
    HKLM, strKeyPath, strValueName, strValue
   Loop
   objFile.Close
   WScript.Quit
   </script>
  </job>
</package>

The first thing you’ll notice is that I’ve altered my color-coding scheme a bit. In the past, I’ve followed standard color-coding for .VBS scripts. For .WSF scripts, I used a combination of a standard XML editor view for the XML and the .VBS color scheme for the <script> part. Because PrimalScript opens .WSF scripts, I’ve decided to use its color-coding scheme for my scripts. It’s close enough to standard, but adds nice highlights where they count.

By utilizing WMI to remotely change the Registries of several computers, we were able to ensure that every computer using the aforementioned inventory application is now pointing to the correct server. What’s more, we received immediate confirmation that the change had taken place, rather than waiting until someone eventually logged on. When you run the script, you must pass the name of a text file containing a list of computers—one computername per line—using the named argument, List. The script then cycles through this list, connecting to each computer in turn and making the appropriate change. Of course, if I were deploying this script in a production environment, I’d include some error handling in case one or more of the computers wasn’t available when the script was run. Perhaps I’d write this information to a log file to try those machines later.

It should be obvious that the Registry key/entry I used in the script is completely fictitious. Even if Brandon had included the key/value name in his e-mail, I probably wouldn’t have used it. We wouldn’t want anyone accidentally breaking an internal application just because your company happens to use the same inventory system as Brandon’s and you accidentally ran the script on a production machine running said application, would we? Moreover, I can certainly do without the inevitable hate mail that would follow!

This script can be altered to read/write any kind of Registry entry. The WMI Standard Registry Provider (StdRegProv) has methods for reading and creating DWORD, String, Expanded String, and MultiString values. Make sure you use the correct method for the type of value you’re reading/creating. Also, make sure you heed the obligatory Don’t Ever Edit The Registry warning!

Next month, we’re going to tackle another reader question. I’m hoping that in the process of providing a solution, I can demonstrate an alternative means for viewing text files.

About the Author

Chris Brooke, MCSE, is a contributing editor for Redmond magazine and director of enterprise technology for ComponentSource. He specializes in development, integration services and network/Internet administration. Send questions or your favorite scripts to [email protected].

comments powered by Disqus
Most   Popular