Automated ZEN Imaging: The Next Step
Novell Cool Solutions: Trench
By Jim Shank
Reader Rating
from 21 ratings
|
Digg This -
Slashdot This
Posted: 3 Apr 2003 |
Here's an exceptionally detailed explanation of how to deploy Windows 2000 to workstations and get them up and running on the desktops of the employees in a hurry. Jim Shank takes you through the entire process he developed at his company, and along the way offers excellent insight into how to use many different tools and bits of information to create a unique solution. (Which is, after all, our our whole raison d'etre here at Cool Solutions.) Thanks, Jim!
Update: We've added all the files Jim shared in this solution to a zip file for your convenience, so the line breaks on this page don't drive you mad. See the Files section.
Introduction
Like many of you, I work for a medium-size organization using ZENworks imaging in order to deploy stock workstations to our employees. I wanted to be able to deploy a Windows 2000 PC with Novell Client to the desktop without needing to revisit it for any additional configuration. In fact, if it weren't for the need to set the PC to boot from the NIC and put the asset tag in BIOS, I could have the systems shipped directly to the location. The goal was to create an image that when deployed would have the following abilities:
- Automatically join the local domain
- Automatically name itself (something identifiable)
- Support changes within the post image scripting without requiring a re-image
- Update ZIS and create a workstation object
I started this process reviewing the excellent article Getting ZEN Imaging to work with SYSPREP by Michael J. Prentice. I used his steps to begin the process but along the way, realized that batch scripting, without enhancements, was not going to get me far enough. I needed a scripting platform with maximum flexibility with minimum additional software installation. After reviewing KiXtart, Perl for Windows and VBScript, I settled on VBScript as my automation language of choice. The main benefit being that it runs natively without any additional software installs and gives quick and dirty access to the file system and registry. Without further introduction, let's look at the imaging process outline (that's your cue to print this out, get a drink and come back. Then use the printout of the files to compare to the process outlined next):
Imaging Process
- The workstation is received; first thing we do is place an asset tag on the system and boot to BIOS. Set the boot order to NIC 1st and then enter the asset tag in the BIOS in the System ID's section (we use Compaq Evo slim lines). The PC is then warehoused or immediately deployed to the employee's desktop.
- Once deployed, the PC is booted for the first time. ZENworks policies determine that the box doesn't have a workstation object and therefore, begins the imaging process.
- The image is received and the machine automatically reboots.
- Sysprep runs in fully automatic configuration mode.
- Sysprep checks for different hardware than the base image and locates the drivers in the OemPNPDriversPath and adds any new hardware to the system.
- Sysprep licenses the product.
- Sysprep does basic network configuration including activating DHCP and joining the Imaging Workgroup (we will join the domain later).
- Sysprep names the machine AURORA-xxxxxxx where xxxxxxx is a randomly generated string by Sysprep. The aurora comes from the first word in the OrgName title in sysprep.inf.
- Sysprep sets up Autologin so we can do fully automated post imaging scripting.
- Sysprep sets the runonce key to run 1strun.vbs on the first full boot (after Sysprep).
- The machine reboots and performs 1strun.vbs.
- 1strun.vbs logs to the event log that the post imaging scripting has started.
- 1strun.vbs logs to the event log that 1strun.vbs has started.
- 1strun.vbs puts ziswin.exe back into the registry so that it will run on the next boot, it is removed directly prior to imaging the system so that it doesn't interfere with Sysprep.
- 1strun.vbs removes the desktop update component so that we can update the desktop information stamp at will instead of on each run (this will be covered in a future article).
- 1strun.vbs sets the runonce key to run 2ndrun.vbs on the next boot.
- 1strun.vbs removes the desktop to show that we are in an automated imaging environment, this also acts as a failsafe should imaging fail, it would be extremely obvious when the desktop is missing.
- 1strun.vbs checks for the existence of c:\sysinfo\debug.txt, I can include this file in the image if I want to pause for debugging. Nice if you want to see what has happened and adjust the timing of events during testing.
- 1strun.vbs logs to the event log that 1strun.vbs has completed.
- 1strun.vbs uses ncshtdwn to reboot the system (more info on ncshtdwn later).
- The machine reboots and performs 2ndrun.vbs.
- 2ndrun.vbs logs to the event log that 2ndrun.vbs has started.
- 2ndrun.vbs clears out the current domain name so that there is no error on reboot (from Michael J. Prentice's article).
- 2ndrun.vbs determines the current name of the machine by reading from registry.
- 2ndrun.vbs uses some logic to determine if the machine has had its name corrected or not. In Sysprep, we use the auto naming system which allows Sysprep to generate a random name with a fixed prefix. By testing for this prefix, we are able to determine if the machine has been named or not. Most of this logic is designed so that this scripting can be run if a machine has recovered its information from ZIS. A feature that I haven't gotten working yet.
- 2ndrun.vbs reads in from WMI which is the interface for accessing BIOS information from the OS, this is some of the real magic.
- 2ndrun.vbs then checks the asset tag to verify it has been properly entered and formatted correctly. If not, we preset the (hopefully) desktop tech with the ability to manually correct the name and then fix it in BIOS and log the event to the event log. If it is named correctly we use ENGL Zcnc Lite to:
- Name the machine from the BIOS asset tag.
- Remove the ZENwsimport record from the hosts file (more on this later).
- Force the change and do it without prompting.
- 2ndrun.vbs sets the runonce key to run 3rdrun.vbs on the next boot.
- 2ndrun.vbs checks for the existence of c:\sysinfo\debug.txt, once again, for debugging purposes and pauses if found.
- 2ndrun.vbs logs to the event log that 2ndrun.vbs has completed.
- 2ndrun.vbs uses ncshtdwn to reboot the system.
- The machine reboots and performs 3rdrun.vbs. This is the meat of the post imaging process and as such, I decided to throw in a control that allows me to put up a progress bar and message. This utility is a hack for VBScript that allows you to show dialog boxes while your script runs, it's not necessary but provides that ?wow? factor many of us thrive on. As it is not necessary, I will not comment on it directly, you may use the in-line commenting included with the files and determine if you want it in your scripts.
- 3rdrun.vbs uses netdom to join the domain; this utility is included in the Windows 2000 support tools. Netdom was updated in SP3 and can be found here.
- 3rdrun.vbs uses the return code generated by netdom to determine if we were successful or not, if so, we log to the event log that we successfully joined the domain. As an added benefit, I have found that if you use netdom to rejoin a domain it will not create the dreaded trust relationship broken error that is often a result of joining a domain in which the workstation is already listed. If there was an error, 3rdrun.vbs will log the error code to the event log and then preset us with a dialog requesting that we join the domain manually and then click ok on our message box.
- 3rdrun.vbs will check once again to see if we are in debug mode and, if so, tell us what the result code was of running netdom.
- 3rdrun.vbs then implements a fix for the auto admin logon process (from Michael J. Prentice's article).
- 3rdrun.vbs locks down the c:\winnt\zmg directory so that only administrators can read it. Since we have stored the password in plain text to join the domain, we don't want users snooping around in this directory (from Michael J. Prentice's's article).
- 3rdrun.vbs updates the service pack source path in registry. Oddly enough, when Sysprep is run, the path to where the slipstreamed service pack files are stored is reset to the CDROM drive. This can be repaired by updating the registry value.
- 3rdrun.vbs runs another script, locationprofiletz.vbs. This script is responsible for managing location specific information on the system. It is based on determining the users IP address and then comparing it to an array to find out what location it is in. It then updates the time zone information and applies the correct wallpaper for the location. I have also incorporated some code to remove IPX in our pure IP offices. I will include the entire file later on.
- 3rdrun.vbs updates the profiles path in the registry. In a previous attempt to move the profiles directory to the users home drive, I found out that the mapping doesn't happen until after the OS needs access to create the profiles directory. I left this key in so that I could update it should a solution ever be found.
- 3rdrun.vbs uses vidchng.exe to set the desktop resolution and depth to our corporate standard. I found this jewel on appdeploy.com, written by Tony Pombo. It can be found here.
- 3rdrun.vbs updates the desktop information stamp (a future article).
- 3rdrun.vbs puts the desktop information stamp utility back in startup.
- 3rdrun.vbs re-enables the desktop so that we have a visual queue that the imaging process completed running all the login scripts.
- 3rdrun.vbs checks for the existence of c:\sysinfo\debug.txt, once again, for debugging purposes and pauses if found.
- 3rdrun.vbs logs to the event log that 3rdrun.vbs has completed.
- 3rdrun.vbs logs to the event log that the post imaging scripting has completed.
- 3rdrun.vbs uses ncshtdwn to reboot the system.
If you have made it this far, congratulations, that was the bulk of what happens. Next we will review the preparation work that goes into getting your image ready for this process. You might think it strange to put the prep work after the actual imaging but I thought it would make more sense to see why you need it. Here are the few changes that need to be made before imaging.
Preparation Work
- Remove HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\System\ziswin.exe from the registry. Use the ZISWIN switches and functionality article listed in the tools section.
- In the hosts file, add ZENwsimport to the line that resolves localhost. This will keep the workstation from creating a workstation object until we are done changing the name. This line is eventually removed by zcnc lite. (e.g. 127.0.0.1 localhost ZENwsimport)
- Run Sysprep with the Sysprep.inf options shown below.
Tools and Resources
There are quite a few tools and articles on how to use them that are included in this process. Here is a list of everything you need and where it is from. (Includes articles that I found useful in learning these tools.)
- Getting ZEN Imaging to work with SYSPREP by Michael J. Prentice
- ZISWIN switches and functionality
- ENGL ZCNC Lite by Heath Upton
- NCSHTDWN
- Microsoft's NETDOM from Windows 2000 Support Tools
- Video Resolution Changer 1.0 by Tony Pombo
Personal disclaimer
I have tried to give credit to the sources of the code and utilities used within this program. If there is anyone I have missed, please contact me directly and I will gladly add credit or remove the reference to your utility/code upon request. All information contained in this document is expressed by Jim Shank and does not implicitly or explicitly represent official positions and policies of Aurora Loan Services.
This information is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
Files
NEW: Here are all the files in one zip file, for your convenience.
sysprep.inf file
;SetupMgrTag
[Unattended]
DriverSigningPolicy=Ignore
OemSkipEula=Yes
OemPNPDriversPath=\Compaq\NIC;\Compaq\video;\
Compaq\WBEM;\Compaq\Audio;\Compaq\eak\drv2k;\
Compaq\misc1;\Compaq\Misc4;\Compaq\Misc3;\
Compaq\Misc5;\Compaq\SP21181\SMAXWDM\W2K_XP\;\
Compaq\O2Micro\Win2K
[GuiUnattended]
AdminPassword=verysecurepassword
AutoLogon = Yes
AutoLogonCount = 3
OemSkipWelcome=1
OEMSkipRegional=1
OEMDuplicatorstring="My Image 2.0 1/27/03"
TimeZone=010
[UserData]
FullName="Aurora User"
ComputerName=*
OrgName=Aurora Company
productid=XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
[TapiLocation]
CountryCode=1
[RegionalSettings]
LanguageGroup=1
Language=00000409
[Identification]
JoinWorkgroup=Imaging
[Networking]
InstallDefaultComponents=Yes
[GUIRunOnce]
Command0="c:\winnt\zmg\1strun.vbs"
[SysprepCleanup]
1strun.vbs
'1strun.vbs
'Written by Jim Shank 1/28/03
Option Explicit
Dim WshShell, oFso
Set WshShell=Wscript.CreateObject("Wscript.shell")
Set oFso = CreateObject("Scripting.FileSystemObject")
WshShell.LogEvent 0, "Post imaging scripting started"
WshShell.LogEvent 0, WScript.ScriptName & " started"
WshShell.RegWrite "HKLM\SOFTWARE\Microsoft\Windows NT\
CurrentVersion\Winlogon\System","ziswin.exe"
WshShell.RegDelete "HKEY_LOCAL_MACHINE\SOFTWARE\
Microsoft\Windows\CurrentVersion\Run\ALSUpdate"
WshShell.RegWrite "HKCU\Software\Microsoft\Windows\
CurrentVersion\Runonce\2run","c:\winnt\zmg\2ndrun.vbs"
WshShell.RegWrite "HKLM\Software\Microsoft\Windows\
CurrentVersion\Policies\Explorer\NoDesktop",1,"REG_DWORD"
if (oFso.FileExists("C:\sysinfo\debug.txt")) then
WshShell.LogEvent 4, "Entering debug mode scripting"
msgbox "Pausing for debug"
end if
WshShell.LogEvent 0, WScript.ScriptName & " completed successfully"
WshShell.Run "c:\winnt\zmg\ncshtdwn.exe /7"
2ndrun.vbs
'The purpose of this script is to
determine if the machine has had ZIS recovered on it
yet, and if not,
'run zcnc, recover the asset tag from BIOS
and name the machine.
Added the rest of 2ndrun.bat so we can
'internally handle the timing.
'Written by Jim Shank 1/28/03
Option Explicit
Dim WshShell, current_name, oFso, bios,
SystemAT,oWMI
Set WshShell=Wscript.CreateObject
("Wscript.shell")
Set oFso = CreateObject
("Scripting.FileSystemObject")
WshShell.LogEvent 0,
WScript.ScriptName & " started"
'Clear out the current domain name
so that there is no error on reboot
WshShell.RegWrite
"HKLM\SOFTWARE\Microsoft\Windows NT\
CurrentVersion\Winlogon\DefaultDomainName",""
'Find out the current name of
the machine on the next line
current_name = WshShell.RegRead
("HKLM\SYSTEM\CurrentControlSet\
Control\ComputerName\
ActiveComputerName\ComputerName")
'If the machine hasn't been ZISed,
it will read Aurora-<random characters>,
otherwise it will have ALS as the
'beginning of the asset tag.
if left(current_name,3) <> "ALS" then
' This logic will check
before we set the machine name from
BIOS that the machine name
actually is in BIOS
Set oWMI = GetObject("winmgmts:")
For Each bios In oWMI.InstancesOf
("Win32_SystemEnclosure")
SystemAT = bios.SMBIOSAssetTag
Next
if left(SystemAT,3) <> "ALS" then
WshShell.LogEvent 1,
"Malformed BIOS asset tag:
" & SystemAT & ".
Enabling manual machine name
dialog."
msgbox "This workstation does
not have the correctly formed
asset tag defined in BIOS,
you must manually name this PC.
Please call x2600 or 000-555-1212
for assistance. If you are with
PC Support click OK to continue
and rename the PC to the
asset tag.",vbOKOnly,"Critical
Imaging Error"
WshShell.Run "c:\winnt\zmg\Zcnc.exe
/remZEN /m:cccnnnn",7
else
WshShell.Run chr(34) &
"c:\winnt\zmg\Zcnc.exe"
& chr(34) & "
/q /remZEN /forcerun
/wmi:" & chr(34) &
"Win32_SystemEnclosure,
SMBIOSAssetTag" & chr(34)
& " /sn:"
& chr(34) & chr(34),7
WshShell.LogEvent 0,
"ZCNC Rename completed"
end if
end if
WshShell.RegWrite
"HKCU\Software\Microsoft\Windows\CurrentVersion\
Runonce\3run",
"c:\winnt\zmg\3rdrun.vbs"
if (oFso.FileExists("C:\sysinfo\debug.txt")) then
msgbox "Pausing for debug"
end if
WshShell.LogEvent 0,
WScript.ScriptName & " completed successfully"
WshShell.Run "c:\winnt\zmg\ncshtdwn.exe /7"
3rdrun.vbs
' ALS Imaging Script with progress
' Written by Jim Shank
' 1/29/03
Option Explicit
Dim WshShell, i, oFso, returncode
Set WshShell=Wscript.CreateObject("Wscript.shell")
Set oFso = CreateObject("Scripting.FileSystemObject")
Dim oNMD : Call Instantiate(oNMD,
"wshLtWtNonModalDialog.ucNMD", "oNMD_") ' as Object
' --- module level variables ---------------------
Dim m_btnStartID ' as integer
Dim m_btnCancelID ' as integer
'
Dim bCloseFlag ' t/f if user closed the form...
Dim bStartClick, bCancelClick ' as boolean
Dim iSetPoint, pctDone
Dim m_MSTitles(10), m_MSRemark(10)
'
' --- constant declarations ----------------------
Const sDlgCaption = "ALS Post-imaging Scripting"
' --- end of declarations and constants ----------
' ================================================
' === MAIN LINE SCRIPT LOGIC =====================
' ================================================
WshShell.LogEvent 0, WScript.ScriptName & " started"
' Create the Form, and add the controls...
Call Create_Form(sDlgCaption)
oNMD.AddLine "Beginning post imaging
configuration " ' space
oNMD.AddLine "Process Initiated"
oNMD.PctComplete 5 ' advance progbar
oNMD.AddLine "Joining the domain..."
' Joins the domain
returncode = WshShell.Run
("c:\winnt\zmg\netdom.exe join
%computername% /Domain:ALS-TREE /UserD:
secureaccount
/PasswordD:securepassword",7,TRUE)
if returncode = 0 then
WshShell.LogEvent 4, "Netdom successfully
joined the domain"
end if
if returncode <> 0 then
WshShell.LogEvent 1, "Netdom was unable to
join the domain.
Error code was: " & returncode
wshshell.popup "Unable to join the domain!!!
The netdom join command failed. You
will need to manually join the domain now.
When you are finished, click ok on this box.
If you have any
questions about this error, please contact
the help desk.",,"Critical
Imaging Error", 0 + 16
end if
if (oFso.FileExists("C:\sysinfo\debug.txt")) then
msgbox "Netdom return code " & returncode
end if
oNMD.AddLine "Updating Auto-Admin Logon..."
oNMD.PctComplete 40 ' advance progbar
' ###Implements a fix for the Auto Admin Login count
bug and stop the Auto Admin Login.###
WshShell.RegWrite
"HKLM\SOFTWARE\Microsoft\Windows NT\
CurrentVersion\Winlogon\AutoAdminLogon","0"
WshShell.RegWrite
"HKLM\SOFTWARE\Microsoft\Windows NT\
CurrentVersion\Winlogon\DefaultUserName",""
WshShell.RegWrite
"HKLM\SOFTWARE\Microsoft\Windows NT\
CurrentVersion\Winlogon\DefaultPassword",""
WshShell.RegWrite
"HKLM\SOFTWARE\Microsoft\Windows NT\
CurrentVersion\Winlogon\DefaultDomainName",""
oNMD.PctComplete 55
' Lockdown the ZMG directory
oNMD.AddLine "Updating security..."
WshShell.Run
"cmd /c " & chr(34) & "echo y|cacls c:\winnt\
zmg /t /g BUILTIN\Administrators:F" & chr(34),7
WshShell.Run
"cmd /c " & chr(34) & "echo y|cacls c:\winnt\
zmg /t /e /g " & chr(34)
& "NT Authority" & chr(34) & "\
System:F" & chr(34) & "&&",7
oNMD.PctComplete 60
' Fix Service Pack Source Path Key
oNMD.AddLine "Fixing
Service Pack Source Path..."
WshShell.RegWrite
"HKLM\SOFTWARE\Microsoft\Windows\
CurrentVersion\Setup\SourcePath","c:\"
WshShell.RegWrite
"HKLM\SOFTWARE\Microsoft\Windows\
CurrentVersion\Setup\ServicePackSourcePath","c:\"
oNMD.PctComplete 65
' Update Location Profile
oNMD.AddLine "Updating
Location Profile..."
WshShell.Run "c:\sysinfo\
locationtzprofile.vbs",7
oNMD.PctComplete 70
' Update Profile Path
oNMD.AddLine "Updating profile path..."
WshShell.RegWrite
"HKLM\SOFTWARE\Microsoft\
Windows NT\CurrentVersion\
ProfileList\ProfilesDirectory","
%systemdrive%\Documents and Settings",
"REG_EXPAND_SZ"
oNMD.PctComplete 75
'Apply Corporate display standards
oNMD.AddLine "Applying Corporate
display standards..."
WshShell.Run "c:\sysinfo\vidchng
-q 1024x768x32@75",7
oNMD.PctComplete 80
' Apply Corporate desktop
oNMD.AddLine "Applying Corporate
desktop..."
WScript.Sleep 3000
WshShell.Run "c:\sysinfo\
CorpDT.vbs",7,TRUE
oNMD.PctComplete 85
oNMD.AddLine "Re-enabling
CorpDT Autorun..."
WshShell.RegWrite
"HKLM\SOFTWARE\Microsoft\Windows\
CurrentVersion\Run\ALSUpdate",
"C:\sysinfo\CorpDT.vbs"
oNMD.PctComplete 90
oNMD.AddLine
"Re-enabling Desktop..."
WshShell.RegWrite
"HKLM\Software\Microsoft\Windows\
CurrentVersion\Policies\
Explorer\NoDesktop",0,"REG_DWORD"
oNMD.PctComplete 95
oNMD.AddLine "Completed
Successfully"
oNMD.PctComplete 100
if (oFso.FileExists
("C:\sysinfo\debug.txt")) then
msgbox "Pausing for debug"
end if
oNMD.ShowDialog False
' clean up oNMD...
oNMD.UnloadDialog
set oNMD = Nothing
WshShell.LogEvent 0,
WScript.ScriptName & "
completed successfully"
WshShell.LogEvent 0,
"Post imaging scripting completed"
WshShell.Run
"c:\winnt\zmg\ncshtdwn.exe /7"
WScript.Quit '
end of script
' ================================================
' === SUBROUTINES FOLLOW =========================
' ================================================
' --- this code creates the form and adds the controls ---
Sub Create_Form(sCaption)
Dim wdForm, htForm, wdBtn, htBtn, wdBtnSp ' as long
Const sLBLabel = "Configuring System"
' do some geometry calculations...
wdForm = 460 : htForm = 320 :
wdBtn = 100 : htBtn = 25
wdBtnSp = Int((wdForm - wdBtn)
/ 2) - 3
oNMD.CreateDialog sCaption,
80,100, wdForm,htForm
oNMD.MinMaxBtns = False '
hide the min/max buttons
oNMD.AddLabel sLBLabel,
20,10, 300,20
oNMD.AddLstBox 20,30,
400,170
oNMD.AddProgressBar 40,
205, 360,20
oNMD.ShowDialog True
End Sub
' --- INSTANTIATE ACTX OBJECT (or class) AND CHECK ----
' (using a sub to get this ugly instantiation code
out of main line code)...
Sub Instantiate (oObject, sProgramID,
sEventPrefix)
Const sME = "[sub Instantiate], "
' check variant sub-type
parameters...
BugAssert (VarType(sProgramID) =
vbString), sME &
"sProgramID must be a STRING!"
BugAssert (VarType(sEventPrefix) =
vbString), sME &
"sEventPrefix must be a STRING!"
On Error Resume Next ' turn on
error checking
Set oObject = WScript.CreateObject
(sProgramID, sEventPrefix)
BugAssert (err.number = 0), sME
& "This script requires: "
& sProgramID & vbCrlf _
& " kindly INSTALL and
REGISTER this ActX component... "
On Error goto 0 ' turn off
error checking...
End Sub
' --- BUGASSERT (yes, it's for debugging) --------
Sub BugAssert (bTest, sErrMsg)
' BugAssert is a Bruce McKinney
creation.
' It is used to test for
intermediate results...
if bTest then Exit Sub
MsgBox "Error Detected by
BugAssert: " & vbCr & vbCr & sErrMsg, _
vbCritical, "
<< BugAssert FAILED >> "
WScript.Quit
End Sub
locationprofiletz.vbs
I have edited this file specifically for this document to remove specific information about my company's infrastructure. As such, you should debug this code since I have not tested it since editing it.
' LocationProfileTZ.vbs - Utility to determine the
IP address and set timezone, desktop logo, removed IPX if in ROC,
' and set Import Server key for SBF.
' Last update 2/25/03 by JShank
Option Explicit
' On Error Resume Next
Dim IP_Address : IP_Address = GetIP() ' Let's get
the first IP address on the system
Dim filesys,wshShell,bfsrange,alsrange,arr_midip,midip,
compip,desktop,parange,pacifictz,mountaintz,centraltz,
easterntz,pacificoffset,mountainoffset,centraloffset,
easternoffset,comprange,rocrange' Dim all of our variables
Set filesys = CreateObject("Scripting.FileSystemObject")
Set wshShell = CreateObject("WScript.Shell")
'We have to define our IP subnets for workstations
in our locations. Since we only care about the 2nd and 3rd
'octet, thats all we specify and compare.
? I have removed the arrays that go here because they would
represent a security risk to our company's
network and replaced them with
? ficticious ranges.
parange = Array ("2.10","2.11","2.12")
pacifictz = Array ()
mountaintz = Array ()
centraltz = Array ()
easterntz = Array (parange)
rocrange = Array (parange)
pacificoffset = 480 ' -8 from GMT = 8 hours x 60 minutes = 480
mountainoffset = 420 ' -7 from GMT = 7 hours x 60 minutes = 420
centraloffset = 360 ' -6 from GMT = 6 hours x 60 minutes = 360
easternoffset = 300 ' -5 from GMT = 5 hours x 60 minutes = 300
arr_midip = Split(IP_Address, ".") ' Breaking up the IP
address so we can look at the middle octets
midip = arr_midip(1) & "." & arr_midip(2) ' Recompose
the 2nd & 3rd octets
'Here is the logic for changing the timezone
For Each comprange in pacifictz
For Each compip in comprange
if compip = midip then
'If they are in the
Pacific timezone
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
ActiveTimeBias",pacificoffset,"REG_DWORD"
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\Bias",
pacificoffset,"REG_DWORD"
WshShell.RegWrite "HKLM\SYSTEM\
CurrentControlSet\
Control\TimeZoneInformation\
StandardName","Pacific Standard Time"
WshShell.RegWrite "HKLM\SYSTEM\
CurrentControlSet\
Control\TimeZoneInformation\
DaylightName","
Pacific Daylight Time"
WshShell.LogEvent 4,"IP Detected:
" & IP_Address & ".
Set for Pacific TimeZone"
end if
Next
Next
For Each comprange in mountaintz
For Each compip in comprange
if compip = midip then
'If they are in the
Mountain timezone
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
ActiveTimeBias",mountainoffset,"REG_DWORD"
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
Bias",mountainoffset,"REG_DWORD"
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
StandardName",
"Mountain Standard Time"
WshShell.RegWrite "HKLM\SYSTEM\
CurrentControlSet\
Control\TimeZoneInformation\
DaylightName",
"Mountain Daylight Time"
WshShell.LogEvent 4,"IP Detected:
" & IP_Address & ".
Set for Mountain TimeZone"
end if
Next
Next
For Each comprange in centraltz
For Each compip in comprange
if compip = midip then
'If they are in the Central timezone
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
ActiveTimeBias",centraloffset,"REG_DWORD"
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
Bias",centraloffset,"REG_DWORD"
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
StandardName","Central Standard Time"
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
DaylightName","Central Daylight Time"
WshShell.LogEvent 4,"IP Detected:
" & IP_Address & ".
Set for Central TimeZone"
end if
Next
Next
For Each comprange in easterntz
For Each compip in comprange
if compip = midip then
'If they are in the
Eastern timezone
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\Control\
TimeZoneInformation\ActiveTimeBias",easternoffset,"REG_DWORD"
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\Bias",
easternoffset,"REG_DWORD"
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
StandardName","Eastern Standard Time"
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\
Control\TimeZoneInformation\
DaylightName","Eastern Daylight Time"
WshShell.LogEvent 4,"IP Detected:
" & IP_Address & ".
Set for Eastern TimeZone"
end if
Next
Next
For Each compip in bfsrange
if compip = midip then
'If they are in BFS
set desktop = filesys.GetFile
("c:\sysinfo\Desktop.bmp")
desktop.attributes = 0
' Set this to read/write since
it can be set to read only on the image
filesys.CopyFile
"C:\sysinfo\BFSDesktop.bmp",desktop,1
' Copy the BFS image to desktop.bmp
wshShell.Run("c:\sysinfo\bginfo.exe
/ic:\sysinfo\alsdefault.bgi
/timer:0") ' Run BGInfo to stamp
the new desktop
WshShell.LogEvent 4,"Set BFS Logo Desktop"
end if
Next
For Each compip in alsrange
if compip = midip then
'If they are in ALS
set desktop = filesys.GetFile
("c:\sysinfo\Desktop.bmp")
desktop.attributes = 0
filesys.CopyFile
"C:\sysinfo\ALSDesktop.bmp",desktop,1
' See above example,
this sets it to ALS desktop.
wshShell.Run("c:\sysinfo\bginfo.exe
/ic:\sysinfo\alsdefault.bgi /timer:0")
WshShell.LogEvent 4,"Set ALS Logo Desktop"
end if
Next
' I needed to add some logic to change the ZENwsimport
server based on location. This section updates the
' registry key for ZENwsimport so workstations would import
into the proper container.
For Each compip in nerange
if compip = midip then
'If they are in NE
WshShell.RegWrite
"HKEY_LOCAL_MACHINE\SOFTWARE\Novell\
Workstation Manager\
Import Server\","10.5.1.74"
end if
Next
For Each comprange in rocrange
For Each compip in comprange
if compip = midip then
'If they are in a ROC,
remove IPX
wshshell.popup "Remote
IP detected,
removing IPX!",3,
"ALS Scripting", 0 + 16
WshShell.Run "c:\winnt\
system32\NetWare\Nwmigw2k\
setupw2k.exe /u ms_nwipx",
7,TRUE
WshShell.LogEvent 0,
"ROC detected: Removed IPX"
end if
Next
Next
Function GetIP()
Dim ws : Set ws = CreateObject("WScript.Shell")
Dim fso : Set fso = CreateObject
("Scripting.FileSystemObject")
Dim TmpFile : TmpFile = fso.GetSpecialFolder(2)
& "/ip.txt"
Dim ThisLine, IP
IP = "0"
If ws.Environment("SYSTEM")("OS") = "" Then
ws.run "winipcfg /batch " & TmpFile, 0, True
Else
ws.run "%comspec% /c ipconfig > " & TmpFile,
0, True
End If
With fso.GetFile(TmpFile).OpenAsTextStream
Do While NOT .AtEndOfStream
ThisLine = .ReadLine
if IP = "0" then ' A little logic to make
it read the 1st IP address if the machine
has multiple IP's
If InStr(ThisLine, "Address") <> 0 Then IP =
Mid(ThisLine, InStr(ThisLine, ":") + 2)
end if
Loop
.Close
End With
'WinXP (NT? 2K?) leaves a carriage return at the end of line
If IP <> "" Then
If Asc(Right(IP, 1)) = 13 Then IP = Left(IP, Len(IP) - 1)
End If
GetIP = IP
fso.GetFile(TmpFile).Delete
Set fso = Nothing
Set ws = Nothing
End Function
If you have any questions you may contact Jim at zenhelp@theshanks.net
Reader Comments
- Excelent information. Great starter for a new admin wondering what to do
- I appreciate the details Jim provided. His article is very straightforward with good explanation of the process.
- Great ideas!
- Great to see this detail. We use a similar instruction sheet.
- Impressively straight forward time-saver. Look forward to hearing from you often.
- Wish I had this info about 3 months ago.. Thanks.
- Wow, Great usage of VBS ! We use batch files in same way.
- Awesome! A little editing and it works perfectly on our network. Unfortunately the "NonModalDialog" ActiveX control is no longer available.
Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com


