Mr. Script
Directing Traffic
This script can be altered to read/write any kind of Registry entry.
- By Chris Brooke
- 06/01/2004
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].