Scripting Host File Changes
The Windows host file is both a powerful tool and a pain in the posterior. It's powerful because you can do so much with it. Build a poor man's site filter, create shortcuts to local resources, that sort of thing. It's a pain because Windows doesn't want you to edit it. If you've ever done so, then you know the hoops you have to jump through because Windows wants to protect you from dangerous changes to system files. How kind of them.
That said, I have a server, let's call it "server1", that is essential to my work process. Sadly, the address by which I need to reach it changes depending upon why I need it, and where I'm sitting. I've been manually changing the hosts setting for it for a few weeks, but that finally got old and I decided I needed to script that puppy.
I have batch files I use when making the environmental changes necessary for each of my varied tasks. I can now insert a line into them that calls a VBS script to make the host changes I need. I can pass a variable to indicate which setting I need to change. Here is the script in it's entirety.
First, lets assume you have a hosts file that looks something like this:
#192.168.1.1 server1
# Server1 public address
256.2.2.2 server1
Your goal with this script is to toggle between the two possible value for this mapping..
The first thing I do is parse the arguments I pass it. For reasons that will make more sense in a moment, I can have either one or two. For purposes of the posting, let's assume I'm passing:
ToggleServer1.vbs enable
The second one is wrapped in an IF clause to avoid an out-of-bound error.
Set args = WScript.Arguments
arg1 = args.Item(0) 'the parameter from batch comes in here to arg1
If WScript.Arguments.length > 1 Then
arg2 = args.Item(1) 'the parameter from admin mode is set here
End If
As noted above, the host file is protected, so you need to be in "Administrative" mode to edit. This section checks to see if you have one argument or two. If one, as you would at the start, it adds another one (to keep you from looping through here forever) and then recursively (once) calls this same script, but running as an admin.
Set WshShell = WScript.CreateObject("WScript.Shell")
If WScript.Arguments.length = 1 Then
Set ObjShell = CreateObject("Shell.Application")
ObjShell.ShellExecute "wscript.exe", """" & _
WScript.ScriptFullName & """" &_
" " & arg1 & " RunAsAdministrator", , "runas", 1
Wscript.Quit
End If
This section does exactly what the comment says.
Const ForReading = 1, ForWriting = 2, ForAppending = 8, ReadOnly = 1
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell=CreateObject("WScript.Shell")
WinDir =WshShell.ExpandEnvironmentStrings("%WinDir%")
HostsFile = WinDir & "\System32\Drivers\etc\hosts"
These variables correspond to commented and uncommented versions of the host mapping for the two possible addresses.
LocalOn = "192.168.1.1 server1"
LocalOff = "#192.168.1.1 server1"
RemoteOn = "256.2.2.2 server1"
RemoteOff = "#256.2.2.2 server1"
This part opens the current host file and reads the whole thing into a string variable.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(HostsFile, ForReading)
'Adds all text in text file to "FileContent" string
FileContents = objFile.ReadAll
objFile.Close
This section reads the argument you passed and replaces strings as appropriate. Note the part where check to make sure the "Off" (uncommented) strings are not already present before adding them. They shouldn't but I'm paranoid and I can imagine a scenario where the states get of sync. This just prevent something like a double-comment, which would then forever leave that line commented.
'"enable" means enable localIP, disable remote mapping
If arg1 = "enable" then
'Toggle to RemoteOff and LocalOn
NewContents = Replace(FileContents, LocalOff, LocalOn)
If Instr(FileContents,RemoteOff) = 0 then
NewContents = Replace(NewContents, RemoteOn, RemoteOff)
End If
End If
'make second statemnt independent, in case they get out of sync
If arg1 = "disable" then
'Toggle to LocalOff and RemoteOn
If Instr(FileContents,LocalOff) = 0 then
NewContents = Replace(FileContents, LocalOn, LocalOff)
End If
NewContents = Replace(NewContents, RemoteOff, RemoteOn)
End If
If arg1 <> "disable" AND arg1 <> "enable" Then
NewContents = FileContents
End If
That thing above is another bit of paranoia. If you got this far with the wrong argument sent, it would otherwise blank out your host file.
Finally, you write the full contents of your changes into the host file, replacing the previous values.
Set objFile = objFSO.OpenTextFile(HostsFile, ForWriting)
objFile.WriteLine NewContents
objFile.Close
result=Msgbox("Server set to "&arg1&".",0, "Process Complete!")
WScript.Quit
Hope that works for you!