Hello Devfrag hows it going.

Well I hope this helps you and others out to hopefully have a better
understanding of how and why the script does what it does. I don't see anything right off the bat
that would prevent the code from running on anything from version KiXtart 4.02 and above, however I can
only verify that it works on version 4.21 of KiXtart. If you have further questions please let
me know and I'll try to help you out as best I can.

I know how it is being new and unfamiliar with something and how great it feels to have someone
take the time to Mentor or otherwise explain and walk you through something. As time goes on you
learn more and more and the whole scripting thing becomes easier.

As a reminder though, this script assumes that your users have Local Admin rights on their workstations. If they do not have Admin rights then this method WILL NOT work for you.






; 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



[ 09. August 2003, 07:16: Message edited by: NTDOC ]