Automated ZEN Imaging: The Next Step
Novell Cool Solutions: Trench
By Jim Shank
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

Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com