; Okay, the SEMICOLAN acts as the REM or :: does in a batch file. It is used in KiXtart to
; allow you to comment code, etc...
$nul=SetOption("WrapAtEOL","On") ; This allows the return to the console to wrap when it
; reaches the end of the screen and not overwrite the output as it would when not using it.
$nul=SetOption("Explicit","On") ; When you enable the Explicit option, you must explicitly
;declare all variables using Dim, Global or ReDim statements. If you attempt to use an
;undeclared variable name, an error occurs. Use the Explicit option to avoid incorrectly
;typing the name of an existing variable.
KB823980 ; This line is calling the FUNCTION KB823980() below
Function KB823980()
IF @INWIN=1 ; This checks to make sure it is Windows NT/2000/XP/2003 ie. it does not run for Windows 9x
; also note that the ENDIF matching pair for this IF is near the very end of this FUNCTION
; so that basically if a Windows 9x attempts to run this code, it does not run.
DIM $KBPath,$Admin,$KBFile,$KBRequired,$IServer,$LServer,$GetLogServer,$Rpcs,$RPCver ; This line DIM the variables
$KBPath='SP\KB823980' ; This var $KBPath hold the path portion ie.. SP\KB823980 Which later on is added to another
; var (variable) to complete the full name and path to the file. For this example we have a
; Server the SP folder shared. So when you take the Server name SERVER1 and add this var to it
; you end up with a full path. SERVER1\SP\KB823980 then you add the var for the file name as
; well in the code to get the full path and file name to execute the program.
IF LocalAdmin ; This runs the LocalAdmin UDF (User Defined Function) that checks to make sure the user has Admin Rights
; on his/her local system when logging in.
$RPCver=GetRPCVersion ; This runs the check to put the version of the file into a var for testing.
$Admin ='Yes' ; This sets a var to Yes mainly for use when logging data about the results of this code to a log file.
SELECT ; Begins a multiple choice selection process. However, only 1 choice can be used. Once the first check is
; valid the code performs the task and then moves out of the SELECT section of code. If no choice is found to
; match then the CASE 1 is automatically selected.
CASE @ProductType='Windows NT Workstation' ; This is a built-in macro of KiXtart that checks if the machine is a
; Windows NT 4.0 Workstation.
$KBFile='Q823980i.EXE' ; Sets the file name to use into a var
$KBRequired=KeyExist('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Q823980') ; Puts the results if found
; into a var and then checks it. This could all be done with with a single check also to trim the code down a little.
IF $KBRequired ; If the key exists in the Registry it does nothing as it assumes the patch was installed
; if the key does not exist it will run the ELSE code which would install the patch.
; Patch already installed
ELSE
$GetLogServer = GetLogServer() ; This is used so that we know the name of the Server to write the log files to and
; which server to run the installation from. In a large Network you would not want
; to run the installation for all machines from one Server. If you have a smaller
; Network and all systems are locally located you can substitute this code with the
; actual name of the Server where you want to both install the patch from and where
; to log the results of this script.
$IServer = $GetLogServer[0] ; This is the var used for us in a bigger Network to determine the Installation Server
$LServer = $GetLogServer[1] ; This is the var used to select the Logging Server
SHELL '%comspec% /c \\'+$IServer+'\'+$KBPath+'\'+$KBFile+' /q /z' ; This executes the installation of the patch
; but is SILENT. You may want to use only the
; /u /z switch so that if the application has
; trouble finding a temp extract path the user
; could select a path.
ENDIF
CASE @ProductType='Windows 2000 Professional' ; Built-in KiXtart macro to check if the current system is a Windows 2000
; Workstation or not.
$KBFile='Windows2000-KB823980-x86-ENU.exe' ; Var to hold the name of the file to execute
IF $RPCver <> "5.00.2195.6753" ; Checks if the value of the GetRPCVersion() function is correct and if not
; it then gets the name of the installation and logging Servers and then
; it executes the patch
$GetLogServer = GetLogServer()
$IServer = $GetLogServer[0]
$LServer = $GetLogServer[1]
SHELL '%comspec% /c \\'+$IServer+'\'+$KBPath+'\'+$KBFile+' /u /q /z'
ENDIF
CASE @ProductType='Windows XP Professional' OR @ProductType='Windows XP Home Edition'
; This line above is the KiXtart macro to check if the Workstation is a Windows XP Pro or not. Yes, in a logon script you
; would have no need to check for a Home Editon as they can not join a Domain, so they could not be processing a logon
; script in the first place. However, this should work just fine and be checking XP Pro workstations.
$KBFile='WindowsXP-KB823980-x86-ENU.exe' ; Var that holds the name of the file to execute.
IF @CSD = 'Service Pack 1' ; Checks to make sure the XP Workstation has SP1 installed, if not the ELSE
; statement is used to assume it is not at SP1 level and thus needs a different
; check for the patch.
IF $RPCver <> "5.1.2600.1230"
$GetLogServer = GetLogServer()
$IServer = $GetLogServer[0]
$LServer = $GetLogServer[1]
SHELL '%comspec% /c \\'+$IServer+'\'+$KBPath+'\'+$KBFile+' /u /q /z'
; Notice in the line above how you have the $IServer (installation server name) then the $KBPath (path to the files)
; and then the $KBFile (the actual name of the patch to launch). When they are all put together it is like typing
; out the full Server\Path\Filename as in this example
; JOHNDOESERVER\SP\KB823980\WindowsXP-KB823980-x86-ENU.exe /u /q /z
ENDIF
ELSE
IF $RPCver <> "5.1.2600.109" ; This code is executed if the system is an XP Pro and it is NOT at SP1 level yet.
$GetLogServer = GetLogServer()
$IServer = $GetLogServer[0]
$LServer = $GetLogServer[1]
SHELL '%comspec% /c \\'+$IServer+'\'+$KBPath+'\'+$KBFile+' /u /q /z'
? 'Results of running the patch were: '+@ERROR+' : '+@SERROR
; The line above would show briefly on the DOS console after the patch ran. You could place similar lines
; any where you want in your code to check what is happening. To stop the script until you press a key you
; could use GET $ after the ERROR line and the script will wait till you press a key before continuing on.
ENDIF
ENDIF
CASE 1 ; CASE 1 is used when none of the other checks were found to be true.
; 'Unknown Error..' ; You could have this do anything you want
EXIT @ERROR
ENDSELECT
ELSE
$Admin ='No' ; This sets the var to No for loggins so that you coudl write in a log file and no why the patch did not run
; for a paticular system.
ENDIF
ENDIF
EndFunction
function LocalAdmin() ; This is the function that checks if the user is a local administrator or not.
$LocalAdmin=ingroup('@wksta\'+sidtoname('S-1-5-32-544'))-1+@INWIN
endfunction
Function GetCurrentIP() ; This function gets back the current IP of the users machine so that you can determine where the
; system logged in from and assign an Installation Server based on the IP address
; If you don't have system all over the World or in other locations then you may not need to use
; this check either. There are other ways to check the IP as well, but in our case most of the other
; methods require either WSH/WMI etc... This particular method should work on ALL Windows systems
; including Windows 9x
DIM $IP, $TempFile, $Line, $cf
$TempFile = "%TEMP%\PING.TXT"
If Exist($TempFile)
Del $TempFile
EndIf
SHELL '%COMSPEC% /C PING -n 1 @WKSTA >'+$TempFile
$IP = ""
If Open(1, $TempFile) = 0
$Line = ReadLine(1)
While @ERROR = 0
If InStr($Line,@WKSTA)
$Line = SubStr($Line,InStr($Line,"[")+1)
$GetCurrentIP = Substr($Line,1,InStr($Line,"]")-1)
EndIf
$Line = ReadLine(1)
Loop
$cf = Close(1)
EndIf
If Exist($TempFile)
Del $TempFile
EndIf
EndFunction
Function GetLogServer() ; This function helps and is an example of one of many methods available to try and assign different
; Servers based on the returned IP or Domain. As in our case we have systems all over the World and
; we have multiple Domains. Again, if you don't have a need for such a large selection process you
; don't need to use this function, you can hard code your Server names.
DIM $InstallerArray[2],$IP,$UserDomain,$spServer,$LogServer
$UserDomain=@DOMAIN
$IP=GetCurrentIP
SELECT
CASE InStr($IP, '132.36.')
$spServer='none'
$LogServer='APPSERVER1'
RETURN
CASE InStr($IP, '122.124.111')
$spServer='FPSERV2'
$LogServer='APPSERVER1'
CASE InStr($IP, '122.124.112')
$spServer='FPSERV2'
$LogServer='APPSERVER1'
CASE $UserDomain='DOMAIN1'
$spServer='FPSERV3'
$LogServer='APPSERVER3'
CASE $UserDomain='DOMAIN2'
$spServer='FPSERV1'
$LogServer='APPSERVER1'
CASE $UserDomain='DOMAIN3'
$spServer='FPSERV4'
$LogServer='APPSERVER1'
CASE 1
$spServer='FPSERV1'
$LogServer='APPSERVER1'
ENDSELECT
$InstallerArray[0]=$spServer
$InstallerArray[1]=$LogServer
$GetLogServer=$InstallerArray
EndFunction
Function GetRPCVersion() ; This function checks the version number of the installed file to make sure it is the correct
; version or not. Basically this script check will run every time a user logs in. If the file
; version DOES NOT match the patch will be installed. If the version DOES match the whole script
; is skipped.
$GetRPCVersion = GetFileVersion('%windir%\system32\Rpcrt4.dll', 'Productversion')
endfunction
|