On Error Resume Next

'-------------------------------------------------------------------------------------------------------
' Global Variables
'-------------------------------------------------------------------------------------------------------

' Create Objects
Dim WshShell, WshNetwork, fso, WshSysEnv, objArgs, objArgsNamed, WshProcEnv, fsoX, objReg

' Retrieve RAT Client Parameters
Dim Reg, sRegName, sParamWarning, iCounter, sRegData, sParam

' Global Parameters
Dim iFunctionLibraryVersion

Dim sMessageTitle, strModeArg, strLangArg, sApplicationInstallLanguage, strOptionsArg, strPropertiesArg, strInstallDriveArg, iStep, iPhase, bErrorOccured, sErrorMessage
Dim sTemp, sWindir, sSystemDrive, sProgramFiles, sProgramFilesX86, sComspec, sComputerName, sCurrentFolder, sParentFolder
Dim OSType, OSVersion, OSLanguage, OSArchitecture
Dim ApplicationArchitecture
Dim sRegPackageLog, sLogPath, sMainLogFile, sMainTraceFile, sPackageLogFile, sSetupLogFileName, sSetupLogFile
Dim sUninstallLogFileName, sUninstallLogFile, sPackageScreenShot, sAdjustCUFolder
Dim sAllUsersPrograms, sPrograms, sAllUsersDesktop, sDesktop, sAllUsersStartMenu, sStartMenu
Dim bFirstWindow, AdditionalWindowsCount

Dim iErrorExitCode, sErrorName, sErrorDescription

' Other Parameters
Dim ObjAutoIt
Dim Mode
Dim StartTime, EndTime, sShare, sCheckDrive, sCheckShare
Dim iMinimalFunctionLibraryVersion, sSubFolderPackage
Dim sSources, sStringToAdd
Dim AdditionalWindows(10, 2)
Dim nCompare, iLength, sSourcePath, sAutoLogonStatus
Dim Status, sJobID, Return, filelog, sMSIProductCode
Dim MyAutoLogon
Dim bIsSCCM, bIsLANDESK, sIvantiEpmCoreNameUsedByAgent

' Package Parameters
Dim sPackageName, sPackageVersion

' Application Parameters
Dim sApplicationName, sApplicationVersion

bErrorOccured = False
iErrorExitCode = 0

Dim sAdDomain,sAdComputerLocation,sAdCorpDiv,sAdSub1,sAdSub2,sAdSub3
Dim sOfficeVersion
Dim oProgressMsg		'Public variable needed for Subprocedure ProgressMsg

'-------------------------------------------------------------------------------------------------------
' Create objects
'-------------------------------------------------------------------------------------------------------
Set WshShell		= WScript.CreateObject("Wscript.Shell")
Set WshNetwork		= WScript.CreateObject("WScript.Network")
Set fso		    	= CreateObject("Scripting.FileSystemObject")
Set WshSysEnv		= WshShell.Environment("System")
'Set Installer		= WScript.CreateObject("WindowsInstaller.Installer")
Set objArgs 		= WScript.Arguments
Set objArgsNamed	= WScript.Arguments.Named
'Set Groups	    	= CreateObject("Scripting.Dictionary")
Set WshProcEnv 		= WshShell.Environment("Process")
Set fsoX		= New FileSystemObjectX
Set objReg		= GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")

'-------------------------------------------------------------------------------------------------------
' Global Parameters
'-------------------------------------------------------------------------------------------------------
iFunctionLibraryVersion 	= "10"

' History
' * 1
'	- Merge of previous INSLibrary and EmersonLibrary 
'
' * 2
'	- New functions GetMsProductInstalled, RegKeyExist
'
' * 3
'	- Updated function StartLog, to not append but always write new log file
'	- Updated function CheckLibraryVersion, correct bug
'   - New functions HotFixFound, GetPowerShellVersion
'
' * 4
'	- Updated function RetrieveOSLanguage: also check entry HKLM\SYSTEM\CurrentControlSet\Control\MUI\Settings\PreferredUILanguages
'	- Updated function Translate
'	- Changed constant value Const cstDutchNetherlandsLangCode to "NL" (instead of "NL-NL")
'	- Changed constant value Const cstEnglishUS to "English United States" (instead of "English")
'   - Added constants cstEnglishGB, cstEnglishGBLocaleID, cstEnglishGBLangCode
'
' * 5
'   - Added functions getUserSecondaryTelephoneNumber, getUserHomePhone
'
' * 6
'   - Corrected bug in GetMsProductInstalled resulting in reporting wrong bitness for an installed Microsoft product
' 
' * 7
'   - Corrected bug in RetrieveOSArchitecture resulting in not identifying a 64Bit Russian Windows 10 as being 64 Bit
'
' * 8
'   - Corrected bug in GetMsiErrorDescription resulting in not defining variables sErrorName, sErrorDescription (added them as public variables to correct)
'   - Corrected bug in GetEmrsnAdComputerLocation resulting in not returning False if the PC is in a workgroup (added On error resume next in function to correct)
'	- Updated SendInstallStatusEmail so no mail is sent by default to ITLANDeskSupport.EPM-EMA@Emerson.com
'   - Updated Sub EmersonLog: don't use deprecated function sdclient.exe to send message to Ivanti Endpoint Manager core server but use sendtaskstatus.exe instead
'   - Added function GetIvantiEpmCoreNameUsedByAgent + added public variable sIvantiEpmCoreNameUsedByAgent  (required for updated EmersonLog)
'	- Corrected bug in function OsPendingReboot - not seeing pending file rename operations for files in C:\Windows
'
' * 9
'   - Added workaround in GetEmrsnAdComputerLocation: if account installing sw cannot connect to domain controller (no rights, or not available) then get AD computer location from registry
'
' * 10
'   - Corrected function DecimalToBinary, not returning 0 if parameter was "0"
'   - Updated function AddPackagingFrameworkInfoToRegistry to store package information in HKLM\SYSTEM\Emerson\Packaging Framework\<sBaselineName>
'	- Added function ProgressMsg(sMessage, sWindowTitle)
'	- Corrected GetProfileSIDTweak
'	- Added functions: GetFreeSpace, FormatGB, FolderIsEmpty
'	- Changed the sTemp variable definition to refer to %Windir%\Temp rather than referring to %temp%
'     This means the temp folder used when started under system is the same folder used when ran with a local administrator account
'	- When extracting Program.7z the extracted folder will no longer contain the package version
'
' Constants for Mode
Const cstInteractiveMode	= "Interactive"
Const cstINSRatMode		= "INSRat"
Const cstSilentMode		= "Silent"

' Constants for SetSecurity
Const AddSecurity		= "Add"
Const ReplaceSecurity 		= "Replace"

' Constants for WinlogonStatus
Const cstWinlogonUserLoggedOn		= "User Logged On"
Const cstWinlogonNoUserLoggedOn		= "No User Logged On"
Const cstWinlogonUnknown		= "Unknown"

' Constants for PackageStatus
Const cstInstalled		= "Installed"
Const cstInstalling		= "Installing"
Const cstInstallFailed		= "InstallFailed"
Const cstUninstallFailed	= "UninstallFailed"

' Constants for Jobs
Const cstInstallJob		= "Install"
Const cstUninstallJob 		= "Uninstall"
Const cstReinstallJob		= "Reinstall"

' Constants for Languages
' https://msdn.microsoft.com/en-us/library/ms912047(v=winembedded.10).aspx 
' https://www.sitepoint.com/web-foundations/iso-2-letter-language-codes/
Const cstArabicSaudiArabia 				= "Arabic Saudi Arabia"
Const cstArabicSaudiArabiaLocaleID 		= 1025
Const cstArabicSaudiArabiaLangCode		= "AR"
Const cstBulgarian						= "Bulgarian"
Const cstBulgarianLocaleID 				= 1026
Const cstBulgarianLangCode 				= "BG"
Const cstChineseChina					= "Chinese China"
Const cstChineseChinaLocaleID 			= 2052
Const cstChineseChinaLangCode 			= "ZH-CN"
Const cstChineseTaiwan					= "Chinese Taiwan"
Const cstChineseTaiwanLocaleID			= 1028
Const cstChineseTaiwanLangCode			= "ZH-TW"
Const cstCroatian						= "Croatian"
Const cstCroatianLocaleID				= 1050
Const cstCroatianLangCode				= "HR"
Const cstDanish     					= "Danish"
Const cstDanishLocaleID					= 1030
Const cstDanishLangCode					= "DA"
Const cstDutchBelgium					= "Dutch Belgium"
Const cstDutchBelgiumLocaleID			= 2067
Const cstDutchBelgiumLangCode			= "NL-BE"
Const cstDutchNetherlands				= "Dutch Netherlands"
Const cstDutchNetherlandsLocaleID		= 1043
Const cstDutchNetherlandsLangCode		= "NL"
Const cstEnglishUS						= "English United States"
Const cstEnglishUSLocaleID				= 1033
Const cstEnglishUSLangCode				= "EN"
Const cstEnglishGB						= "English Great Britain"
Const cstEnglishGBLocaleID				= 2057
Const cstEnglishGBLangCode				= "EN-GB"
Const cstEstonian   					= "Estonian"
Const cstEstonianLocaleID				= 1061
Const cstEstonianLangCode				= "ET"
Const cstFinnish 						= "Finnish"
Const cstFinnishLocaleID				= 1035
Const cstFinnishLangCode				= "FI"
Const cstFrenchFrance					= "French France"
Const cstFrenchFranceLocaleID			= 1036
Const cstFrenchFranceLangCode			= "FR"
Const cstGermanGermany					= "German Germany"
Const cstGermanGermanyLocaleID			= 1031
Const cstGermanGermanyLangCode			= "DE"
Const cstGreek      					= "Greek"
Const cstGreekLocaleID					= 1032
Const cstGreekLangCode					= "EL"
Const cstHebrew 						= "Hebrew"
Const cstHebrewLocaleID					= 1037
Const cstHebrewLangCode					= "IW"
Const cstHindi							= "Hindi"
Const cstHindiLocaleID					= 1081
Const cstHindiLangCode					= "HI"
Const cstHungarian  					= "Hungarian"
Const cstHungarianLocaleID				= 1038
Const cstHungarianLangCode				= "HU"
Const cstItalianItaly					= "Italian Italy"
Const cstItalianItalyLocaleID			= 1040
Const cstItalianItalyLangCode			= "IT"
Const cstJapanese 						= "Japanese"
Const cstJapaneseLocaleID				= 1041
Const cstJapaneseLangCode				= "JA"
Const cstKazakh							= "Kazakh"
Const cstKazakhLocaleID					= 1087
Const cstKazakhLangCode					= "KK"
Const cstKorean							= "Korean"
Const cstKoreanLocaleID					= 1042
Const cstKoreanLangCode					= "KO"
Const cstNorwegianBokmal  				= "Norwegian Bokmal"
Const cstNorwegianBokmalLocaleID		= 1044
Const cstNorwegianBokmalLangCode		= "NB"
Const cstPolish							= "Polish"
Const cstPolishLocaleID					= 1045
Const cstPolishLangCode					= "PL"
Const cstPortuguesePortugal 			= "Portuguese Portugal"
Const cstPortuguesePortugalLocaleID		= 2070
Const cstPortuguesePortugalLangCode		= "PT"
Const cstRomanian						= "Romanian"
Const cstRomanianLocaleID				= 1048
Const cstRomanianLangCode				= "RO"
Const cstRussian						= "Russian"
Const cstRussianLocaleID				= 1049
Const cstRussianLangCode				= "RU"
Const cstSerbianLatin					= "Serbian Latin"
Const cstSerbianLatinLocaleID			= 2074
Const cstSerbianLatinLangCode			= "SR"
Const cstSlovak							= "Slovak"
Const cstSlovakLocaleID					= 1051
Const cstSlovakLangCode					= "SK"
Const cstSlovenian						= "Slovenian"
Const cstSlovenianLocaleID				= 1060
Const cstSlovenianLangCode				= "SL"
Const cstSpanishSpain					= "Spanish Spain"
Const cstSpanishSpainLocaleID			= 1034
Const cstSpanishSpainLangCode			= "ES"
Const cstSwedishSweden					= "Swedish Sweden"
Const cstSwedishSwedenLocaleID			= 1053
Const cstSwedishSwedenLangCode			= "SV"
Const cstThai							= "Thai"
Const cstThaiLocaleID					= 1054
Const cstThaiLangCode					= "TH"
Const cstTurkish						= "Turkish"
Const cstTurkishLocaleID				= 1055
Const cstTurkishLangCode				= "TR"
Const cstUkranian						= "Ukranian"
Const cstUkranianLocaleID				= 1058
Const cstUkranianLangCode				= "UK"

' Constants for LocalGroup
Const cstAdministrators					= "Administrators"
Const cstEveryone						= "Everyone"
Const cstUsers							= "Users"
Const cstGuests							= "Guests"
Const cstPowerUsers						= "Power Users"
Const cstRemoteDesktopUsers				= "Remote Desktop Users"
Const cstBackupOperators				= "Backup Operators"
Const cstReplicators					= "Replicators"
Const cstNetworkConfigurationOperators	= "Network Configuration Operators"
Const cstAccountOperators				= "Account Operators"
Const cstServerOperators				= "Server Operators"
Const cstPrintOperators					= "Print Operators"

' Constants for LocalUser
Const cstAdministrator	= "Administrator"
Const cstGuest		= "Guest"

' Constants for fso
Const fsoOverwrite	= True
Const fsoForce		= True
Const fsoForReading	= 1
Const fsoForWriting	= 2
Const fsoForAppending	= 8
Const fsoUnicode	= -1
Const fsoASCII		= 0

' Constants for WshShell.Run
Const RunWaitOnReturn	= True
Const RunHideWindow	= 0
Const RunShowWindow	= 1

' Constants for strings
Const DoubleQuote	= """" ' = Chr(34)

' Constants for OSType
Const OSNT4	= "WinNT4"
Const OSW2K	= "Win2000"
Const OSXP	= "WinXP"
Const OSW2K3	= "Win2003"
Const OSVista	= "WinVista"
Const OSW2K8	= "Win2008"
Const OSWin7	= "Win7"
Const OSW2K8R2	= "Win2008R2"
Const OSWin8 = "Win8"
Const OSWin81 = "Win8.1"
Const OSW2K12 = "Win2012"
Const OSW2K12R2 = "Win2012R2"
Const OSWin10	= "Win10"
Const OSWin2016	= "Win2016"

' Constants for Sizes
Const KByte	= 1024
Const MByte	= 1048576

' Constants for SetNTFSPermissions
Const AddPermissions		= "Add"
Const ReplacePermissions	= "Replace"

' Constants for Registry
Const hexHKCR 	= &H80000000
Const hexHKCU 	= &H80000001
Const hexHKLM 	= &H80000002
Const hexHKU	= &H80000003
Const strHKCR 	= "HKEY_CLASSES_ROOT"
Const strHKCU 	= "HKEY_CURRENT_USER"
Const strHKLM 	= "HKEY_LOCAL_MACHINE"
Const strHKU	= "HKEY_USERS"

' Constants for CPUArchitecture
Const CPUx86 = "x86"
Const CPUx64 = "x64"
Const CPUia64 = "ia64"

' Constants for OSArchitecture
Const OSx86 = "x86"
Const OSx64 = "x64"
Const OSia64 = "ia64"

' Constants for Architecture
Const x86 = "x86"
Const x64 = "x64"
Const ia64 = "ia64"

' Constants for RetrieveOSProductType
Const OSClient = "WindowsClient"
Const OSServer = "WindowsServer"

' Constants for Packages Registry
Const sRegPackages	= "HKEY_LOCAL_MACHINE\SOFTWARE\INS\Packages"
Const sRegPackagePhase	= "HKEY_LOCAL_MACHINE\SOFTWARE\INS\Packages\Phase"
Const sRegPackagesLog	= "HKEY_LOCAL_MACHINE\SOFTWARE\INS\Packages\Log"

' Other Parameters
sMessageTitle 		= "INS Script"

strModeArg	    	= objArgsNamed.Item("mode")
strLangArg			= objArgsNamed.Item("lang")
strOptionsArg		= objArgsNamed.Item("Options")
strPropertiesArg	= objArgsNamed.Item("Properties")
strInstallDriveArg  = objArgsNamed.Item("InstallDrive")
iStep		    	= UCase(objArgsNamed.Item("step"))
If iStep = "" Then iStep = 1
iStep = CInt(iStep)
iPhase			= WshShell.RegRead(sRegPackagePhase)
If iPhase = "" Then
  iPhase = 1
Else
  WshShell.RegDelete sRegPackagePhase
End If
iPhase = CInt(iPhase)

bErrorOccured	    	= False
sErrorMessage		= ""
iErrorExitCode		= 0
sWindir		    	= WshShell.ExpandEnvironmentStrings("%WinDir%")
sTemp				= sWindir & "\Temp" 
sSystemDrive		= WshShell.ExpandEnvironmentStrings("%SystemDrive%")
sProgramFiles		= WshShell.ExpandEnvironmentStrings("%ProgramFiles%")
sProgramFilesX86	= WshShell.ExpandEnvironmentStrings("%ProgramFiles(x86)%")
sComspec	    	= WshSysEnv("ComSpec")
sComputerName 		= WshShell.RegRead("HKLM\System\CurrentControlSet\Control\ComputerName\ComputerName\ComputerName")
sCurrentFolder		= fso.GetParentFolderName(WScript.ScriptFullName)
sParentFolder		= fso.GetParentFolderName(sCurrentFolder)
OSType			= RetrieveOSType
OSVersion		= RetrieveOSVersion
OSLanguage		= RetrieveOSLanguage
OSArchitecture		= RetrieveOSArchitecture
Dim strAddWow
If OSArchitecture=OSx86 Then
	strAddWow = ""
Else	
	strAddWow = "\Wow6432Node"
End If
ApplicationArchitecture	= GetApplicationArchitecture

WshProcEnv("SEE_MASK_NOZONECHECKS") = 1

sRegPackageLog 		= sRegPackagesLog & "\" & sPackageName & "\" & sPackageVersion

If sLogPath = "" Then sLogPath = sWindir & "\INS\Logs"
sMainLogFile		= sLogPath & "\_MainLog.log"
sMainTraceFile		= sLogPath & "\_MainTrace.log"
MakeFolder sWindir & "\INS\AdjustCU\CU\Once"
MakeFolder sWindir & "\INS\AdjustCU\CU\Always"
MakeFolder sLogPath
sPackageLogFile 	= sLogPath & "\" & Replace(sPackageName & "_" & sPackageVersion & ".log"," ","_")
sSetupLogFileName	= Replace(sPackageName & "_" & sPackageVersion & "-Setup.log"," ","_")
sSetupLogFile		= sLogPath & "\" & sSetupLogFileName
sUninstallLogFileName	= Replace(sPackageName & "_" & sPackageVersion & "-Uninstall.log"," ","_")
sUninstallLogFile	= sLogPath & "\" & sUninstallLogFileName
sPackageScreenShot	= sLogPath & "\" & Replace(sPackageName & "_" & sPackageVersion & "-ERROR.bmp"," ","_")

If sAdjustCUFolder = "" Then sAdjustCUFolder = sWindir & "\INS\AdjustCU"

sAllUsersPrograms 	= WshShell.SpecialFolders("AllUsersPrograms") 
sPrograms 		= WshShell.SpecialFolders("Programs") 
sAllUsersDesktop 	= WshShell.SpecialFolders("AllUsersDesktop") 
sDesktop 		= WshShell.SpecialFolders("Desktop") 
sAllUsersStartMenu 	= WshShell.SpecialFolders("AllUsersStartMenu") 
sStartMenu 		= WshShell.SpecialFolders("StartMenu") 

bFirstWindow 		= True
AdditionalWindowsCount 	= 0

sIvantiEpmCoreNameUsedByAgent = GetIvantiEpmCoreNameUsedByAgent

'-------------------------------------------------------------------------------------------------------
' Subs and functions
'-------------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------------
Sub CheckLibraryVersion

   '-------------------
   ' Purpose:	Check if the required Function Library version is used
   ' Type:	Sub
   ' Input:	None
   '-------------------

   Status = 2
   'WshShell.RegWrite "HKLM\Software\INS\INSLibraryVersion", iFunctionLibraryVersion

      If Cint(iFunctionLibraryVersion) < Cint(iMinimalFunctionLibraryVersion) Then
      	 Err.Clear 
         PackageLog "The Function Library version is lower than the required version!"
         MainErrLog "The Function Library version is lower than the required version!"
         EndLog
      End If

End Sub

'-------------------------------------------------------------------------------------------------------
Sub DetectMode

   '-------------------
   ' Purpose:	Determine if the package has been started interactive (by user), silent or via INS RAT
   ' Type:	Sub
   ' Input:	None
   '-------------------

  On Error Resume Next

  Select Case OSLanguage
     Case cstDutchNetherlands
        MsgAreYouSureYouWantToExecute = "Bent u zeker dat u " & sPackageName & " - " & sPackageVersion & " wil " & sJobID & "eren ?"
        MsgJobWasCancelledByUser = "De " & sJobID & "atie is geannuleerd door de gebruiker."
     Case cstFrenchFrance
        MsgAreYouSureYouWantToExecute = "Voulez-vous vraiment " & sJobID & "er " & sPackageName & " - " & sPackageVersion & " ?"
        MsgJobWasCancelledByUser = "L'" & sJobID & "ation est annule par l'utilisateur."
     Case Else
        MsgAreYouSureYouWantToExecute = "Are you sure you want to " & sJobID & " " & sPackageName & " - " & sPackageVersion & " ?"
        MsgJobWasCancelledByUser = "The " & sJobID & "ation was cancelled by the user."
  End Select

  Select Case UCase(strModeArg)
    Case "", "INTERACTIVE"
      Mode = cstInteractiveMode
      Return = WshShell.popup(MsgAreYouSureYouWantToExecute, , sMessageTitle, vbQuestion + vbYesNo)
      If Return = vbNo Then
        WshShell.Popup MsgJobWasCancelledByUser, 3, sMessageTitle, vbExclamation
        Wscript.Quit
      End If
    Case "INSRAT"
      Mode = cstINSRatMode
    Case "SILENT"
      Mode = cstSilentMode
    Case Else
      WshShell.Popup "Valid parameters for " & WScript.Scriptname & " : " & VbCrLf & VbCrLf & _
        "INSRAT" & vbTab & "Silent Install during bare-metal INS deployment" & VbCrLf & _
        "SILENT    " & vbTab & "Silent install NOT during bare-metal INS deployment", , sMessageTitle, vbInformation
      WScript.Quit
  End Select

End Sub

'-------------------------------------------------------------------------------------------------------
Sub StartLog
	
   '-------------------
   ' Purpose:	Start Logging in Log file, registry and eventviewer 
   ' Type:	Sub
   ' Input:	None
   '-------------------

  On Error Resume Next

  If iStep > 1 Then Exit Sub 'step 2, 3, 4... is running, package already logged
  If iPhase > 1 Then Exit Sub 'Phase 2, 3, 4... is running, package already logged

  If Status = "" Then Status = 1
  If IsNull(Status) Then Status = 1
  If Not fso.FolderExists(sLogPath) Then
	MakeFolder sWindir & "\INS\AdjustCU\CU\Once"
	MakeFolder sWindir & "\INS\AdjustCU\CU\Always"
    MakeFolder sLogPath
    MainLog "Setting security on " & sLogPath
	If OSType = OSNT4 Or OSType = OSW2K Or OSType = OSW2K3 Or OSType = OSXP Then
		Call SetSecurity(ReplaceSecurity, sLogPath, LocalGroup(cstAdministrators) & ":F System:F " & LocalGroup(cstEveryone) & ":R")
	Else
		Call SetISecurity(ReplaceSecurity, sLogPath, LocalGroup(cstAdministrators) & ":(OI)(CI)F System:(OI)(CI)F " & LocalGroup(cstEveryone) & ":(OI)(CI)R")
	End If
	MainLog "Security applied on " & sLogPath
  End If

  'log to Main log file and Package Log file
  If Not sAutoLogonStatus = "EXECPKG" Then
    MainLog "============================================================================"
    MainLog sPackageName & " version " & sPackageVersion & " started with job " & sJobID
    MainLog "----------------------------------------------------------------------------"
    'Ensure a new package logfile is created to avoid logging is appended to a logfile that was created by a previous installation
    If fso.FileExists(sPackageLogFile) Then
    	fso.DeleteFile sPackageLogFile, True
    End If
    PackageLog "============================================================================"
	PackageLog "Baseline Name		: " & sBaselineName
    PackageLog "Package Name        : " & sPackageName
    PackageLog "Package Version     : " & sPackageVersion
    PackageLog "Application Name    : " & sApplicationName
    PackageLog "Application Version : " & sApplicationVersion
    PackageLog "Script              : " & WScript.ScriptFullName
    PackageLog "Job Parameter       : " & sJobID
    PackageLog "Mode Parameter      : " & Mode
	PackageLog "Options Parameter   : " & strOptionsArg
	PackageLog "Lang Parameter      : " & strLangArg
	PackageLog "Language for install: " & sApplicationInstallLanguage
    PackageLog "User context        : " & WshNetwork.UserDomain & "\" & WshNetwork.UserName
    PackageLog "Computer Name       : " & sComputerName
    PackageLog "FunctionLibrary Ver.: " & iFunctionLibraryVersion
    PackageLog "System Uptime       : " & SystemUpTime & "s"
    PackageLog "OS Type             : " & OSType
    PackageLog "OS Version          : " & OSVersion
    PackageLog "OS Language         : " & OSLanguage
    PackageLog "OS Architecture     : " & OSArchitecture
    'PackageLog "Desktop status      : " & DesktopStatus
    PackageLog "----------------------------------------------------------------------------"
  Else
    PackageLog "AutoLogon: Script = " & WScript.ScriptFullName
    PackageLog "AutoLogon: Job = " & sJobID
    PackageLog "AutoLogon: Mode = " & Mode
    PackageLog "AutoLogon: User context = " & WshNetwork.UserDomain & "\" & WshNetwork.UserName   
  End If
  
  'log to EventViewer
  EventErrLog "Started"

  'log to Registry
  PackageRegInfo
  PackageLog "Started at " & Now
  WshShell.RegWrite sRegPackageLog & "\Status", cstInstalling
  
  Err.Clear
  
End Sub

'-------------------------------------------------------------------------------------------------------
Sub DiskSpace

   '-------------------
   ' Purpose:	Determine if there's enough free disk space on the system drive
   ' Type:	Sub
   ' Input:	None
   '-------------------

  Status = 5
  On Error Resume Next

  Dim d

  Set d = fso.GetDrive(fso.GetDriveName(sSystemDrive))
  If d.FreeSpace/1048576 < iDiskSpaceBottomLimit + iRequiredDiskSpace Then
    Err.Raise 1005, "WSH", "Not enough diskspace available to run this script. Required diskspace = " & (iDiskSpaceBottomLimit + iRequiredDiskSpace) & " MB."
    RuntimeErrLog
    EndLog
  End If
  Err.Clear
End Sub

'-------------------------------------------------------------------------------------------------------
Sub MainLog(sItem)

   '-------------------
   ' Purpose:	Logs into the main log file
   ' Type:	Sub
   ' Input:	sItem: Textline to add (Type: string)
   '-------------------

  On Error Resume Next
  Set fileLog = fso.OpenTextFile(sMainLogFile, 8, TRUE)
  If IsNull(sItem) Then
    fileLog.WriteLine ""
  Else
    fileLog.WriteLine Now & " : " & vbTab & sItem
  End If
  fileLog.Close
  Err.Clear
End Sub

'-------------------------------------------------------------------------------------------------------
Sub MainErrLog(sItem)

   '-------------------
   ' Purpose:	Logs an error into the main log file and into the system's event log
   ' Type:	Sub
   ' Input:	sItem: Textline to add (Type: string)
   '-------------------

  If Err.Number <> 0 or not sItem = "" Then
    If Mode = cstInteractiveMode Then
      WshShell.popup "! ERROR : " & sItem & " : " & Err.Number & "   " & Err.Description, , sMessageTitle, vbCritical
    End If
    EventErrLog Err.Number & "   " & Err.Description
    MainLog "! ERROR : " & sItem & " : " & Err.Number & "   " & Err.Description
    bErrorOccured = True
    Err.Clear
  End If
End Sub

'------------------------------------------------------------------------------------------------------
Sub PackageLog(sItem)

   '-------------------
   ' Purpose:	Logs into the package log file and into the package registry key
   ' Type:	Sub
   ' Input:	sItem: Textline to add (Type: string)
   '-------------------

  Err.Clear 
  On Error Resume Next
  Set fileLog = fso.OpenTextFile(sPackageLogFile, 8, True)
  If IsNull(sItem) Then
    fileLog.WriteLine ""
  Else
    fileLog.WriteLine Now & " : " & vbTab & sItem
    WshShell.RegWrite sRegPackageLog & "\Progress", Status, "REG_SZ"
  End If
  fileLog.Close
  
End Sub

'-------------------------------------------------------------------------------------------------------
Sub RuntimeErrLog

   '-------------------
   ' Purpose:	Logs, if an error occurs, into the package log file and into the system's event log
   ' Type:	Sub
   ' Input:	None
   '-------------------

  If Err.Number <> 0 Then
    If bErrorOccured = False Then
      sErrorMessage = "! ERROR in Package : " & Err.Number & "   " & Err.Description
    End If
    bErrorOccured = True
    If iErrorExitCode = 0 Then
       iErrorExitCode = Err.Number
    End If
    If Mode = cstInteractiveMode Then
      WshShell.Popup "! ERROR in Package : " & Err.Number & "   " & Err.Description, 10, sMessageTitle, vbCritical
    End If
    PackageLog "! ERROR in Package : " & Err.Number & "   " & Err.Description
    EventErrLog Err.Number & "   " & Err.Description
    If bQuitOnError Then
       EndLog
    End If
  End If
  Err.Clear
End Sub

'-------------------------------------------------------------------------------------------------------
Sub EventErrLog(sTextEntry)

   '-------------------
   ' Purpose:	Logs into the system's event log
   ' Type:	Sub
   ' Input:	sTextEntry: Textline to add (Type: string)
   '-------------------

  On Error Resume Next
  If Not bErrorOccured Then
    WshShell.LogEvent 4, WScript.Scriptname & " " & Mode & " " & sJobID & ": " & sTextEntry
  Else 
    WshShell.LogEvent 1, WScript.Scriptname & " " & Mode & " " & sJobID & ": " & sTextEntry
  End If
  Err.Clear
End Sub

'-------------------------------------------------------------------------------------------------------
Sub EndLog

   '-------------------
   ' Purpose:	Takes care of all logging when the package execution has been completed
   ' Type:	Sub
   ' Input:	None
   '-------------------

  On Error Resume Next
  Err.Clear
 
  Select Case OSLanguage
     Case cstDutchNetherlands
        MsgJobFailed = "De " & sJobID & "atie van " & sPackageName & " - " & sPackageVersion & " is beeindigd met fouten"
        MsgJobFinishedSuccesfully = "De " & sJobID & "atie van " & sPackageName & " - " & sPackageVersion & " is successvol beeindigd"
        MsgJobFinishedSuccesfullyShort = "Successvol beeindigd"
     Case cstFrenchFrance
        MsgJobFailed = "L'" & sJobID & "ation de " & sPackageName & " - " & sPackageVersion & " a terminer avec des erreurs"
        MsgJobFinishedSuccesfully = "L'" & sJobID & "ation of " & sPackageName & " - " & sPackageVersion & " a terminer sans erreur"
        MsgJobFinishedSuccesfullyShort = "Terminer sans erreur"
     Case Else
        MsgJobFailed = "The " & sJobID & "ation of " & sPackageName & " - " & sPackageVersion & " finished with error(s)"
        MsgJobFinishedSuccesfully = "The " & sJobID & "ation of " & sPackageName & " - " & sPackageVersion & " finished successfully"
        MsgJobFinishedSuccesfullyShort = "Completed successfully"
  End Select

  If bErrorOccured Then
	Status = -100
  Else
    Status = 100
  End If

  If bErrorOccured Then
    'log to LogFile
    MainLog "Finished with error(s)"
    MainLog "============================================================================"

    'log to Package LogFile
    PackageLog "----------------------------------------------------------------------------"
    PackageLog "Finished with error(s)"
    PackageLog "============================================================================"

    'Log to EventViewer
    EventErrLog "Finished with error(s)"
  Else
    'log to LogFile
    MainLog "Finished successfully"
    MainLog "============================================================================"

    'log to Package LogFile
    PackageLog "----------------------------------------------------------------------------"
    PackageLog "Finished successfully"
    PackageLog "============================================================================"

    'Log to EventViewer
    EventErrLog "Finished successfully"
  End If

  'log to Registry
  If sJobID <> cstUninstallJob Then
    If bErrorOccured Then
      WshShell.RegWrite sRegPackageLog & "\Status", cstInstallFailed
      WshShell.RegWrite sRegPackageLog & "\Result", sErrorMessage
    Else
      WshShell.RegWrite sRegPackageLog & "\Status", cstInstalled
      WshShell.RegDelete sRegPackageLog & "\Progress"
      WshShell.RegWrite sRegPackageLog & "\Result", "Completed successfully at " & Now
      WshShell.RegWrite sRegPackagesLog & "\" & sPackageName & "\LastInstalledVersion",sPackageVersion
    End If
  ElseIf sJobID = cstUninstallJob Then
    If Not bErrorOccured Then
      WshShell.RegDelete sRegPackagesLog & "\" & sPackageName & "\" & sPackageVersion & "\"
      WshShell.RegDelete sRegPackagesLog & "\" & sPackageName & "\LastInstalledVersion"
    Else
      WshShell.RegWrite sRegPackageLog & "\Status", cstUninstallFailed
      WshShell.RegWrite sRegPackageLog & "\Progress", Status
    End If
  End If

  If Mode = cstInteractiveMode Then
    If bErrorOccured Then
      WshShell.Popup MsgJobFailed, 5, sMessageTitle, vbCritical
    Else
      WshShell.Popup MsgJobFinishedSuccesfully, 5, sMessageTitle, vbInformation
    End If
  End If

  WshProcEnv.Remove("SEE_MASK_NOZONECHECKS")

  If (Not bErrorOccured) Or (sAutoLogonStatus = "EXECPKG") Then
    Call RebootProcess
  Else
    MainLog Null
    MainLog Null
    If bErrorOccured Then
      If iErrorExitCode <> 0 Then
         WScript.Quit(iErrorExitCode)
      Else
         WScript.Quit(-1)
      End If
    Else
      If bRebootRequired Then
         '
         If bIsSCCM Then
            Set SCCM = New clsSCCM
            If SCCM.IsTaskSequence Then
               WScript.Quit(0)
            End If
         End If
         If bIsLANDESK Then
            ' LANDesk retries installing if return value <> 0
            WScript.Quit(0)
         End If
         WScript.Quit(3010)
         '
      Else
         WScript.Quit(0)
      End If
    End If
  End If

End Sub

'-------------------------------------------------------------------------------------------------------
Sub GroupsProcess

   '-------------------
   ' Purpose:	Create local groups and add global groups into local groups
   ' Type:	Sub
   ' Input:	None
   '-------------------

  On Error Resume Next
  Err.Clear 
  If Groups.Count > 0 Then
    Array1 = Groups.Items
    For i = 0 to Groups.Count - 1
      sSettings	= Array1(i)
      Array2	= Split(sSettings,"---")
      sGG	= TRIM(Array2(0))
      sLG	= TRIM(Array2(1))
      sLGDesc	= TRIM(Array2(2))
      WshShell.Run "cmd /c net localgroup " & Chr(34) & sLG & Chr(34) & " /add /comment:" & Chr(34) & sLGDesc & Chr(34), 0, True
      RuntimeErrLog
      WshShell.Run "cmd /c net localgroup " & Chr(34) & sLG & Chr(34) & " " & Chr(34) & sUserDomain & "\" & sGG & Chr(34) & " /Add", 0, True
      RuntimeErrLog
      PackageLog "Global Group " & sGG & " added to Local Group " & sLG
    Next
  End If
  Err.Clear
End Sub



'-------------------------------------------------------------------------------------------------------
Sub AdjustCU

   '-------------------
   ' Purpose:	Prepare user component
   ' Type:	Sub
   ' Input:	None
   '-------------------

   On Error Resume Next
   If sJobID = cstInstallJob Or sJobID = cstReinstallJob Then
      If fso.FolderExists(sCurrentfolder & "\CU") Then
         If Not sAdjustCUFolder = "" Then
            Err.Clear
            If Not fso.FolderExists (sAdjustCUFolder) Then 
               MainLog "Create folder " & sAdjustCUFolder
			   MakeFolder sWindir & "\INS\"
               MakeFolder sAdjustCUFolder
			   MakeFolder sAdjustCUFolder & "\Always"
			   MakeFolder sAdjustCUFolder & "\Once"
			   If OSType = OSNT4 Or OSType = OSW2K Or OSType = OSW2K3 Or OSType = OSXP Then
					SetSecurity ReplaceSecurity, sAdjustCUFolder, LocalGroup(cstAdministrators) & ":F System:F " & LocalGroup(cstEveryone) & ":R"
				Else
					SetISecurity ReplaceSecurity, sAdjustCUFolder, LocalGroup(cstAdministrators) & ":(OI)(CI)F System:(OI)(CI)F " & LocalGroup(cstEveryone) & ":(OI)(CI)R"
				End If
            End If
            If fso.FolderExists(sCurrentFolder & "\CU\Once") Then
               sTargetOnceDir = Replace(sAdjustCUFolder & "\CU\Once\" & sPackageName, " ", "_")
               fso.DeleteFolder sTargetOnceDir & ".*", True
			   MakeFolder sWindir & "\INS\"
               MakeFolder sTargetOnceDir & "." & sPackageVersion
               fso.CopyFolder sCurrentFolder & "\CU\Once", sTargetOnceDir & "." & sPackageVersion, True
            End If
            If fso.FolderExists(sCurrentFolder & "\CU\Always") Then
               sTargetAlwaysDir = Replace(sAdjustCUFolder & "\CU\Always\" & sPackageName, " ", "_")
               fso.DeleteFolder sTargetAlwaysDir & ".*", True
			   MakeFolder sWindir & "\INS\"
               MakeFolder sTargetAlwaysDir & "." & sPackageVersion
               fso.CopyFolder sCurrentFolder & "\CU\Always", sTargetAlwaysDir & "." & sPackageVersion, True
            End If
            PackageLog "User component folders copied to " & sAdjustCUFolder
            Err.clear
         Else
            MainErrLog "AdjustCUFolder parameter not defined in RAT!"
         End If
      End If
      Err.Clear
   ElseIf sJobID = cstUninstallJob Then
      PackageLog "Delete user component folders"
      sTargetOnceDir = Replace(sAdjustCUFolder & "\CU\Once\" & sPackageName, " ", "_")
      sTargetAlwaysDir = Replace(sAdjustCUFolder & "\CU\Always\" & sPackageName, " ", "_")
      fso.DeleteFolder sTargetOnceDir & "." & sPackageVersion, True
      fso.DeleteFolder sTargetAlwaysDir & "." & sPackageVersion, True
      Err.clear
   End If
End Sub

'-------------------------------------------------------------------------------------------------------
Sub RebootProcess

   '-------------------
   ' Purpose:	Determines how to handle a system reboot (notify user or not?)
   ' Type:	Sub
   ' Input:	None
   '-------------------

  On Error Resume Next
  Select Case OSLanguage
     Case cstDutchNetherlands
        MsgSystemMustRestart = "De computer moet herstart worden."
        MsgAskDoYouWantToRestartNow = "Wilt u de computer nu herstarten ?"
        MsgWarningSystemRebootIn30Minutes = "WAARSCHUWING! Het systeem zal herstarten binnen 30 minuten!"
        MsgWarningSystemRebootNow = "WAARSCHUWING! Het systeem zal NU herstarten!"
        MsgRestartForNewSettings = "De computer moet herstart worden om de wijzigingen door te voeren."
        MsgInstallationFinished = "Installatie van " & sApplicationName & " " & sApplicationVersion & " is succesvol beeindigd."
        MsgInstallationFailed = "Installatie van " & sApplicationName & " " & sApplicationVersion & " is gefaald."
     Case cstFrenchFrance
        MsgSystemMustRestart = "Votre PC doit rebooter."
        MsgAskDoYouWantToRestartNow = "Voulez-vous rebooter maintenant ?"
        MsgWarningSystemRebootIn30Minutes = "RAPPEL! Votre PC va rebooter dans 30 minutes!"
        MsgWarningSystemRebootNow = "RAPPEL! Votre PC va rebooter MAINTENANT!"
        MsgRestartForNewSettings = "Votre pc va rebooter afin d’appliquer les modifications."
        MsgInstallationFinished = "Installation of " & sApplicationName & " " & sApplicationVersion & " finished successfully"
        MsgInstallationFailed = "Installation of " & sApplicationName & " " & sApplicationVersion & " finished with error(s)"
     Case Else
        MsgSystemMustRestart = "The system must restart your computer."
        MsgAskDoYouWantToRestartNow = "Do you want to restart your computer now ?"
        MsgWarningSystemRebootIn30Minutes = "WARNING! The system will reboot in 30 minutes!"
        MsgWarningSystemRebootNow = "WARNING! The system will reboot NOW!"
        MsgRestartForNewSettings = "You must restart your computer before the new settings will take effect."
        MsgInstallationFinished = "Installation of " & sApplicationName & " " & sApplicationVersion & " finished successfully"
        MsgInstallationFailed = "Installation of " & sApplicationName & " " & sApplicationVersion & " finished with error(s)"
  End Select

  WshProcEnv.Remove("SEE_MASK_NOZONECHECKS")

  Select Case Mode
     Case cstInteractiveMode
        If bRebootRequired Then
           If bErrorOccured Then
              return = WshShell.Popup(MsgInstallationFailed & _
                       VbCrLf & MsgRestartForNewSettings & _
                       VbCrLf & VbCrLf & MsgAskDoYouWantToRestartNow, , sMessageTitle, vbInformation + vbYesNo + vbDefaultButton2)
           Else
              return = WshShell.Popup(MsgInstallationFinished & _
                       VbCrLf & MsgRestartForNewSettings & _
                       VbCrLf & VbCrLf & MsgAskDoYouWantToRestartNow, , sMessageTitle, vbInformation + vbYesNo + vbDefaultButton2)
           End If
           If return = vbYes Then
              Call Reboot
           End If
        End If
     Case cstINSRatMode, cstSilentMode
        If (Not bExternalRebootProcess) Or (Mode = cstINSRatMode) Then
           Select Case WinlogonStatus
              Case cstWinlogonUserLoggedOn
                 ' A user is logged on
                 If sAutoLogonStatus = "INITIALIZE" Then
                    WshShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\NoLogoff", "1", "REG_DWORD"
                    return = WshShell.Popup(MsgSystemMustRestart & _
                             VbCrLf & VbCrLf & MsgAskDoYouWantToRestartNow, 7200, sMessageTitle, vbInformation + vbYesNo + vbDefaultButton2)
                    If return = vbNo Then
                       MainLog "* The user choosed to postpone the reboot of the system." & vbCrLf & VbCrLf
                       WScript.Sleep 1800 * 1000
                       return = WshShell.Popup(MsgWarningSystemRebootIn30Minutes & _
                                VbCrLf & VbCrLf & MsgAskDoYouWantToRestartNow, 1800, sMessageTitle, vbExclamation + vbYesNo + vbDefaultButton2)
                       If return = vbNo Then
                          MainLog "* The user choosed to postpone the reboot of the system." & vbCrLf & vbCrLf
                          WScript.Sleep 1800 * 1000
                          WshShell.Popup MsgWarningSystemRebootNow, 300, sMessageTitle, vbExclamation
                          Call Reboot
                       Else
                          Call Reboot
                       End If
                    Else
                       Call Reboot
                    End If
                 ElseIf sAutoLogonStatus = "EXECPKG" Then
                    Call Reboot
                 ElseIf bRebootRequired Then
                    If bScriptingToolboxInstalled And bUseScriptingToolbox Then
                       Call SetRebootPending
                       ' Wait for the reboot to occure
                       Do While RebootIsPending
                          WScript.Sleep 60000
                       Loop
                    Else
                       If bErrorOccured Then
                          return = WshShell.Popup(MsgInstallationFailed & _
                                   VbCrLf & MsgRestartForNewSettings & _
                                   VbCrLf & VbCrLf & MsgAskDoYouWantToRestartNow, , sMessageTitle, vbInformation + vbYesNo + vbDefaultButton2)
                       Else
                          return = WshShell.Popup(MsgInstallationFinished & _
                                   VbCrLf & MsgRestartForNewSettings & _
                                   VbCrLf & VbCrLf & MsgAskDoYouWantToRestartNow, , sMessageTitle, vbInformation + vbYesNo + vbDefaultButton2)
                       End If
                       If return = vbNo Then
'                           If Mode = cstINSRatMode Then
                          If IsEmpty(iShowRebootMessage) Then
                             iShowRebootMessage = 3
                          End If
                          WScript.Sleep 30 * 60 * 1000
                          Do While (iRebootMessageShown < iShowRebootMessage) Or (iShowRebootMessage = 0)
                             return = WshShell.Popup(MsgSystemMustRestart & VbCrLf & VbCrLf & MsgAskDoYouWantToRestartNow, 30 * 60, sMessageTitle, vbExclamation + vbYesNo + vbDefaultButton2)
                             iRebootMessageShown = iRebootMessageShown + 1
                             If return = vbYes Then
                                Call Reboot
                             Else
                                WScript.Sleep 30 * 60 * 1000
                             End If
                          Loop
                          WshShell.Popup MsgWarningSystemRebootNow, 300, sMessageTitle, vbExclamation
                          Call Reboot
'                           End If
                       Else
                          Call Reboot
                       End If
                    End If
                 End If
  
              Case cstWinlogonNoUserLoggedOn
                 ' No user is logged on
                 If bRebootRequired Or sAutoLogonStatus = "INITIALIZE" Then
                    Call Reboot
                 End if  
              Case Else
                 ' WinlogonStatus = Unknown
                 MainErrLog "Unknown WinlogonStatus"
                 MainErrLog WinlogonStatus
                 If bRebootRequired Then
                    WshShell.Popup "Unknown WinlogonStatus. Please reboot the system !"
                 End If
           End Select
        End If
  End Select
  
  MainLog Null
  MainLog Null

  If bErrorOccured Then
     If iErrorExitCode <> 0 Then
        WScript.Quit(iErrorExitCode)
     Else
        WScript.Quit(-1)
     End If
  Else
    If bRebootRequired Then
       '
       If bIsSCCM Then
          Set SCCM = New clsSCCM
          If SCCM.IsTaskSequence Then
             WScript.Quit(0)
          End If
       End If
       If bIsLANDESK Then
          ' LANDesk retries installing if return value <> 0
          WScript.Quit(0)
       End If
       WScript.Quit(3010)
       '
    Else
       WScript.Quit(0)
    End If
  End If

End Sub

'-------------------------------------------------------------------------------------------------------
Sub ShowMessage(sItem)

   '-------------------
   ' Purpose:	Shows a message box / progress bar
   ' Type:	Sub
   ' Input:	sItem: Text to show (Type: string)
   '-------------------

  On Error Resume Next
  If (Mode = cstInteractiveMode) Or (Not bDontShowMessage) Then
    Select Case OSType
       Case OSNT4, OSW2K, OSW2K3, OSXP
          If fso.FileExists(sCurrentFolder & "\INS\" & OSArchitecture & "\PackMsg.exe") Then
             WshShell.Run Chr(34) & sCurrentFolder & "\INS\" & OSArchitecture & "\PackMsg.exe" & Chr(34), 1, False
          Else
             If fso.FileExists(sCurrentFolder & "\INS\PackMsg.exe") Then
               WshShell.Run Chr(34) & sCurrentFolder & "\INS\PackMsg.exe" & Chr(34), 1, False
             Else
               MainLog "PackMsg.exe not found"
             End If
          End If
       Case Else
          ' On Windows Vista the PackMsg.exe is launched by the user
    End Select
  End If
  Err.Clear
End Sub

'-------------------------------------------------------------------------------------------------------
Sub UpdateMessage(sMessageTitle, sMessageStatus, sMessage)

   '-------------------
   ' Purpose:	Update the message box / progress bar
   ' Type:	Sub
   ' Input:
   '		sMessageTitle: Title of the progress bar (Type: string)
   ' 		sMessageStatus: Progress of the progress bar (Type: string)
   ' 		sMessage: Message to show on the progress bar (Type: string)
   '-------------------

  On Error Resume Next
  If (Mode = cstInteractiveMode) Or (Not bDontShowMessage) Then
     WshShell.RegWrite "HKEY_LOCAL_MACHINE\SOFTWARE\INS\PackMsg\Title", sMessageTitle
     WshShell.RegWrite "HKEY_LOCAL_MACHINE\SOFTWARE\INS\PackMsg\Progress", sMessageStatus
     WshShell.RegWrite "HKEY_LOCAL_MACHINE\SOFTWARE\INS\PackMsg\Message", sMessage
  End If
  Err.Clear
End Sub

'-------------------------------------------------------------------------------------------------------
Sub Reboot

   '-------------------
   ' Purpose:	Performs a system reboot
   ' Type:	Sub
   ' Input:	None
   '-------------------

  On Error Resume Next
  Err.Clear

  Select Case OSLanguage
     Case cstDutchNetherlands
        MsgAutomatedRebootFailed = "De automatisch herstart is niet gelukt. Gelieve de computer manueel te herstarten."
     Case cstFrenchFrance
        MsgAutomatedRebootFailed = "Le reboot automatic n'a pas reussi. Veuillez rebooter, svp."
     Case Else
        MsgAutomatedRebootFailed = "Automated reboot failed. Please restart your computer manually."
  End Select

  If sAutoLogonStatus = "INITIALIZE" Then
    MainLog "* Reboot system"
  Else
    MainLog "* Reboot system" & VbCrlf
  End If
  WshShell.RegDelete "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\NoLogoff"

  Set objService = GetObject("WinMgmts:Win32_Service.Name='RATAgent'")
  If objService.State = "Running" Then
    MainLog "Stopping the RAT Agent service" & VbCrlf
    objService.StopService
  End If

  If bKillScreenSaverOnReboot Then
     WshShell.Run "taskkill.exe /F /IM logon.scr", 0, True
     Err.Clear
  End If

  If bAutoLogon Then
     MainLog "Rebooting (during AutoLogon " & sAutoLogonStatus & ")..."
     WshShell.Run "shutdown.exe -r -t 0 -f", 0, True
     WScript.Quit
  End If

  For i = 1 To 10
     MainLog "rebooting..."
     Set oOS = GetObject("WinMgmts:{(Shutdown)}").ExecQuery("SELECT * FROM Win32_OperatingSystem") 
     For Each oOperatingSystem In oOS 
        oOperatingSystem.Win32Shutdown(6)  '6 = forced reboot, 2 = reboot
     Next
     WScript.Sleep 1 * 60 * 1000
  Next

  MainErrLog "* Automated reboot failed (after 10 minutes)"
  WshShell.Popup MsgAutomatedRebootFailed, 20, sMessageTitle, vbCritical
  WScript.Quit
End Sub

'-------------------------------------------------------------------------------------------------------
Sub PowerOff

   '-------------------
   ' Purpose:	Performs a system shutdown
   ' Type:	Sub
   ' Input:	None
   '-------------------

  On Error Resume Next
  Err.Clear

  Select Case OSLanguage
     Case cstDutchNetherlands
        MsgAutomatedPowerOffFailed = "De automatisch power-off is niet gelukt. Gelieve de computer manueel af te sluiten."
     Case cstFrenchFrance
        MsgAutomatedPowerOffFailed = "L'arret automatic n'a pas reussi. Veuillez arreter l'ordinateur, svp."
     Case Else
        MsgAutomatedPowerOffFailed = "Automated power off failed. Please shutdown your computer manually."
  End Select

  MainLog "* Power Off system" & VbCrLf
  Set oOS = GetObject("winmgmts:{(Shutdown)}").ExecQuery("Select * from Win32_OperatingSystem") 
  For Each oOperatingSystem in oOS 
    oOperatingSystem.Win32Shutdown(12)  '12 = forced power down, 8 = power down
  Next 
  If Err <> 0 Then
    MainErrLog "* Automated power off failed : " & Err.Number & " : " & Err.Description
    WshShell.Popup MsgAutomatedPowerOffFailed, , sMessageTitle, vbCritical
  End If
End Sub

'-------------------------------------------------------------------------------------------------------
Sub PrepareNextStep(iStep)

   '-------------------
   ' Purpose:	Prepare the next step for a package divided by reboots
   ' Type:	Sub
   ' Input:	iStep: Step number (Type: integer)
   '-------------------

   On Error Resume Next

   If bLANDeskEnabled Then

      PackageLog "AutoLogonNext: PrepareNextStep " & iStep
      If iStep <> 0 Then
         sSubFolderPackage = Replace(sPackageName," ", "")
         strShellCommand = "wscript.exe //Job:" & sJobID & " " & Chr(34) & sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion & "\" & Wscript.Scriptname & Chr(34) & " /AutoLogon:EXECPKG"  & " /Step:" & iStep
         strExecuteAfterRebootCommand = "wscript.exe //Job:" & sJobID & " " & chr(34) & sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion & "\" & Wscript.Scriptname & chr(34) & " /AutoLogon:RunCheck"
         If Mode = cstInteractiveMode Then
            strShellCommand = strShellCommand & " /mode:" & cstSilentMode
            strExecuteAfterRebootCommand = strExecuteAfterRebootCommand & " /mode:" & cstSilentMode
         Else
            strShellCommand = strShellCommand & " /mode:" & mode
            strExecuteAfterRebootCommand = strExecuteAfterRebootCommand & " /mode:" & mode
         End If
         PackageLog "AutoLogonNext: New Shell-command: " & strShellCommand
         MyAutoLogon.SetAutoLogon strShellCommand, True
         
         If bDisableInput = True Then
            PackageLog "AutoLogonNext: Disable Input Devices"
            MyAutoLogon.DisableInput
         End If

         MainLog "AutoLogonNext: Reboot by Autologon procedure"
         PackageLog "AutoLogonNext: Reboot by Autologon procedure"
         Reboot
      Else
         PackageLog "AutoLogonNext: all steps completed"
      End If

   Else
      MainErrLog "This function (PrepareNextStep) can not be used in a non-RAT environment!"
   End If
End Sub

'-------------------------------------------------------------------------------------------------------
Sub PrepareNextPhase(bReboot)

   '-------------------
   ' Purpose:	Prepare the next phase for a package divided by reboots
   ' Type:	Sub
   ' Input:	bReboot: Specifies if the script should do the reboot (Type: boolean)
   '-------------------

   If bIsLANDESK Then
      iPhase = iPhase + 1
      PackageLog "Preparing for Phase " & iPhase
      WshShell.RegWrite sRegPackagePhase, iPhase
      If bReboot Then
         PackageLog "Preparing for a reboot"
         bRebootRequired = True
         RebootProcess
      Else
         PackageLog "Waiting for the setup to do a reboot"
      End If
   Else
      MainErrLog "This function (PrepareNextPhase) can not be used in a non-RAT environment!"
   End If
End Sub

'-------------------------------------------------------------------------------------------------------
Function ReadIniFile(sIniFile,sSection,sKey)

   '-------------------
   ' Purpose:	Read value from a parameter in an ini file
   ' Type:	Function
   ' Input:
   '		sIniFile: Full path of the INI file (Type: string)
   ' 		sSection: Section in the INI file (Type: string)
   ' 		sKey: Key in the INI file (Type: string)
   ' Output:	String containing the value from the INI file
   '-------------------

  On Error Resume Next
 'create a dynamic array and put each line of the file in it
  Dim LineArray()
  Redim LineArray(0)
  LineArray(0)=""
  Set file = fso.OpenTextFile(sIniFile, 1)
  Do Until File.AtEndOfStream
    LineArray(Ubound(LineArray, 1)) = file.ReadLine  
    If not LineArray(0) = "" Then Redim Preserve LineArray(Ubound(LineArray, 1) + 1)
  Loop
  file.Close
  Set file = Nothing
  
  'check if section exists and check if value exists in the keys until the next section is reached(or end of file)
  For x = 0 to Ubound(LineArray,1)
    If Instr(1,UCase(LineArray(x)),"[" & UCase(sSection) & "]",vbTextCompare) = 1 Then 'section is found
      For y = x+1 to Ubound(LineArray,1)
        If Instr(1,LineArray(y),"[",vbTextCompare) = 1 Then 'next section is reached
         Exit Function
        Else
          If Instr(1,UCase(LineArray(y)),UCase(sKey),VbTextCompare) <> 0 Then
            Splitline = Split(LineArray(y),"=",2,vbTextCompare)	    
            If UCase(sKey) = UCase(Trim(Splitline(0))) Then
              ReadIniFile = Trim(SplitLine(1))
              Exit Function
            End if
          End If
        End If
      Next
    End if
  Next

End Function

'-------------------------------------------------------------------------------------------------------
Sub WriteIniFile(sIniFile,sSection,sKey,sValue)

   '-------------------
   ' Purpose:	Writes a value in a parameter in an ini file
   ' Type:	Sub
   ' Input:
   '		sIniFile: Full path of the INI file (Type: string)
   ' 		sSection: Section in the INI file (Type: string)
   ' 		sKey: Key in the INI file (Type: string)
   ' 		sKey: Value of the key in the INI file (Type: string)
   '-------------------

On Error Resume Next

If fso.FileExists (sIniFile) Then  'File exists

 'create a dynamic array and put each line of the file in it
 Dim file
 Dim LineArray()
 Redim LineArray(0)
 LineArray(0)=""
 Set file = fso.OpenTextFile(sIniFile, 1)
 Do Until File.AtEndOfStream
  LineArray(Ubound(LineArray, 1)) = file.ReadLine  
  If Not LineArray(0) = "" Then Redim Preserve LineArray(Ubound(LineArray, 1) + 1)
 Loop
 file.Close
 Set file = Nothing

 Dim x, y, z
 Dim SectionFound, KeyFound, LastSection, Splitline, KeyWithoutTabs
 'go through each line and search for section
 SectionFound = "NO"
 For x = 0 to Ubound(LineArray,1)
  If Instr(1,UCase(LineArray(x)),"[" & UCase(sSection) & "]",vbTextCompare) = 1 Then 'section is found
   SectionFound = "YES"
   KeyFound = "NO"
   If sKey = "" Then 'delete the section
    LastSection ="YES"
    For y = x+1 to Ubound(LineArray,1) 
     If Instr(1,LineArray(y),"[",vbTextCompare) = 1 Then 'next section is reached 
      LastSection = "NO"
      For z = x to y-1
       LineArray(z) = ""
      Next
      Exit For
     End If
    Next
    If LastSection = "YES" Then 'the section was the last section
     For z = x to Ubound(LineArray,1)
      LineArray(z) = ""
     Next
     Exit For
    End If
   
   Else 'key is not empty, search for key
    For y = x+1 to Ubound(LineArray,1)
     If Instr(1,LineArray(y),"[",vbTextCompare) = 1 Then 'next section is reached without the key being found
      Redim Preserve LineArray(Ubound(LineArray,1) +1) 'add 1 element to the array
      For z = Ubound(LineArray,1) to x+2 Step -1  'move each element 1 line down in the array
       LineArray(z) = LineArray(z-1)
      Next
      LineArray(x+1) = sKey & "=" & sValue
      KeyFound = ""
      Exit For
     Else
      If Instr(1,UCase(LineArray(y)),UCase(sKey),VbTextCompare) <> 0 Then 'key has been found 
       Splitline = Split(LineArray(y),"=",2,vbTextCompare)
       KeyWithoutTabs = replace(Splitline(0),chr(9),chr(32),1,-1,1) 'replace tabs with spaces    
       If UCase(sKey) = UCase(Trim(KeyWithoutTabs)) Then
        KeyFound = "YES"
        If sValue = "" Then
         LineArray(y) = ""
        Else
         LineArray(y) = sKey & "=" & sValue
        End If
        Exit For
       End if
      End If
     End If
    Next
    If KeyFound = "NO" Then  'reached the end of the array without the key found
     LineArray(Ubound(LineArray,1)) = sKey & "=" & sValue
    End If
   End If
  End if
 Next

 'compose the file
 Set file = fso.OpenTextFile(sIniFile, 2)
 For x = 0 to Ubound(LineArray,1)
  If LineArray(x) <> "" Then
   file.WriteLine LineArray(x)
  End If
 Next
 file.Close
 Set file = Nothing

 If SectionFound = "NO" Then 
  'Section does not exist, add a section to the existing file
  If sKey <> "" and sValue <> "" Then
   Set file = fso.OpenTextFile(sIniFile, 8)
   File.WriteLine "[" & sSection & "]"
   File.WriteLine sKey & "=" & sValue 
   File.Close
   Set file = Nothing
  End If
 End If
  
Else  'File does not exist, create a new file and add the section to it
 err.clear
 Set File = fso.CreateTextFile(sInifile, True)
 If err <> 0 then
  LogItem vbtab & "! ERROR : Unable to create the Inifile '" & sIniFile & "'"
 Else 
  File.WriteLine "[" & sSection & "]"
  File.WriteLine sKey & "=" & sValue 
  File.Close
 End If
End if

End Sub


'-------------------------------------------------------------------------------------------------------
Sub Overwrite(sTargetFile, sFindString, sReplaceWith)

   '-------------------
   ' Purpose:	Overwrites a text string by another text string in a text file
   ' Type:	Sub
   ' Input:
   '		sTargetFile: Full path of the file (Type: string)
   ' 		sFindString: Text to find in the file (Type: string)
   ' 		sReplaceWith: New text to be placed in the file (Type: string)
   ' Other:	Better use 'ReplaceTextInFile' (but this one is needed for backward compatibility)
   '-------------------

   On Error Resume Next
   Set file1 = fso.OpenTextFile(sTargetFile, 1)
   sOldfile  =  file1.ReadAll
   file1.close
   sNewFile = Replace(sOldfile,sFindString,sReplaceWith,1,-1,vbTextCompare)
   Set file2 = fso.CreateTextFile(sTargetFile, True)
   file2.WriteLine sNewFile
   file2.Close
End Sub

'-------------------------------------------------------------------------------------------------------
Sub HoldIssSetup

   '-------------------
   ' Purpose:	Monitors an ISS Setup and checks the ISS log file for the resultcode
   ' Type:	Sub
   ' Input:	None
   '-------------------

 On Error Resume Next
 Installation = "Ongoing"
 Do While Installation = "Ongoing"
  Wscript.Sleep 10000
  If fso.FileExists(sSetupLogFile) Then
    sResultCode = ReadIniFile(sSetupLogFile, "ResponseResult", "ResultCode")
    If sResultCode = "" Then	'Installation is not finished yet, loop again
    ElseIf sResultCode = "0" Then
      PackageLog "Resultcode = 0"
      Installation = "Finished"
      Exit Do
    Else				'if an error occurs, log the error but continue installation
      Err.Raise 3001, "WSH", "HoldIssSetup failed with ResultCode = " & sResultCode
      RuntimeErrLog
      Installation = "Finished"
      Exit Do
    End If

  Else		'logfile does not exist, should be created by setup.exe instantly
    Err.Raise 3002, "WSH", "HoldIssSetup failed to create ISS logfile"
    RuntimeErrLog
    EndLog
  End If
 Loop
End Sub

'-------------------------------------------------------------------------------------------------------
Sub MapFreeDrive(sShare)

   '-------------------
   ' Purpose:	Creates a network mapping to a share with a free drive letter
   ' Type:	Sub
   ' Input:	sShare: Full UNC path for the drive to map (Type: string)
   '-------------------

  On Error Resume Next
  For x = 26 to 5 Step -1
    sDrive = Chr(x + 64) & ":"
    Err.Clear
    WSHNetwork.MapNetworkDrive sDrive, sShare, False
    If Err = 0 Then 
      Exit For
    End If
  Next

  'Check if a free drive letter is found
  Set sCheckDrive	= fso.GetDrive(fso.GetDriveName(fso.GetAbsolutePathName(sDrive)))
  sCheckShare	= sCheckDrive.ShareName
  If UCase(sShare) <> UCase(sCheckShare) Then
    Err.Raise 4001, "WSH", "Could not connect to " & sShare
    RuntimeErrLog
  End If
End Sub

'-------------------------------------------------------------------------------------------------------
Sub AddToPath(sStringToAdd)

   '-------------------
   ' Purpose:	Adds entry to the environment variable 'path'
   ' Type:	Sub
   ' Input:	sStringToAdd: Text to add to the Path variable (Type: string)
   '-------------------

   On Error Resume Next
   Err.clear
   sPath = WshShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path") 
   Return = InStr(1, sPath, sStringToAdd, vbTextCompare)
   If Return < 1 Then
      PackageLog "Adding '" & sStringToAdd & "' to the Path variable"
      sNewPath = sPath & ";" & sStringToAdd
      WshShell.RegWrite "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path", sNewPath, "REG_EXPAND_SZ"
      RuntimeErrLog
   Else
      PackageLog "The entry '" & sStringToAdd &"' already exists in the Path variable"
   End If
End Sub 

'--------------------------------------------------------------------------------------------------------------
Sub RemoveFromPath(sStringToRemove)

   '-------------------
   ' Purpose:	Remove entry from the system environment variable 'path'
   ' Type:	Sub
   ' Input:	sStringToRemove: Text to remove from the Path variable (Type: string)
   '-------------------

   On Error Resume Next
   Err.Clear
   sPath = WshShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path") 
   sPath = ";" & sPath & ";"
   Return = InStr(1, sPath, ";" & sStringToRemove & ";", vbTextCompare)
   If return < 1 Then
      PackageLog "'" & sStringToRemove & "' not found in the Path variable"
   Else
      PackageLog "Removing '" & sStringToRemove & "' from the Path variable"
      sNewpath = Replace (sPath, ";" & sStringToRemove & ";", ";", 1, -1, vbTextCompare)
      If Left (sNewpath, 1) = ";" Then
         sNewpath = Right(sNewpath, Len(sNewpath) - 1)
      End If
      If Right(sNewpath, 1) = ";" Then 
         sNewpath = Left(sNewpath, Len(sNewpath) - 1)
      End If 
      WshShell.RegWrite "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path", sNewPath, "REG_EXPAND_SZ"
   End if
End Sub

'--------------------------------------------------------------------------------------------------------------
Sub MakeFolder(sFullFolderName)

   '-------------------
   ' Purpose:	Creates a complete folderstructure (easier than fso.CreateFolder)
   ' Type:	Sub
   ' Input:	sFullFolderName: Name of the folder to be created (Type: string)
   '-------------------

  On Error Resume Next
  Err.Clear
  sDrive = Mid(sFullFolderName, 1, 2)
  If fso.DriveExists(sDrive) Then
    iStartPosition = 3
    iEndPosition = 4
    sFolderName = sDrive
    Do While InStr(iEndPosition, sFullFolderName, "\", vbTextCompare) > 0
      iEndPosition = InStr(iEndPosition, sFullFolderName, "\", vbTextCompare)
      sFolderName = sFolderName & "\" & Mid(sFullFolderName, iStartPosition + 1, iEndPosition - iStartPosition - 1)
      iStartPosition = iEndPosition
      iEndPosition = iEndPosition + 1
      If Not fso.FolderExists(sFolderName) Then fso.CreateFolder sFolderName
    Loop
    sFolderName = sFolderName & "\" & Mid(sFullFolderName, iEndPosition, (Len(sFullFolderName) - iEndPosition + 1))
    If Not fso.FolderExists(sFolderName) Then fso.CreateFolder sFolderName
  Else
    Err.Raise 1001, "WSH", "Drive " & sDrive & " does not exist"
  End If
  RuntimeErrLog
End Sub


'--------------------------------------------------------------------------------------------------------------
Sub RemoveAttributes(sFolder)

   '-------------------
   ' Purpose:	Remove the attributes from a folder, subfolders and files
   ' Type:	Sub
   ' Input:	sFolder: Name of the folder (Type: string)
   '-------------------

  On Error Resume Next
  'Start
  Set StartFolder = fso.GetFolder(sFolder)
  StartFolder.Attributes = 0

  'Enum Folders
  Set SubFolders = StartFolder.SubFolders
  For Each Folder In SubFolders
    Folder.Attributes = 0
    RemoveAttributes(Folder)
  Next

  'Enum Files
  Set StartFiles = StartFolder.Files
  For Each File In StartFiles
    File.Attributes = 0
  Next

End Sub

'-------------------------------------------------------------------------------------------------------
Function ConnectShare(sServer, sShare)

   '-------------------
   ' Purpose:	Connects to a share (without using a drive letter)
   ' Type:	Function
   ' Input:
   '		sServer: Name of the server (Type: string)
   ' 		sShare: Name of the share (Type: string)
   ' Output:	Boolean returning True if the connect was successfull
   '-------------------

  On Error Resume Next
  ConnectShare = False
  Err.Clear
  WshNetwork.MapNetworkDrive "", "\\" & sServer & "\" & sShare, False
  If Err <> 0 Then
    PackageLog "Unable to connect to \\" & sServer & "\" & sShare
  Else
    PackageLog "Connected to \\" & sServer & "\" & sShare
    ConnectShare = True
  End If
  Err.Clear
End Function

'-------------------------------------------------------------------------------------------------------
Sub FindSources(strLocation)

   '-------------------
   ' Purpose:	Find the sources for the package
   ' Type:	Sub
   ' Input:	strLocation: Parameter defining where to find the sources (Type: string)
   '			Possible values are:
   ' 				"DistributionServerOrRolloutServer"
   ' 				"DistributionServer"
   ' 				"SourcesFolder"
   ' 				"RolloutServer"
   ' 				"CurrentFolder"
   ' 				"OfflineSources"
   ' 				"ParentFolder"
   ' 				"CurrentOrParentFolder"
   '-------------------

  On Error Resume Next

  Dim intPackagesStartString, sRootFolder
  Dim objShell, objFolder, objFolderItem

  If bSourcesRequired Then
    Status = 4
    Select Case UCase(strLocation)
      Case "DISTRIBUTIONSERVERORROLLOUTSERVER"
        PackageLog "Finding sources on the local Distribution Server"
        sSourcePath = "\\" & sDistributionServer & "\" & sDistributionShare & "\" & sSourcesFolderName
        If Not fso.FolderExists(sSourcePath) Then
          PackageLog "Finding sources on the local Rollout Server"
          sSourcePath = "\\" & sRolloutServer & "\" & sRolloutSourcesShare & "\" & sSourcesFolderName
        End If
      Case "ROLLOUTSERVER"
        PackageLog "Finding sources on the local Rollout Server"
        sSourcePath = "\\" & sRolloutServer & "\" & sRolloutSourcesShare & "\" & sSourcesFolderName
      Case "DISTRIBUTIONSERVER"
        PackageLog "Finding sources on the local Distribution Server"
        sSourcePath = "\\" & sDistributionServer & "\" & sDistributionShare & "\" & sSourcesFolderName
      Case "SOURCESFOLDER"
        PackageLog "Finding sources in the Sources folder"
        intPackagesStartString = InStr(UCase(sCurrentFolder), "\PACKAGES\")
        If intPackagesStartString > 0 Then
           sRootFolder = Left(sCurrentFolder, intPackagesStartString)
        End If
        If Right(sRootFolder, 1) = "\" Then
          sSourcePath = sRootFolder & "Sources\" & sSourcesFolderName
        Else
          sSourcePath = sRootFolder & "\Sources\" & sSourcesFolderName
        End If
      Case "CURRENTFOLDER"
        PackageLog "Finding sources in the current folder"
        sSourcePath = sCurrentFolder & "\" & sSourcesFolderName
		If fso.FileExists(sSourcePath & ".7z") Then
			'Unpack Package.7z 
			sCommand=sCurrentFolder & "\INS\7zr.exe"
			sParameters="x """ & sCurrentFolder & "\" & sSourcesFolderName & ".7z"" -o""" & sTemp & "\" & Replace(sPackageName," ","_") & """ -aoa"
			EmersonLog "Running [""" & sCommand & """ " & sParameters & "]"
			sRc = WshShell.Run(Chr(34) & sCommand & Chr(34) & " " & sParameters, 0, True)
			'Redirect sSourcePath to the extracted version
			sSourcePath =  sTemp & "\" & Replace(sPackageName," ","_") & "\" & sSourcesFolderName	
		End If
      Case "OFFLINESOURCES"
        PackageLog "Finding sources on the offline source location"
        sSourcePath = sOfflineSources & "\" & sSourcesFolderName
      Case "PARENTFOLDER"
        PackageLog "Finding sources in the parent folder"
        sSourcePath = sParentFolder & "\" & sSourcesFolderName
      Case "CURRENTORPARENTFOLDER"
        PackageLog "Finding sources in the current folder"
        sSourcePath = sCurrentFolder & "\" & sSourcesFolderName
        If Not fso.FolderExists(sSourcePath) Then
          PackageLog "Finding sources in the parent folder"
          sSourcePath = sParentFolder & "\" & sSourcesFolderName
        End If
      Case Else
        Err.Raise 1005, "Find Sources", "Unknown Sources Location: " & strLocation
        RuntimeErrLog
    End Select
    If (sSourcePath = "") And (Mode = cstInteractiveMode) Then
      PackageLog "Finding sources via user input"
      WshShell.Popup "The sources folder could not be found at the default locations." & VbCrlf & VbCrlf & "You can browse to the " & sSourcesFolderName & " folder after clicking on OK.", 10, sMessageTitle, vbInformation
      Set objShell = CreateObject("Shell.Application")
      Set objFolder = objShell.BrowseForFolder (0, "Browse to the " & sSourcesFolderName & " folder", 0, ssfDRIVES) 
      Set objFolderItem = objFolder.Self
      sSourcePath = objFolderItem.Path
    End If
    If fso.FolderExists(sSourcePath) Then
      PackageLog "Found SourcesFolder=" & sSourcePath
    Else
      Err.Raise 1004, "WSH", "Unable to retrieve " & sSourcePath
      RuntimeErrLog
    End If
  Else
    PackageLog "No sources required"
  End If
End Sub

'--------------------------------------------------------------------------------------------------------------
Function ProcessRunning(sProcess)

   '-------------------
   ' Purpose:	Check for a process running
   ' Type:	Function
   ' Input:	sProcess: Name of the process (Type: string)
   ' Output:	Boolean returning True if the process is running
   '-------------------

  On Error Resume Next
  ProcessRunning = False
  Set Processes = GetObject("WinMgmts:{impersonationLevel=impersonate}").InstancesOf("Win32_Process")
  For Each Process In Processes
    If UCase(Process.Caption) = UCase(sProcess) Then
      ProcessRunning = True
    End If
  Next
End Function

'--------------------------------------------------------------------------------------------------------------
Function KillProcess(sProcess)

   '-------------------
   ' Purpose:	Stops a running process
   ' Type:	Function
   ' Input:	sProcess: Name of the process (Type: string)
   ' Output:	Boolean returning True if the killing the process succeeded
   '-------------------

   On Error Resume Next
   Err.Clear
   Dim bReturn, iTerminateProcessRc, Process
   bReturn = False
   For Each Process In GetObject("WinMgmts:{impersonationLevel=impersonate}").ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & sProcess & "'")
      iTerminateProcessRc = Process.Terminate(0)
      If iTerminateProcessRc <> 0 Then
         Err.Raise 1050, "KillProcess", "Killing Process " & sProcess & " failed with return code " & iTerminateProcessRc
      End If
   Next
   If Err = 0 Then bReturn = True
   Err.Clear
   KillProcess = bReturn
End Function

'--------------------------------------------------------------------------------------------------------------
Function MSIInstalled(sMSIProductCode)

   '-------------------
   ' Purpose:	Verifies if the Product State of an MSI Product Code equals 5 (= Installed)
   ' Type:	Function
   ' Input:	sMSIProductCode: Product Code of the MSI (Type: string)
   ' Output:	Boolean returning True if the MSI is installed
   '-------------------

   On Error Resume Next

   Dim Installer

   Set Installer = WScript.CreateObject("WindowsInstaller.Installer")

   State = Installer.ProductState(sMSIProductCode)
   If State = 5 Then
      MSIInstalled = True
   Else
      MSIInstalled = False
   End If
   Set Installer = Nothing
End Function

'--------------------------------------------------------------------------------------------------------------
Sub CheckRequiredPackages

   '-------------------
   ' Purpose:	Checks if all required packages are installed (based on the package inventory registry keys)
   ' Type:	Sub
   ' Input:	None
   '-------------------

  Status = 6
  On Error Resume Next
  DependendPackages = Split(sRequiredPackages,";")
  For i = 0 To UBound(DependendPackages)
    If Not Instr(1, DependendPackages(i), "_", 1) > 0 Then
      Err.Raise 1005,"WSH","Invalid required package format used in Package.dat: " & DependendPackages(i)
      RuntimeErrLog
      EndLog
    End If
    DependendPackage = Split(DependendPackages(i), "_")
    sLastInstalledVersion = ""
    sLastInstalledVersion = WshShell.RegRead(sRegPackagesLog & "\" & DependendPackage(0) & "\LastInstalledVersion")
    If Not sLastInstalledVersion = "" Then
      Select Case CompareVersions(DependendPackage(1),sLastInstalledVersion)
        Case "EQ"
          PackageLog "Required package " & DependendPackage(0) & " version " & DependendPackage(1) & " is installed: OK."
        Case "LT"
          PackageLog "Required package " & DependendPackage(0) & " version " & DependendPackage(1) & " is installed: OK."
        Case "ERR"
          Err.Raise 1005, "WSH", "Required Package check failed: " & DependendPackage(1) & " compared with " & sLastInstalledVersion
          RuntimeErrLog
          EndLog
        Case Else
          Err.Raise 1005, "WSH", "Required Package " & DependendPackage(0) & " version " & DependendPackage(1) & " is NOT installed !"
          RunTimeErrLog
          EndLog
      End Select
    Else
      Err.Raise 1005, "WSH", "Required Package " & DependendPackage(0) & " version " & DependendPackage(1) & " is NOT installed !"
      RuntimeErrLog
      EndLog
    End If
  Next 
End Sub

'--------------------------------------------------------------------------------------------------------------
Function CompareVersions(strVersionA, strVersionB)

   '-------------------
   ' Purpose:	Compares 2 version numbers and returns EQ, GT, LT or ERR
   ' Type:	Function
   ' Input:
   '		strVersionA: First version number (Type: string)
   ' 		strVersionB: Second version number (Type: string)
   ' Output:	Returns a string containing the result:
   '			Possible values are:
   ' 				"EQ": Versions are equal
   ' 				"GT": The first version is higher than the second version
   ' 				"LT": The first version is lower than the second version
   ' 				"ERR": The comparison failed
   '-------------------

   On Error Resume Next

   ' Split the versions
   arrVersionA = Split(strVersionA, ".")
   arrVersionB = Split(strVersionB, ".")

   ' Get number of elements in the versions
   intElementsA = UBound(arrVersionA)
   intElementsB = UBound(arrVersionB)
   intElements = intElementsA
   If intElementsB > intElements Then
      intElements = intElementsB
   End If

   ' Add extra empty fields to the 'shortest' version, to get equal length
   If intElementsA < intElements Then
      ReDim Preserve arrVersionA(intElements)
      For i = intElementsA + 1 To intElements
         arrVersionA(i) = "0"
      Next
   End If
   If intElementsB < intElements Then
      ReDim Preserve arrVersionB(intElements)
      For i = intElementsB + 1 To intElements
         arrVersionB(i) = "0"
      Next
   End If

   ' Add zeroes and combine the string
   NewVersionA = AddLeadingChars(arrVersionA(0), 4, "0")
   NewVersionB = AddLeadingChars(arrVersionB(0), 4, "0")
   For i = 1 To intElements
      NewVersionA = NewVersionA & AddLeadingChars(arrVersionA(i), 4, "0")
      NewVersionB = NewVersionB & AddLeadingChars(arrVersionB(i), 4, "0")
   Next

   ' Convert the versions to a 'long' and compare
   NewVersionA = CLng(NewVersionA)
   NewVersionB = CLng(NewVersionB)
   If NewVersionA = NewVersionB Then
      CompareVersions = "EQ"
      Exit Function
   ElseIf NewVersionA > NewVersionB Then
      CompareVersions = "GT"
      Exit Function
   ElseIf NewVersion1 < NewVersionA Then
      CompareVersions = "LT"
      Exit Function
   Else 
      CompareVersions = "ERR"
   End If
End Function

'--------------------------------------------------------------------------------------------------------------
Sub InitAutoit
   '-------------------
   ' Purpose:	Initializes AutoIT object
   ' Type:	Sub
   ' Input:	None
   '-------------------

  On Error Resume Next 
  ' Copies autoitX3.dll to system32 folder and registers it.
  ' Removes any previous screenshot for the installing package
  ' Initializes autoit object
  select case OSArchitecture
	case OSx86
	  If Not fso.FileExists (sWindir & "\System32\AutoitX3.dll") Then
		MainLog "Copy " & sCurrentFolder & "\INS\AutoitX3.dll to " & sWindir & "\System32"
		fso.CopyFile sCurrentFolder & "\INS\AutoitX3.dll",sWindir & "\System32\",True
		RuntimeErrLog
		MainLog "Register " & sWindir & "\System32\AutoitX3.dll"
		WshShell.Run "Cmd /c regsvr32 /s """ & sWindir & "\System32\AutoitX3.dll""",0,True
		RuntimeErrLog
	  End IF
	case else
	  If Not fso.FileExists (sWindir & "\System32\AutoitX3_x64.dll") Then
		MainLog "Copy " & sCurrentFolder & "\INS\AutoitX3_x64.dll to " & sWindir & "\System32"
		fso.CopyFile sCurrentFolder & "\INS\AutoitX3_x64.dll",sWindir & "\System32\",True
		RuntimeErrLog
		MainLog "Register " & sWindir & "\System32\AutoitX3_x64.dll"
		WshShell.Run "Cmd /c regsvr32 /s """ & sWindir & "\System32\AutoitX3_x64.dll""",0,True
		RuntimeErrLog
	  End IF
  End Select
		
  ' Initialize AutoItX3.dll
  Set ObjAutoit = CreateObject("AutoItX3.Control")
  ObjAutoit.AutoItSetOption "WinWaitDelay", 1000
  ObjAutoit.AutoItSetOption "SendKeyDelay", 50
  ObjAutoit.AutoItSetOption "WinTitleMatchMode", 2

  If fso.FileExists (sPackageScreenShot) Then
    fso.DeleteFile sPackageScreenShot,True
  End if
End Sub

'--------------------------------------------------------------------------------------------------------------
Sub Sendkey(Title, Text, Timeout, Keystroke)

   '-------------------
   ' Purpose:	Simulates a keystroke (using AutoIT object)
   ' Type:	Sub
   ' Input:
   '		Title: Title of the window (Type: string)
   ' 		Text: Text in the window (Type: string)
   ' 		Timeout: Time to wait for the window (Type: integer)
   ' 		Keystroke: Keystrokes to send to the window (Type: string)
   '-------------------

  ' Send Keystrokes to window
  ' If window is not found after timeout, checks if there is another interfering window (CheckAdditionalWindows)
  ' If window is still not available after CheckAdditionalWindows takes screenshot and ends the installation
  On Error Resume Next 
  If CheckWindow(Title, Text, Timeout) Then 
    PackageLog "AutoIt : Send Keystroke '" & Keystroke & "' to window '" & Title & "' With text '" & Text & "'"
    ObjAutoIt.WinActivate Title,Text
    ObjAutoIt.Send Keystroke
  Else 
    PackageLog "AutoIt : Window not found, looking for additional windows"
    CheckAdditionalWindows
    PackageLog "AutoIt : Second Attempt waiting for window '" & Title & "' with text '" & Text & "'"
    If CheckWindow(Title, Text, Timeout) Then 
      PackageLog "AutoIt : Send Keystroke '" & Keystroke & "' to window '" & Title & "' With text '" & Text & "'"
      ObjAutoIt.WinActivate Title,Text
      ObjAutoIt.Send Keystroke
    Else
      Err.Raise 1200, "WSH" , "Window '" & Title & "' could not be found, installation will end"
      RuntimeErrLog
      WshShell.Run sCurrentFolder & "\INS\capture.exe "  & sPackageScreenShot,0,True
      EndLog
    End If
  End If
End Sub

'--------------------------------------------------------------------------------------------------------------
Sub SendMouseClick(Title, Text, Timeout, PositionX, PositionY)

   '-------------------
   ' Purpose:	Simulates a mouseclick (using AutoIT object)
   ' Type:	Sub
   ' Input:
   '		Title: Title of the window (Type: string)
   ' 		Text: Text in the window (Type: string)
   ' 		Timeout: Time to wait for the window (Type: integer)
   ' 		PositionX: Horizontal position where to send the mouse click (Type: string)
   ' 		PositionY: Vertical position where to send the mouse click (Type: string)
   '-------------------

  On Error Resume next
  If CheckWindow (Title, Text, TimeOut) Then
    PackageLog "AutoIt : Send mouseclick to window '" & Title & "' With text '" & Text & "'"
    ObjAutoIt.WinActivate Title,Text
    ObjAutoIt.MouseClick "left", PositionX, PositionY
  Else 
    PackageLog "AutoIt : Window not found, looking for additional windows"
    CheckAdditionalWindows
    PackageLog "AutoIt : Second Attempt waiting for window '" & Title & "' with tekst '" & Text & "'"
    If CheckWindow (Title, Text, TimeOut) Then 
      PackageLog "AutoIt : Send mouseclick to window '" & Title & "' With text '" & Text & "'"
      ObjAutoIt.WinActivate Title, Text
      ObjAutoIt.MouseClick "left", PositionX, PositionY
    Else
      Err.Raise 1200, "WSH" , "Window '" & Title & "' could not be found, installation will end"
      RuntimeErrLog
      WshShell.Run sCurrentFolder & "\INS\capture.exe "  & sPackageScreenShot,0,True
      Endlog
    End If
  End If
End Sub

'--------------------------------------------------------------------------------------------------------------
Function CheckWindow(Title, Text, Timeout)

   '-------------------
   ' Purpose:	Checks for a window (using AutoIT object)
   ' Type:	Function
   ' Input:
   '		Title: Title of the window (Type: string)
   ' 		Text: Text in the window (Type: string)
   ' 		Timeout: Time to wait for the window (Type: integer)
   ' Output:	Boolean returning True if the window is found
   '-------------------

  On Error Resume Next

  PackageLog "AutoIt : Waiting for window '" & Title & "' with tekst '" & Text & "'"
  If bFirstWindow Then 
    InitAutoit
    'Sometimes installation hangs without sleep before sending keys
    Wscript.sleep 1500
    bFirstWindow = False
  End If
  RC = ObjAutoIt.WinWait(Title, Text, Timeout)

  If RC = 0 Then
    CheckWindow = False
  Else
    CheckWindow = True
  End If
End Function

'--------------------------------------------------------------------------------------------------------------
Sub CheckAdditionalWindows()

   '-------------------
   ' Purpose:	Checks for interfering windows during SendKey (using AutoIT object)
   ' Type:	Sub
   ' Input:	None
   '-------------------

  ' Check if there is an interfering additional window for Sendkey
  ' (AdditionalWindows are added with AddAdditionalWindow)
  On Error Resume Next 
  bFound = False
  If AdditionalWindowsCount = 0 Then 
    PackageLog "AutoIt : no additional windows "
    Exit Sub
  End If

  For i = 0 To AdditionalWindowsCount - 1
    If ObjAutoIt.WinExists(AdditionalWindows(i,0),AdditionalWindows(i, 1)) Then
      bFound = True
      PackageLog "AutoIt : Additional window found, sending '" & AdditionalWindows(i, 2) & "' to " & AdditionalWindows(i, 0)
      ObjAutoIt.WinActivate AdditionalWindows(i, 0), AdditionalWindows(i, 1)
      ObjAutoIt.Send AdditionalWindows(i, 2)
    End If
  Next
  If Not bFound Then
    PackageLog "AutoIt : No additional windows found"
  End If
End Sub

'--------------------------------------------------------------------------------------------------------------
Sub AddAdditionalWindow(Title, Text, Keystroke)

   '-------------------
   ' Purpose:	Adds possible interfering window during SendKey
   ' Type:	Sub
   ' Input:
   '		Title: Title of the window (Type: string)
   ' 		Text: Text in the window (Type: string)
   ' 		Keystroke: Keystrokes to send to the window (Type: string)
   '-------------------

  ' Add keystroke for possible interfering window (for sendkey)
  AdditionalWindows(AdditionalWindowsCount,0) = Title
  AdditionalWindows(AdditionalWindowsCount,1) = Text
  AdditionalWindows(AdditionalWindowsCount,2) = Keystroke
  AdditionalWindowsCount = AdditionalWindowsCount + 1
End Sub

'--------------------------------------------------------------------------------------------------------------
Sub ProcessAutologon

   '-------------------
   ' Purpose:	Performs all needed steps, workflow, for an Autologon-package
   ' Type:	Sub
   ' Input:	None
   '-------------------

On Error Resume Next
If bAutoLogon = True Then

	Set MyAutoLogon = New AutoLogon
	sAutoLogonStatus = UCase(objArgsNamed.Item("AutoLogon"))
	If sAutoLogonStatus = "" Then
		sAutoLogonStatus = "INITIALIZE"
	End If
	Select Case UCase(sAutoLogonStatus)
		Case "INITIALIZE"	'prepare for autologon procedure
			DetectMode
			StartLog
			CheckLibraryVersion
			Call FindSources("CurrentOrParentFolder")
			DiskSpace
			CheckRequiredPackages
			ShowMessage sPackageName & " " & sPackageVersion & " is preparing for AutoLogon procedure..."
			'Copy package files locally
			MainLog "AutoLogonInit: Initialization of AutoLogon procedure"
			PackageLog "AutoLogonInit: Initialization of AutoLogon procedure"
			Status = 1
			sSubFolderPackage = Replace(sPackageName," ", "")
			PackageLog "AutoLogonInit: Copy package files from " & sCurrentFolder & " to " & sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion
			MakeFolder sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion
			fso.CopyFolder sCurrentFolder, sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion, True
			RuntimeErrLog
			'Copy source files locally
		  	If bSourcesRequired = True Then
				If not fso.FolderExists(sCurrentFolder & "\" & sSourcesFolderName) Then
				  PackageLog "AutoLogonInit: Copy source files from " & sSourcePath & " to " & sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion & "\" & sSourcesFolderName
				  MakeFolder sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion & "\" & sSourcesFolderName
				  fso.CopyFolder sSourcePath, sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion & "\" & sSourcesFolderName, True
				  RuntimeErrLog
				Else
				  PackageLog "AutoLogonInit: Sources already copied via the package folder"
				End If
			Else
				PackageLog "AutoLogonInit: No source files required"
			End If

			strShellCommand = "wscript.exe //Job:" & sJobID & " " & Chr(34) & sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion & "\" & Wscript.Scriptname & Chr(34) & " /AutoLogon:EXECPKG"
			strExecuteAfterRebootCommand = "wscript.exe //Job:" & sJobID & " " & chr(34) & sSystemDrive & "\RunAsAdmin\" & sSubFolderPackage & "\" & sPackageVersion & "\" & Wscript.Scriptname & chr(34) & " /AutoLogon:RunCheck"
			If Mode = cstInteractiveMode Then
			   strShellCommand = strShellCommand & " /mode:" & cstSilentMode
			   strExecuteAfterRebootCommand = strExecuteAfterRebootCommand & " /mode:" & cstSilentMode
			Else
			   strShellCommand = strShellCommand & " /mode:" & mode
			   strExecuteAfterRebootCommand = strExecuteAfterRebootCommand & " /mode:" & mode
			End If
			PackageLog "AutoLogonInit: New Shell-command: " & strShellCommand
			MyAutoLogon.SetAutoLogon strShellCommand, True

   			'disable input devices
			If bDisableInput = True Then
			   PackageLog "AutoLogonInit: Disable Input Devices"
			   MyAutoLogon.DisableInput
  			End If
			MainLog "AutoLogonInit: Reboot by Autologon procedure"
			PackageLog "AutoLogonInit: Reboot by Autologon procedure"
			RebootProcess
		Case "EXECPKG"	'/Autologon:EXECPKG

			PackageLog "AutoLogonExec: Restore AutoLogon"
			MyAutoLogon.RestoreAutoLogon
			PackageLog "AutoLogonExec: Enable Input Devices"
			MyAutoLogon.EnableInput

			bRebootRequired = True   'Always reboot the system at end of Autologon:EXECPKG

			PackageLog "AutoLogonExec: Wait for AutoLogon RunCheck to start via ExecuteAfterReboot"
			iTries = 0
			Do While Not ExecAfterRebootIsEmpty
			   If iTries > 40 Then
			      Exit Do
			   Else
			      PackageLog "AutoLogonExec: Waiting ..."
			      iTries = iTries + 1
			      WScript.Sleep 3 * 1000
			   End If
			Loop
			RuntimeErrLog
			
			PackageLog "AutoLogonExec: Creating Cleanup Script"
			Call SetCleanupScript
			RuntimeErrLog

  			If bErrorOccured Then
				Err.Raise 1005, "WSH", "Error during clean up of Autologon information"
      				RuntimeErrLog
	    			WshShell.Run sCurrentFolder & "\INS\capture.exe "  & sPackageScreenShot,0,True
      				EndLog
	      		End If
			MainLog "AutoLogonExec: Perform " & sJobID & " script"
			PackageLog "AutoLogonExec: Perform " & sJobID & " script"
		Case "RUNCHECK"		'/Autologon:RunCheck
			MainLog "AutoLogonChk: Start waiting for Autologon-ExecPkg..."
			PackageLog "AutoLogonChk: Start waiting for Autologon-ExecPkg..."
			WScript.Sleep 60000
			x = 0
			Do While x <= 12		'12 times 5 minutes (= 12 x 300000 milliseconds)
				WScript.Sleep 300000
				PackageLog "AutoLogonChk: Autologon-ExecPkg still busy..."
				x = x + 1
			Loop

			PackageLog "AutoLogonChk: Restore AutoLogon"
			MyAutoLogon.RestoreAutoLogon
			PackageLog "AutoLogonChk: Enable Input Devices"
			MyAutoLogon.EnableInput

			bRebootRequired = True   'Always reboot the system at end of Autologon:EXECPKG

			PackageLog "AutoLogonChk: Creating Cleanup Script"
			Call SetCleanupScript
			RuntimeErrLog

	End Select

End If

End Sub


'--------------------------------------------------------------------------------------------------------------
Function GeneratePassword(iLength)

   '-------------------
   ' Purpose:	Generate Random Password
   ' Type:	Function
   ' Input:	iLength: Length of the password (Type: integer)
   ' Output:	String containing a randomly generated password
   '-------------------

   Set NewPassword = New Password
   NewPassword.Length = iLength
   GeneratePassword = NewPassword.Generate
   Set NewPassword = Nothing

End Function


'--------------------------------------------------------------------------------------------------------------
Function CheckFloppyDisk()

   '-------------------
   ' Purpose:	Check if a floppydisk is present in floppy drive
   ' Type:	Function
   ' Input:	None
   ' Output:	Boolean returning True if a floppy is in the drive
   '-------------------

  On Error Resume Next

  sFolder = Fso.GetFolder("A:\")
  If Err = 0 Then
    CheckFloppyDisk = True
  Else
    CheckFloppyDisk = False
  End If
End Function

'-------------------------------------------------------------------------------------------------------
Sub SetSecurity(sSecurityMode, sFolderFileName, sSecurity)
   '-------------------
   ' Purpose:	Set Security on files and folders
   ' Type:	Sub
   ' Input:
   '		sSecurityMode: How security should apply (Type: string)
   '			Possible values are:
   ' 				AddSecurity: Adds the specified security
   ' 				ReplaceSecurity: Replaces the specified security
   ' 		sFolderFileName: Full path of the folder (Type: string)
   ' 		sSecurity: Security to set according to the xcacls.exe /G parameter (Type: string)
   ' Other:	Better use 'SetNTFSPermissions' (but this one is needed for backward compatibility)
   '-------------------

   On Error Resume Next

   Select Case sSecurityMode
      Case ReplaceSecurity
         sAddOrReplace = ReplacePermissions
      Case AddSecurity
         sAddOrReplace = AddPermissions
      Case Else
         Err.Raise 2003, "WSH", "Unknown Mode " & sSecurityMode
   End Select

   Call SetNTFSPermissions(sFolderFileName, sSecurity, sAddOrReplace, True)
   RuntimeErrLog
End Sub

'-------------------------------------------------------------------------------------------------------
Sub SetISecurity(sSecurityMode, sFolderFileName, sSecurity)
   '-------------------
   ' Purpose:	Set Security on files and folders (using ICACLS.EXE)
   ' Type:	Sub
   ' Input:
   '		sSecurityMode: How security should apply (Type: string)
   '			Possible values are:
   ' 				AddSecurity: Adds the specified security
   ' 				ReplaceSecurity: Replaces the specified security
   ' 		sFolderFileName: Full path of the folder (Type: string)
   ' 		sSecurity: Security to set according to the icacls.exe /grant parameter (Type: string)
   ' Other:	Better use 'SetNTFSPermissions' (but this one is needed for backward compatibility)
   '-------------------

   On Error Resume Next

   Select Case sSecurityMode
      Case ReplaceSecurity
         sAddOrReplace = ReplacePermissions
      Case AddSecurity
         sAddOrReplace = AddPermissions
      Case Else
         Err.Raise 2003, "WSH", "Unknown Mode " & sSecurityMode
   End Select
   Call SetINTFSPermissions(sFolderFileName, sSecurity, sAddOrReplace, True)
   RuntimeErrLog
End Sub

Function GetFileVersion (ByVal sFile)

   '-------------------
   ' Purpose:	Get the version of a file
   ' Type:	Function
   ' Input:	sFile: Full path of the file (Type: string)
   ' Output:	String containing the version of the file
   '-------------------

	on error resume next
	err.clear
	Dim sVersion

	GetFileVersion = ""
	if sFile = "" then
	    Err.Raise 10002, "GetFileVersion", "Empty argument(s)"
		Exit Function
	end if

	if not fso.FileExists(sFile) then
	    Err.Raise 10003, "GetFileVersion", "File not found"
		Exit Function
	end if

	sVersion = fso.GetFileVersion(sFile)
	if len(sVersion) = 0 then
	    Err.Raise 10004, "GetFileVersion", "No version found"
	end if
	GetFileVersion = sVersion

End Function

'-------------------------------------------------------------------------------------------------------
Sub AddFileToPackageLog(sFile)

   '-------------------
   ' Purpose:	Add the content of a file to the Package log file
   ' Type:	Sub
   ' Input:	sFile: Full path of the file (Type: string)
   '-------------------

    On Error Resume Next

    Err.clear
    Set file = fso.OpenTextFile(sFile, 1)
    If Err.Number <> 0 Then
	   PackageLog "Unable to open " & sFile & " (RC " &Cstr(Err.number) & ": " & Err.Description& ")"  
       Exit Sub
	End If
	sFileContents  =  file.ReadAll
	file.close
	
    PackageLog "Contents of " & sFile
    Set fileLog = fso.OpenTextFile(sLogPath & "\" & sPackageName & ".log", 8, True)
    fileLog.WriteLine sFileContents
    fileLog.Close
    PackageLog "End of " & sFile
    PackageLog ""

End Sub

'-------------------------------------------------------------------------------------------------------
Sub GetMsiErrorDescription(nErrorCode)

   '-------------------
   ' Purpose:	Return the name and description of the MSI error
   ' Type:	Sub
   ' Input:	nErrorCode: MSI Error Code (Type: integer)
   '-------------------

  On Error Resume Next

  Select Case nErrorCode
    case 0
       sErrorName = "SUCCESS"
       sErrorDescription = "Successful ended."
    case 1601
       sErrorName = "ERROR_INSTALL_SERVICE_FAILURE"
       sErrorDescription = "The Windows Installer service could not be accessed. Contact your support personnel to verify that the Windows Installer service is properly registered."
    case 1602
       sErrorName = "ERROR_INSTALL_USEREXIT"
       sErrorDescription = "User cancel installation."
    case 1603
    	sErrorName = "ERROR_INSTALL_FAILURE"
    	sErrorDescription = "Fatal error during installation."
    case 1604	
       sErrorName = "ERROR_INSTALL_SUSPEND"
       sErrorDescription = "Installation suspended, incomplete."
    case 1605
    	sErrorName = "ERROR_UNKNOWN_PRODUCT"
    	sErrorDescription = "This action is only valid for products that are currently installed."
    case 1606
    	sErrorName = "ERROR_UNKNOWN_FEATURE"
    	sErrorDescription = "Feature ID not registered."
    case 1607
    	sErrorName = "ERROR_UNKNOWN_COMPONENT"		
    	sErrorDescription = "Component ID not registered."
    case 1608
    	sErrorName = "ERROR_UNKNOWN_PROPERTY"	
    	sErrorDescription = "Unknown property."
    case 1609
    	sErrorName = "ERROR_INVALID_HANDLE_STATE"	
    	sErrorDescription = "Handle is in an invalid state."
    case 1610	
    	sErrorName = "ERROR_BAD_CONFIGURATION"	
    	sErrorDescription = "The configuration data for this product is corrupt. Contact your support personnel."
    case 1611
    	sErrorName = "ERROR_INDEX_ABSENT"	
    	sErrorDescription = "Component qualifier not present."
    case 1612
    	sErrorName = "ERROR_INSTALL_SOURCE_ ABSENT"	
    	sErrorDescription = "The installation source for this product is not available. Verify that the source exists and that you can access it."
    case 1613
    	sErrorName = "ERROR_INSTALL_PACKAGE_VERSION"	
    	sErrorDescription = "This installation package cannot be installed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service."
    case 1614
    	sErrorName = "ERROR_PRODUCT_UNINSTALLED"	
    	sErrorDescription = "Product is uninstalled."
    case 1615
    	sErrorName = "ERROR_BAD_QUERY_SYNTAX"	
    	sErrorDescription = "SQL query syntax invalid or unsupported."
    case 1616
    	sErrorName = "ERROR_INVALID_FIELD"	
    	sErrorDescription = "Record field does not exist."
    case 1618
    	sErrorName = "ERROR_INSTALL_ALREADY_RUNNING"	
    	sErrorDescription = "Another installation is already in progress. Complete that installation before proceeding with this install."
    case 1619
    	sErrorName = "ERROR_INSTALL_PACKAGE_OPEN_FAILED"	
    	sErrorDescription = "This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package."
    case 1620
    	sErrorName = "ERROR_INSTALL_PACKAGE_INVALID"	
    	sErrorDescription = "This installation package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer package."
    case 1621
    	sErrorName = "ERROR_INSTALL_UI_FAILURE"	
    	sErrorDescription = "There was an error starting the Windows Installer service user interface. Contact your support personnel."
    case 1622
    	sErrorName = "ERROR_INSTALL_LOG_FAILURE"	
    	sErrorDescription = "Error opening installation log file. Verify that the specified log file location exists and is writable."
    case 1623
    	sErrorName = "ERROR_INSTALL_LANGUAGE_UNSUPPORTED"	
    	sErrorDescription = "This language of this installation package is not supported by your system."
    case 1625
    	sErrorName = "ERROR_INSTALL_PACKAGE_REJECTED"	
    	sErrorDescription = "This installation is forbidden by system policy. Contact your system administrator."
    case 1626
    	sErrorName = "ERROR_FUNCTION_NOT_CALLED"	
    	sErrorDescription = "Function could not be executed."
    case 1627
    	sErrorName = "ERROR_FUNCTION_FAILED"	
    	sErrorDescription = "Function failed during execution."
    case 1628
    	sErrorName = "ERROR_INVALID_TABLE"	
    	sErrorDescription = "Invalid or unknown table specified."
    case 1629
    	sErrorName = "ERROR_DATATYPE_MISMATCH"	
    	sErrorDescription = "Data supplied is of wrong type."
    case 1630
    	sErrorName = "ERROR_UNSUPPORTED_TYPE"	
    	sErrorDescription = "Data of this type is not supported."
    case 1631
    	sErrorName = "ERROR_CREATE_FAILED"	
    	sErrorDescription = "The Windows Installer service failed to start. Contact your support personnel."
    case 1632
    	sErrorName = "ERROR_INSTALL_TEMP_UNWRITABLE"	
    	sErrorDescription = "The temp folder is either full or inaccessible. Verify that the temp folder exists and that you can write to it."
    case 1633
    	sErrorName = "ERROR_INSTALL_PLATFORM_UNSUPPORTED"	
    	sErrorDescription = "This installation package is not supported on this platform. Contact your application vendor."
    case 1634
    	sErrorName = "ERROR_INSTALL_NOTUSED"	
    	sErrorDescription = "Component not used on this machine."
    case 1624
    	sErrorName = "ERROR_INSTALL_TRANSFORM_FAILURE"	
    	sErrorDescription = "Error applying transforms. Verify that the specified transform paths are valid."
    case 1635
    	sErrorName = "ERROR_PATCH_PACKAGE_OPEN_FAILED"	
    	sErrorDescription = "This patch package could not be opened. Verify that the patch package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer patch package."
    case 1636
    	sErrorName = "ERROR_PATCH_PACKAGE_INVALID"	
    	sErrorDescription = "This patch package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer patch package."
    case 1637
    	sErrorName = "ERROR_PATCH_PACKAGE_UNSUPPORTED"	
    	sErrorDescription = "This patch package cannot be processed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service."
    case 1638
    	sErrorName = "ERROR_PRODUCT_VERSION"	
    	sErrorDescription = "Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel."
    case 1639
    	sErrorName = "ERROR_INVALID_COMMAND_LINE"	
    	sErrorDescription = "Invalid command line argument. Consult the Windows Installer SDK for detailed command line help."
    case 3010
    	sErrorName = "ERROR_SUCCESS_REBOOT_REQUIRED"	
    	sErrorDescription = "A restart is required to complete the install. This does not include installs where the ForceReboot action is run. Note that this error will not be available until future version of the installer. "
    case Else
    	sErrorName = ERROR_UNKNOWN
    	sErrorDescription = "Unknown error."
    	nRc = 1
  end Select

End Sub

'-------------------------------------------------------------------------------------------------------
Sub GetInstallShieldError(sFile)

   '-------------------
   ' Purpose:	Retrieve the InstallShield setup error code
   ' Type:	Sub
   ' Input:	sFile: Full path of the InstallShield log file (Type: string)
   '-------------------

	On Error Resume Next
  
	Err.Clear
	Set file = fso.OpenTextFile(sFile, 1)
	nRc = Err.Number
	sDescription = Err.Description
	If nRc <> 0 Then
   	  PackageLog "Open " & sFile & ": RC " & Cstr(nRc) & "  " & sDescription
      nErrorCode = Null
      Exit Sub
    End If
	sFileContents = file.ReadAll
	file.close
    
    sResultString = "ResultCode="
	nPos = InStr(1,sFileContents, sResultString, vbTextCompare)
    If nPos = 0 or nPos = Null Then   
      PackageLog "Look for '" & sResultString & "' in " & sFile
      PackageLog "String not found."
      nErrorCode = Null
      Exit Sub
    End If
    
    sResult = Mid(sFileContents,nPos+Len(sResultString),2)
    
    If sResult = Null  Then
      nErrorCode  = Null
    Else
      If Left(sResult,1) = "-" Then 
        sResult = Mid(sResult,2,1)      'skip the - sign
      End If
      If Left(sResult,1) = "0" Then 
        sResult = 0                      'skip the character after the 0
      End If
      nErrorCode = CStr(sResult)
      GetInstallShieldErrorDescription nErrorCode
      PackageLog "Result in InstallShield log file: " & Cstr(nErrorCode) & "  " & sErrorDescription
    End if  

End Sub

'-------------------------------------------------------------------------------------------------------
Sub GetInstallShieldErrorDescription(nErrorCode)

   '-------------------
   ' Purpose:	Return the description of the InstallShield setup error
   ' Type:	Sub
   ' Input:	nErrorCode: MSI Error Code (Type: integer)
   '-------------------

  On Error Resume Next

  Select Case nErrorCode
    case 0	
	    sErrorDescription = "Success."
    case 1	
	    sErrorDescription = "General Error."
    case 2	
	    sErrorDescription = "Invalid mode."
    case 3	
	    sErrorDescription = "Required data not found in the Setup.iss file."
    case 4	
	    sErrorDescription = "Not enough memory available."
    case 5	
	    sErrorDescription = "File not exist."
    case 6	
	    sErrorDescription = "Cannot write tothe response file."
    case 7	
	    sErrorDescription = "Unable to write to the log file."
    case 8	
	    sErrorDescription = "Invalid path to the InstallShield silent response file."
    case 9	
	    sErrorDescription = "Not a valid mist type string or number)."
    case 10	
	    sErrorDescription = "Data type is invalid."
    case 11	
	    sErrorDescription = "Unknown error during setup."
    case 12	
	    sErrorDescription = "Dialogs are out of order."
    case 51	
	    sErrorDescription = "Cannot create the specified folder."
    case 52	
	    sErrorDescription = "Cannot access the specifield file or folder."
    case 53	
	    sErrorDescription = "Invalid option selected."
    case Else
    	sErrorDescription = "Unknown error."
    	nRc = 1
  end Select

End Sub

'-------------------------------------------------------------------------------------------------------
Function RunCommand(sCommand, iWindowsStyle, bWaitOnReturn)

   '-------------------
   ' Purpose:	
   ' Type:	Function
   ' Input:
   '		sCommand: The command to run (Type: string)
   ' 		iWindowsStyle: The style of the window for the command (Type: integer)
   ' 		bWaitOnReturn: Specify whether to script should wait for the return of the command (Type: boolean)
   ' Output:	Integer specifying the return code of the command
   '-------------------

  Dim nRcCommand, nRcFunction

  nRcCommand = RunNotExecuted
  PackageLog "Execute " & sCommand

  Err.Clear
  nRcCommand = WshShell.Run(sCommand, iWindowsStyle, bWaitOnReturn)
  If Err.Number <> 0 Then
    nRcFunction = Err.Number
    PackageLog "RC of function: " & Cstr(Err.Number) & "    " & Err.Description
    PackageLog "ERROR: The installation failed. The setup command probably not found."
    nRcCommand = RunNotExecuted
  Else
    PackageLog "RC of command: " & Cstr(nRcCommand)
  End If
  PackageLog ""

  RunCommand = nRcCommand

End Function

'-------------------------------------------------------------------------------------------------------
Function FreeDriveLetter

   '-------------------
   ' Purpose:	Get a free drive letter
   ' Type:	Function
   ' Input:	None
   ' Output:	String containing the first (starting from Z to D) free drive letter
   '-------------------

  On Error Resume Next
  
  Dim i

  For i = Asc("Z") To Asc("D") Step -1
    If Not fso.DriveExists(Chr(i)) Then
      FreeDriveLetter = Chr(i)
      Exit For
    End If
  Next
End Function

'-------------------------------------------------------------------------------------------------------
Sub PackageRegInfo

   '-------------------
   ' Purpose:	Write Package information to the registry
   ' Type:	Sub
   ' Input:	None
   '-------------------

  WshShell.RegWrite sRegPackageLog & "\PackageName", sPackageName
  WshShell.RegWrite sRegPackageLog & "\PackageVersion", sPackageVersion
  WshShell.RegWrite sRegPackageLog & "\PackageAuthor", sPackageAuthor
  WshShell.RegWrite sRegPackageLog & "\Application", sApplicationName
  WshShell.RegWrite sRegPackageLog & "\ApplicationVersion", sApplicationVersion
  WshShell.RegWrite sRegPackageLog & "\Mode", Mode
  WshShell.RegWrite sRegPackageLog & "\JobID", sJobID
  RuntimeErrLog
End Sub

'-------------------------------------------------------------------------------------------------------
Function RetrieveOSType

   '-------------------
   ' Purpose:	Retrieve the Operating System type
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns a string containing the OS Type
   '			Possible values are:
   ' 				OSNT4
   ' 				OSW2K
   ' 				OSXP
   ' 				OSW2K3
   ' 				OSVista
   ' 				OSW2K8
   ' 				OSWin7
   ' 				OSW2K8R2
   '				OSWin8
   '				OSWin81
   '				OSW2K12
   '				OSW2K12R2
   '				OSWin10
   '				OSWin2016
   '-------------------

   On Error Resume Next

   Dim oOperatingSystems, oOS, oOSVersion

  Set oOperatingSystems = GetObject("WinMgmts:").ExecQuery("SELECT Version FROM Win32_OperatingSystem")
  For Each oOS In oOperatingSystems
    oOSVersion = Split(oOS.Version, ".")(0) & "." & Split(oOS.Version, ".")(1)
    Select Case oOSVersion
      Case "4.0"
        RetrieveOSType = OSNT4
        Exit For
      Case "5.0"
        RetrieveOSType = OSW2K
        Exit For
      Case "5.1"
        RetrieveOSType = OSXP
        Exit For
      Case "5.2"
        RetrieveOSType = OSW2K3
        Exit For
      Case "6.0"
        Select Case RetrieveOSProductType
           Case OSClient
              RetrieveOSType = OSVista
           Case OSServer
              RetrieveOSType = OSW2K8
           Case Else
              Err.Raise 1020, "RetrieveOSType", "Unknown OS ProductType"
              RuntimeErrLog
              RetrieveOSType = ""
        End Select
        Exit For
      Case "6.1"
        Select Case RetrieveOSProductType
           Case OSClient
              RetrieveOSType = OSWin7
           Case OSServer
              RetrieveOSType = OSW2K8R2
           Case Else
              Err.Raise 1020, "RetrieveOSType", "Unknown OS ProductType"
              RuntimeErrLog
              RetrieveOSType = ""
        End Select
        Exit For
	  Case "6.2"
        Select Case RetrieveOSProductType
           Case OSClient
              RetrieveOSType = OSWin8
           Case OSServer
              RetrieveOSType = OSW2K12
           Case Else
              Err.Raise 1020, "RetrieveOSType", "Unknown OS ProductType"
              RuntimeErrLog
              RetrieveOSType = ""
        End Select
        Exit For
	  Case "6.3"
        Select Case RetrieveOSProductType
           Case OSClient
              RetrieveOSType = OSWin81
           Case OSServer
              RetrieveOSType = OSW2K12R2
           Case Else
              Err.Raise 1020, "RetrieveOSType", "Unknown OS ProductType"
              RuntimeErrLog
              RetrieveOSType = ""
        End Select
        Exit For
	  Case "10.0"
	    Select Case RetrieveOSProductType
		   Case OSClient
              RetrieveOSType = OSWin10
           Case OSServer
              RetrieveOSType = OSWin2016
           Case Else
              Err.Raise 1020, "RetrieveOSType", "Unknown OS ProductType"
              RuntimeErrLog
              RetrieveOSType = ""
        End Select
        Exit For
      Case Else
        Err.Raise 1020, "RetrieveOSType", "Unknown OS Version"
        RuntimeErrLog
        RetrieveOSType = ""
        Exit For
    End Select
  Next
End Function

'-------------------------------------------------------------------------------------------------------
Function RetrieveOSVersion

   '-------------------
   ' Purpose:	Retrieve the version (Service Pack level) of the Operating System
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns a string containing the OS Version
   '-------------------

  On Error Resume Next
  Dim FoundVersion
  FoundVersion = ""
  Set oOperatingSystems = GetObject("WinMgmts:").ExecQuery("SELECT CSDVersion FROM Win32_OperatingSystem")
  For Each oOS In oOperatingSystems
    If oOS.CSDVersion <> "" Then
      FoundVersion = "SP" & Trim(Right(oOS.CSDVersion, 2))
      Exit For
    Else
      FoundVersion = "RTM"
    End If
  Next
  RetrieveOSVersion = FoundVersion
  RuntimeErrLog
End Function

'-------------------------------------------------------------------------------------------------------
Function RetrieveOSSubVersion

   '-------------------
   ' Purpose:	Retrieve the sub version of the Operating System
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns a string containing the OS Sub Version
   '-------------------

  On Error Resume Next
  Dim FoundVersion
  Err.Clear
  FoundVersion = WshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SubVersionNumber")
  If Err.Number <> 0 Then
     Err.Clear
     FoundVersion = ""
  End If
  RetrieveOSSubVersion = FoundVersion
  RuntimeErrLog
End Function

'-------------------------------------------------------------------------------------------------------
Function RetrieveOSLanguage

	'-------------------
	' Purpose:	Retrieve the language of the Operating System
	' Type:	Function
	' Input:	None
	' Output:	Returns a string containing the OS Language
	'			Possible values are like:
	' 				cstChineseChina
	' 				cstChineseTaiwan
	'-------------------
		
	Dim sRegKeyValue, aRegKeyValue, sPreferredUILanguages
	If RegKeyExist("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\MUI\Settings\PreferredUILanguages", aRegKeyValue) Then
		'Convert PreferredUILanguages REG_MULTI_SZ (array) into string 
		sRegKeyValue=""
		For i = 0 To UBound(aRegKeyValue)
			sRegKeyValue = sRegKeyValue  & aRegKeyValue(i)
		Next
		'Next block converts "fr-FR" to "FR", while converting "nl-BE" to "NL-BE"
		If Ucase(Left(Cstr(sRegKeyValue),2))=Ucase(Right(Cstr(sRegKeyValue),2)) or Ucase(sRegKeyValue)="EN-US" Then
			sPreferredUILanguages = Ucase(Left(sRegKeyValue,2))
		Else
			sPreferredUILanguages = Ucase(sRegKeyValue)
		End If
		
		Select Case sPreferredUILanguages
			Case cstArabicSaudiArabiaLangCode
				sOSLanguage = cstArabicSaudiArabia
			Case cstBulgarianLangCode
				sOSLanguage = cstBulgarian
			Case cstChineseChinaLangCode
				sOSLanguage = cstChineseChina
			Case cstChineseTaiwanLangCode
				sOSLanguage = cstChineseTaiwan
			Case cstCroatianLangCode
				sOSLanguage = cstCroatian
			Case cstDanishLangCode
				sOSLanguage = cstDanish
			Case cstDutchBelgiumLangCode
				sOSLanguage = cstDutchBelgium
			Case cstDutchNetherlandsLangCode
				sOSLanguage = cstDutchNetherlands
			Case cstEnglishUSLangCode
				sOSLanguage = cstEnglishUS
			Case cstEnglishGBLangCode
				sOSLanguage = cstEnglishGB
			Case cstEstonianLangCode
				sOSLanguage = cstEstonian
			Case cstFinnishLangCode
				sOSLanguage = cstFinnish
			Case cstFrenchFranceLangCode
				sOSLanguage = cstFrenchFrance
			Case cstGermanGermanyLangCode
				sOSLanguage = cstGermanGermany
			Case cstGreekLangCode
				sOSLanguage = cstGreek
			Case cstHebrewLangCode
				sOSLanguage = cstHebrew
			Case cstHindiLangCode
				sOSLanguage = cstHindi
			Case cstHungarianLangCode
				sOSLanguage = cstHungarian
			Case cstItalianItalyLangCode
				sOSLanguage = cstItalianItaly
			Case cstJapaneseLangCode
				sOSLanguage = cstJapanese
			Case cstKazakhLangCode
				sOSLanguage = cstKazakh
			Case cstKoreanLangCode
				sOSLanguage = cstKorean
			Case cstNorwegianBokmalLangCode
				sOSLanguage = cstNorwegianBokmal
			Case cstPolishLangCode
				sOSLanguage = cstPolish
			Case cstPortuguesePortugalLangCode
				sOSLanguage = cstPortuguesePortugal
			Case cstRomanianLangCode
				sOSLanguage = cstRomanian
			Case cstRussianLangCode
				sOSLanguage = cstRussian
			Case cstSerbianLatinLangCode
				sOSLanguage = cstSerbianLatin
			Case cstSlovakLangCode
				sOSLanguage = cstSlovak 
			Case cstSlovenianLangCode
				sOSLanguage = cstSlovenian
			Case cstSpanishSpainLangCode
				sOSLanguage = cstSpanishSpain
			Case cstSwedishSwedenLangCode
				sOSLanguage = cstSwedishSweden
			Case cstThaiLangCode
				sOSLanguage = cstThai
			Case cstTurkishLangCode
				sOSLanguage = cstTurkish
			Case cstUkranianLangCode
				sOSLanguage = cstUkranian
			Case Else
				Err.Raise 1020, "RetrieveOSLanguage", "Unknown OS Language"
				RuntimeErrLog
				sOSLanguage = ""
		End Select
	Else
		Dim oOS, oOperatingSystems, sOSLanguage
		Set oOperatingSystems = GetObject("WinMgmts:").ExecQuery("SELECT OSLanguage FROM Win32_OperatingSystem")
		For Each oOS In oOperatingSystems
			Select Case  oOS.OSLanguage
			  Case cstArabicSaudiArabiaLocaleID
				sOSLanguage = cstArabicSaudiArabia
				Exit For
			  Case cstBulgarianLocaleID
				sOSLanguage = cstBulgarian
				Exit For
			  Case cstChineseChinaLocaleID
				sOSLanguage = cstChineseChina
				Exit For
			  Case cstChineseTaiwanLocaleID
				sOSLanguage = cstChineseTaiwan
				Exit For
			  Case cstCroatianLocaleID
				sOSLanguage = cstCroatian
				Exit For		
			  Case cstDanishLocaleID
				sOSLanguage = cstDanish
				Exit For
			  Case cstDutchBelgiumLocaleID
				sOSLanguage = cstDutchBelgium
				Exit For
			  Case cstDutchNetherlandsLocaleID
				sOSLanguage = cstDutchNetherlands
				Exit For
			  Case cstEnglishUSLocaleID
				sOSLanguage = cstEnglishUS
				Exit For
			Case cstEnglishGBLocaleID
				sOSLanguage = cstEnglishGB
				Exit For
			  Case cstEstonianLocaleID
				sOSLanguage = cstEstonian
				Exit For
			  Case cstFinnishLocaleID
				sOSLanguage = cstFinnish
				Exit For
			  Case cstFrenchFranceLocaleID
				sOSLanguage = cstFrenchFrance
				Exit For
			  Case cstGermanGermanyLocaleID
				sOSLanguage = cstGermanGermany
				Exit For
			  Case cstGreekLocaleID
				sOSLanguage = cstGreek
				Exit For
			  Case cstHebrewLocaleID
				sOSLanguage = cstHebrew
				Exit For
			  Case cstHindiLocaleID
				sOSLanguage = cstHindi
				Exit For
			  Case cstHungarianLocaleID
				sOSLanguage = cstHungarian
				Exit For
			  Case cstItalianItalyLocaleID
				sOSLanguage = cstItalianItaly
				Exit For
			  Case cstJapaneseLocaleID
				sOSLanguage = cstJapanese
				Exit For
			  Case cstKazakhLocaleID
				sOSLanguage = cstKazakh
				Exit For
			  Case cstKoreanLocaleID
				sOSLanguage = cstKorean
				Exit For
			  Case cstNorwegianBokmalLocaleID
				sOSLanguage = cstNorwegianBokmal
				Exit For
			  Case cstPolishLocaleID
				sOSLanguage = cstPolish
				Exit For
			  Case cstPortuguesePortugalLocaleID
				sOSLanguage = cstPortuguesePortugal
				Exit For
			  Case cstRomanianLocaleID
				sOSLanguage = cstRomanian
				Exit For
			  Case cstRussianLocaleID
				sOSLanguage = cstRussian
				Exit For
			  Case cstSerbianLatinLocaleID
				sOSLanguage = cstSerbianLatin
				Exit For
			  Case cstSlovakLocaleID
				sOSLanguage = cstSlovak 
				Exit For
			  Case cstSlovenianLocaleID
				sOSLanguage = cstSlovenian
				Exit For
			  Case cstSpanishSpainLocaleID
				sOSLanguage = cstSpanishSpain
				Exit For
			  Case cstSwedishSwedenLocaleID
				sOSLanguage = cstSwedishSweden
				Exit For
			  Case cstThaiLocaleID
				sOSLanguage = cstThai
				Exit For
			  Case cstTurkishLocaleID
				sOSLanguage = cstTurkish
				Exit For
			  Case cstUkranianLocaleID
				sOSLanguage = cstUkranian
				Exit For

			  Case Else
				Err.Raise 1020, "RetrieveOSLanguage", "Unknown OS Language"
				RuntimeErrLog
				sOSLanguage = ""
				Exit For
			End Select
		Next
  	End If
  	RetrieveOSLanguage=sOSLanguage
	
End Function

'-------------------------------------------------------------------------------------------------------
Function AddLeadingChars(strValue, iTotalLength, strChar)

   '-------------------
   ' Purpose:	Returns a string by adding the character strChar in front of the strValue to have a string of lenght iTotalLength
   ' 		ex. AddLeadingChars("2345", 6, "0") --> "002345"
   ' Type:	Function
   ' Input:
   '		strValue: Value where to add the characters to (Type: string)
   ' 		iTotalLength: Length the return value (Type: integer)
   ' 		strChar: Character to add (Type: string)
   ' Output:	Returns a string with the added characters
   '-------------------

   AddLeadingChars = Right(String(iTotalLength, strChar) & strValue, iTotalLength)
End Function

'-------------------------------------------------------------------------------------------------------
Function GetTimeStamp(DateTime)

   '-------------------
   ' Purpose:	Returns a string in the format YYYYMMDDHHMMSS of the date and time in DateTime
   ' Type:	Function
   ' Input:	DateTime: Date & Time (Type: Date)
   ' Output:	Returns a string in a fixed format
   '-------------------

   GetTimeStamp = Year(DateTime) & Right("00" & Month(DateTime), 2) & Right("00" & Day(DateTime), 2) & Right("00" & Hour(DateTime), 2) & Right("00" & Minute(DateTime), 2) & Right("00" & Second(DateTime), 2)
End Function

'-------------------------------------------------------------------------------------------------------
Function WindowsGroup(cstWindowsGroup)

   '-------------------
   ' Purpose:	Get the exact name of built-in windows security groups
   ' Type:	Function
   ' Input:	cstWindowsGroup: Default name of the built-in group in English (Type: string)
   ' Output:	Returns a string containing the current name of the group
   ' Other:	Better use 'LocalGroup' (but this one is needed for backward compatibility)
   '-------------------

   WindowsGroup = LocalGroup(cstWindowsGroup)
   Exit Function
End Function

'-------------------------------------------------------------------------------------------------------
Function IsAlive(strComputer, iMaxRetries, iRetryTimeOutSeconds)

   '-------------------
   ' Purpose:	Check if a computer on the network is alive by pinging to that computer
   ' Type:	Function
   ' Input:
   '		strComputer: Name of the computer to check (Type: string)
   ' 		iMaxRetries: Number of retries (Type: integer)
   ' 		iRetryTimeOutSeconds: Timeout in seconds between retries (Type: integer)
   ' Output:	Returns a boolean that specifies if the computer can be contacted
   '-------------------
   Dim IsAlive_Temp, iRetries
   Dim oPingResult, cPingResults
   IsAlive_Temp = False
   Select Case OSType
      Case OSW2K
         iRetries = 0
         Do Until iRetries = iMaxRetries
            return1 = WshShell.Run("Ping " & strComputer, RunHideWindow, RunWaitOnReturn)
            If return1 = 0 Then
               IsAlive_Temp = True
               Exit Do
            Else
               WScript.Sleep iRetryTimeOutSeconds * 1000
               iRetries = iRetries + 1
            End If
         Loop
      Case OSXP, OSW2K3, OSVista, OSW2K8, OSWin7, OSW2K8R2, OSWin8, OSWin81, OSW2K12, OSW2K12R2, OSWin10, OSWin2016
         iRetries = 0
         Do Until iRetries = iMaxRetries
            Set cPingResults = GetObject("WinMgmts:").ExecQuery("SELECT * FROM Win32_PingStatus WHERE Address = '" & strComputer & "'")
            For Each oPingResult In cPingResults
              If oPingResult.StatusCode = 0 Then
                 IsAlive_Temp = True
                 Exit Do
              Else
                 WScript.Sleep iRetryTimeOutSeconds * 1000
                 iRetries = iRetries + 1
              End If
           Next
         Loop
      Case Else
         Err.Raise 10007, "IsAlive", "Unknown OSType"
         IsAlive_Temp = False
   End Select
   IsAlive = IsAlive_Temp
End Function

'-------------------------------------------------------------------------------------------------------
Function Translate(strString)

   '-------------------
   ' Purpose:	Translate the string according to the OSLanguage
   ' Type:	Function
   ' Input:	strString: String to translate (Type: string)
   ' Output:	String that is the translated string
   '-------------------

   Dim Dic
   Set Dic = CreateObject("Scripting.Dictionary")
   Select Case OSLanguage
      Case cstEnglishUS, cstEnglishGB
         Dic.Add "Y", "Y"
         Dic.Add "y", "y"
         Dic.Add "N", "N"
         Dic.Add "n", "n"
      Case cstDutchBelgium, cstDutchNetherlands, cstGermanGermany
         Dic.Add "Y", "J"
         Dic.Add "y", "j"
         Dic.Add "N", "N"
         Dic.Add "n", "n"
      Case cstFrenchFrance
         Dic.Add "Y", "O"
         Dic.Add "y", "o"
         Dic.Add "N", "N"
         Dic.Add "n", "n"
      Case Else
         Err.Raise 10025, "Translate", "Unknown OS Language"
   End Select
   If Dic.Exists(strString) Then
      Translate = Dic.Item(strString)
   Else
      Err.Raise 10025, "Translate", "Translation not found"
   End If
End Function

'-------------------------------------------------------------------------------------------------------
Function LocalGroup(cstGroupName)

   '-------------------
   ' Purpose:	Get the name of a pre-defined local windows group
   ' Type:	Function
   ' Input:	cstGroupName: Default name of the built-in group in English (Type: string)
   ' Output:	Returns a string containing the current name of the group
   '-------------------

   Dim Return 
   Return = ""
   Dim AccountType
   AccountType = "Group"
   Select Case cstGroupName
      Case cstAdministrators
         SID = "S-1-5-32-544"
      Case cstUsers
         SID = "S-1-5-32-545"
      Case cstGuests
         SID = "S-1-5-32-546"
      Case cstPowerUsers
         SID = "S-1-5-32-547"
      Case cstAccountOperators
         SID = "S-1-5-32-548"
      Case cstServerOperators
         SID = "S-1-5-32-549"
      Case cstPrintOperators
         SID = "S-1-5-32-550"
      Case cstBackupOperators
         SID = "S-1-5-32-551"
      Case cstReplicators
         SID = "S-1-5-32-552"
      Case cstRemoteDesktopUsers
         SID = "S-1-5-32-555"
      Case cstNetworkConfigurationOperators
         SID = "S-1-5-32-556"
      Case cstEveryone
         SID = "S-1-1-0"
         AccountType = "SystemAccount"
      Case Else
         Err.Raise 1059, "LocalGroup", "Unknown cstGroupName"
   End Select

   Set Groups = GetObject("WinMgmts:").ExecQuery("SELECT Name FROM Win32_" & AccountType & " WHERE Domain = '" & sComputerName & "' AND SID = '" & SID & "'")
   For Each Group in Groups
      Return = Group.Name
   Next

   If Return = "" Then
      ' For Win2K the domain is 'BUILTIN'
      Set Groups = GetObject("WinMgmts:").ExecQuery("SELECT Name FROM Win32_" & AccountType & " WHERE Domain = 'BUILTIN' AND SID = '" & SID & "'")
      For Each Group in Groups
         Return = Group.Name
      Next
   End If

   LocalGroup = Return

End Function

'-------------------------------------------------------------------------------------------------------
Function LocalUser(cstUserName)

   '-------------------
   ' Purpose:	Get the name of a pre-defined local windows user
   ' Type:	Function
   ' Input:	cstUserName: Default name of the built-in user in English (Type: string)
   ' Output:	Returns a string containing the current name of the user
   '-------------------

   Return = ""

   Select Case cstUserName
      Case cstAdministrator
         SearchPattern = "^S-1-5-21-\d{8,}-\d{8,}-\d{8,}-500$"
      Case cstGuest
         SearchPattern = "^S-1-5-21-\d{8,}-\d{8,}-\d{8,}-501$"
      Case Else
         Err.Raise 1059, "LocalUser", "Unknown cstWindowsUser"
   End Select

   Set regEx = New RegExp
   regEx.IgnoreCase = False

   Set Users = GetObject("WinMgmts:").ExecQuery("SELECT Name, SID FROM Win32_UserAccount WHERE Domain = '" & sComputerName & "'")
   For Each User In Users
      regEx.Pattern = SearchPattern
      If regEx.Test(User.SID) Then
         Return = User.Name
         Exit For
      End If
   Next
   
   LocalUser = Return

End Function

'-------------------------------------------------------------------------------------------------------
Class Password

   '-------------------
   ' Purpose:	Class for Passwords
   ' Type:	Class
   ' Properties:
   '		Length: Set the length of the password
   ' 		Generate: Return a random password
   '-------------------

	Private RandomChar
	Private Return, NrUppercase, NrLowercase, NrNumber
	Private bRandomLength
	Private iLength

	Private Sub Class_Initialize
		bRandomLength = True
		Complex = True
		Set RandomChar = New RandomCharacter
	End Sub
	Private Sub Class_Terminate
		Set RandomChar = Nothing
	End Sub
	Private Function Scramble(strWord)
		strSource = strWord
		strDestination = ""
		For counter = 1 To Len(strWord)
			Position = Random(1, Len(strSource))
			strDestination = strDestination & Right(Left(strSource, Position), 1)
			strSource = Left(strSource, Position - 1) & Right(strSource, Len(strSource) - Position)
		Next
		Scramble = strDestination
	End Function

	Public Complex

	Public Property Let Length(NumberOfCharacters)
		bRandomLength = False
		iLength = NumberOfCharacters
	End Property

	Public Property Get Generate
		If bRandomLength Then
			iLength = Random(6, 14)
		End If

		NrUppercase = Random(1, iLength - 2)
		NrLowercase = Random(1, iLength - NrUppercase - 1)
		NrNumber = iLength - NrUppercase - NrLowercase

		Return = ""
		For counter = 1 To NrUppercase
			Return = Return & RandomChar.Uppercase
		Next
		For counter = 1 To NrLowercase
			Return = Return & RandomChar.Lowercase
		Next
		For counter = 1 To NrNumber
			Return = Return & RandomChar.Number
		Next

		Generate = Scramble(Return)
	End Property
End Class

'-------------------------------------------------------------------------------------------------------
Class RandomCharacter

   '-------------------
   ' Purpose:	Class for Random Characters
   ' Type:	Class
   ' Properties:
   '		UpperCase: Return a random uppercase character
   ' 		LowerCase: Return a random lowercase character
   ' 		Number: Return a random numeric character
   ' 		SpecialChar: Return a random special character
   '-------------------

	Private SpecialCharacters

	Private Sub Class_Initialize
		SpecialCharacters = "@#(!{})-_[*$]%?,.;/:+="
	End Sub

	Public Property Get UpperCase
		UpperCase = Chr(Random(Asc("A"), Asc("Z")))
	End Property
	Public Property Get LowerCase
		LowerCase = Chr(Random(Asc("a"), Asc("z")))
	End Property
	Public Property Get Number
		Number = Chr(Random(Asc("0"), Asc("9")))
	End Property
	Public Property Get SpecialChar
		SpecialChar = Right(Left(SpecialCharacters, Random(1, Len(SpecialCharacters))), 1)
	End Property
End Class

'-------------------------------------------------------------------------------------------------------
Function Random(iMin, iMax)

   '-------------------
   ' Purpose:	Return a random integer between a specified minimum and maximum integer
   ' Type:	Function
   ' Input:
   '		iMin: Minimal value of the random character (Type: integer)
   ' 		iMax: Maximum value of the random character (Type: integer)
   ' Output:	Integer containing a random number
   '-------------------

   Randomize
   Random = iMin + Int(Rnd * (iMax - iMin + 0.99999))
End Function

'-------------------------------------------------------------------------------------------------------
Sub DeleteFolder(strPath)

   '-------------------
   ' Purpose:	Delete a folder without having an error if the folder did not exist
   ' Type:	Sub
   ' Input:	strPath: Full path of the folder (Type: string)
   '-------------------

  If fso.FolderExists(strPath) Then
    PackageLog "Deleting folder '" & strPath & "'"
    fso.DeleteFolder strPath, True
    RuntimeErrLog
  Else
    PackageLog "Folder '" & strPath & "' already deleted"
  End If
End Sub

'-------------------------------------------------------------------------------------------------------
Sub DeleteFile(strFilePath)

   '-------------------
   ' Purpose:	Delete a file without having an error if the file did not exist
   ' Type:	Sub
   ' Input:	strPath: Full path of the file (Type: string)
   '-------------------

  If fso.FileExists(strFilePath) Then
    PackageLog "Deleting file '" & strFilePath & "'"
    fso.DeleteFile strFilePath, True
    RuntimeErrLog
  Else
    PackageLog "File '" & strFilePath & "' already deleted"
  End If
End Sub

'-------------------------------------------------------------------------------------------------------
Function WinlogonStatus

   '-------------------
   ' Purpose:	Return the windows logon status
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns a string containing the logon status:
   '			Possible values are:
   ' 				cstWinlogonNoUserLoggedOn: No user is logged on
   ' 				cstWinlogonUserLoggedOn: A user is logged on
   '-------------------

   ret = cstWinlogonNoUserLoggedOn

   'HKU = &H80000003

   Set Reg = GetObject("WinMgmts:!root/default:StdRegProv")
   Reg.EnumKey &H80000003, "", sRegKeys, 1 'fill the Array
   If UBound(sRegKeys) = 0 Then
      ' Can't open HKEY_USERS --> Nobody is logged on
      ret = cstWinlogonNoUserLoggedOn
   Else
      For i = 0 To UBound(sRegKeys)
         If (UCase(Right(sRegKeys(i), Len("_Classes"))) <> UCase("_Classes")) Then
            ' SID not ending with "_Classes"
            If (UCase(sRegKeys(i)) <> ".DEFAULT") Then
               ' Not the .Default user profile
               If (UBound(Split(sRegKeys(i), "-")) > 4) Then
                  ' SID has more than 4 parts
                  If sRegKeys(i) = GetSID(WshNetwork.UserName, sComputerName) Then
                     ' The found SID is the SID of the local account executing the script
                  Else
                     If (UCase(Split(GetAccountFromSID(sRegKeys(i)), "\")(1)) = UCase(WshNetwork.UserName)) And (UCase(Split(GetAccountFromSID(sRegKeys(i)), "\")(0)) <> UCase(sComputerName)) Then
                        ' The found SID is the SID of the domain account executing the script
                     Else
                        ' The found SID is NOT the SID of the domain account executing the script
                        ret = cstWinlogonUserLoggedOn
                        Exit For
                     End If
                  End If
               End If
            End If
         End If
      Next
   End If

   WinlogonStatus = ret
End Function

'-------------------------------------------------------------------------------------------------------
Function GetSID(strUserName, strDomain)

   '-------------------
   ' Purpose:	Get the SID of a user
   ' Type:	Function
   ' Input:
   '		strUserName: Name of the user (Type: string)
   ' 		strDomain: Name of the domain (Type: string)
   ' Output:	String containing the SID of the user
   '-------------------

   ret = ""

   ' Query on Name and Domain
   Set Users = GetObject("WinMgmts:").ExecQuery("SELECT SID FROM Win32_UserAccount WHERE Name = '" & strUserName & "' AND Domain='" & strDomain & "'")
   For Each User In Users
      ret = User.SID
   Next
   Set Users = Nothing

   GetSID = ret
End Function

'-------------------------------------------------------------------------------------------------------
Sub DisableWindowsService(strServiceName, bStopService)

   '-------------------
   ' Purpose:	Disable a Windows service and optionally stop it
   ' Type:	Sub
   ' Input:
   '		strServiceName: Name of the service (Type: string)
   ' 		bStopService: Whether the service should be stopped (Type: boolean)
   '-------------------

   On Error Resume Next

   Set objServices = GetObject("WinMgmts:").ExecQuery("SELECT * FROM Win32_Service WHERE Name='" & strServiceName & "'")
   For Each objService In objServices
      If bStopService Then
         If objService.State = "Running" Then
            RC = objService.StopService
            If RC <> 0 Then
               Err.Raise 2001, "DisableService", "Stopping the service '" & strServiceName & "' failed with RC=" & RC
            End If
            RuntimeErrLog
         End If
      End If
      RC = objService.ChangeStartMode("Disabled")
      If RC <> 0 Then
         Err.Raise 2000, "DisableService", "Disabling the service '" & strServiceName & "' failed with RC=" & RC
      End If
      RuntimeErrLog
   Next
   RuntimeErrLog
End Sub

'-------------------------------------------------------------------------------------------------------
Function GetComputerDNSDomain

   '-------------------
   ' Purpose:	Get Domain DNS Name of the computer
   ' Type:	Function
   ' Input:	None
   ' Output:	String containing the DNS Domain Name
   '-------------------

	Dim Domain, Domains, sComputerDNSDomain
	sComputerDNSDomain = ""
	
	Set Domains = GetObject("WinMgmts:").ExecQuery("SELECT Domain FROM Win32_ComputerSystem WHERE Name = '" & sComputerName & "'")
	For Each Domain In Domains
	   sComputerDNSDomain = Domain.Domain
	Next
	Set Domains = Nothing
	
	GetComputerDNSDomain = sComputerDNSDomain
	
End Function

'-------------------------------------------------------------------------------------------------------
Function GetComputerDomain

   '-------------------
   ' Purpose:	Get the domain name where the computer belongs to
   ' Type:	Function
   ' Input:	None
   ' Output:	String containing the domain name
   '-------------------

   On Error Resume Next

   ret = ""

   DomainName = GetComputerDNSDomain

   ' Replace Domain Name by DNS Domain Name
   Set Reg = GetObject("WinMgmts:!root/default:StdRegProv")
   Reg.EnumValues &H80000002, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DomainCache", sRegName, 1
   If UBound(sRegName) = 0 Then
      Err.Clear
   Else
      For iCounter = 0 To UBound(sRegName)
         Reg.GetStringValue &H80000002, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DomainCache", sRegName(iCounter), sRegData
         If UCase(sRegData) = UCase(DomainName) Then
            ret = sRegName(iCounter)
         End If
      Next
   End If

   GetComputerDomain = ret
End Function

'-------------------------------------------------------------------------------------------------------
Function GetAccountFromSID(strSID)

   '-------------------
   ' Purpose:	Get the account from the specified SID
   ' Type:	Function
   ' Input:	strSID: The SID of the account (Type: string)
   ' Output:	String containing the account (<domain>\<user>)
   '-------------------

   ret = ""

   Set objAcc = GetObject("WinMgmts:\\.\root\cimv2").Get("Win32_SID.SID='" & strSID & "'")
   ret = objAcc.ReferencedDomainName & "\" & objAcc.AccountName

   GetAccountFromSID = ret
End Function

'-------------------------------------------------------------------------------------------------------
Function RebootIsPending

   '-------------------
   ' Purpose:	Check if a reboot is pending
   ' Type:	Function
   ' Input:	None
   ' Output:	Boolean that specifies of a reboot is pending
   '-------------------

   On Error Resume Next
   Return = False
   RC = objReg.GetMultiStringValue(&H80000002, "SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations", arrValues)
   If (RC = 0) And (Err.Number = 0) Then
      For Each strValue In arrValues
         If InStr(UCase(strValue), UCase("\??\" & WshShell.ExpandEnvironmentStrings("%WinDir%") & "\INS\$RebootPending$")) > 0 Then
            Return = True
         End If
      Next
   Else
      Err.Clear
   End If
   RebootIsPending = Return
End Function

'-------------------------------------------------------------------------------------------------------
Sub SetRebootPending

   '-------------------
   ' Purpose:	Set reboot pending
   ' Type:	Sub
   ' Input:	None
   '-------------------

   On Error Resume Next
   If Not RebootIsPending Then
      objReg.CreateKey &H80000002,"SYSTEM\CurrentControlSet\Control\Session Manager"
      objReg.SetMultiStringValue &H80000002, "SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations", Array("\??\" & sWinDir & "\INS\$RebootPending$", "")
   End If
End Sub

'-------------------------------------------------------------------------------------------------------
Sub ReplaceTextInFile(strFilePath, strFindString, strReplaceWith)

   '-------------------
   ' Purpose:	Replace text in a file
   ' Type:	Sub
   ' Input:
   '		strFilePath: Full path of the file (Type: string)
   ' 		strFindString: Text to find in the file (Type: string)
   ' 		strReplaceWith: New text to be placed in the file (Type: string)
   '-------------------

   On Error Resume Next

   ' Retrieve the content of the file in ASCII
   Set objFile = fso.OpenTextFile(strFilePath, fsoForReading, False, fsoASCII)
   FileContentASCII = objFile.ReadAll
   objFile.Close

   ' Retrieve the content of the file in Unicode
   Set objFile = fso.OpenTextFile(strFilePath, fsoForReading, False, fsoUnicode)
   FileContentUnicode = objFile.ReadAll
   objFile.Close

   ' Decide if the file is ASCII or Unicode
   Select Case (Len(FileContentASCII) - LenB(FileContentUnicode))
      Case 0, 1
         FileContent = FileContentASCII
         FileType = fsoASCII
      Case 2
         FileContent = FileContentUnicode
         FileType = fsoUnicode
   End Select
   FileContentASCII = ""
   FileContentUnicode = ""

   ' Replace the content
   FileContent = Replace(FileContent, strFindString, strReplaceWith, 1, -1, vbTextCompare)

   ' Write the content to the same file
   Set objFile = fso.CreateTextFile(strFilePath, True, FileType)
   objFile.Write FileContent
   objFile.Close

End Sub

'-------------------------------------------------------------------------------------------------------
Class AutoLogon

   '-------------------
   ' Purpose:	Class for AutoLogon
   ' Type:	Class
   ' Properties:
   '		SetAutoLogon: Set AutoLogon
   ' 		RestoreAutoLogon: Restore from AutoLogon
   ' 		AutoLogonAccount: Returns the account used for AutoLogon
   ' 		DisableInput: Disables Input Devices
   ' 		EnableInput: Enables Input Devices
   '-------------------

	Private strRegWinlogon
	Private strRegWinlogonBackup
	Private strAutoLogonAccount
	Private strAutoLogonPassword

	' Class_Initialize
	'------------------
	Private Sub Class_Initialize
		strRegWinlogon		= "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
		strRegWinlogonBackup	= "HKLM\SOFTWARE\INS\Winlogon"
		strAutoLogonAccount	= "~AutoLogon~"
	End Sub

	' Class_Terminate
	'-----------------
	Private Sub Class_Terminate
		'Set X = Nothing
	End Sub

	' Class Private
	'---------------
	Private Sub BackupWinlogonRegistry
		On Error Resume Next
		BU_DefaultUserName	= WshShell.RegRead(strRegWinlogon & "\DefaultUserName")
		BU_DefaultDomainName	= WshShell.RegRead(strRegWinlogon & "\DefaultDomainName")
		BU_DefaultPassword	= WshShell.RegRead(strRegWinlogon & "\DefaultPassword")
		BU_AutoAdminLogon	= WshShell.RegRead(strRegWinlogon & "\AutoAdminLogon")
		BU_Shell		= WshShell.RegRead(strRegWinlogon & "\Shell")
		BU_LegalNoticeCaption	= WshShell.RegRead(strRegWinlogon & "\LegalNoticeCaption")
		BU_LegalNoticeText	= WshShell.RegRead(strRegWinlogon & "\LegalNoticeText")
		Err.Clear

		WshShell.RegWrite strRegWinlogonBackup & "\DefaultUserName",	BU_DefaultUserName
		WshShell.RegWrite strRegWinlogonBackup & "\DefaultDomainName",	BU_DefaultDomainName
		WshShell.RegWrite strRegWinlogonBackup & "\DefaultPassword",	BU_DefaultPassword
		WshShell.RegWrite strRegWinlogonBackup & "\AutoAdminLogon",	BU_AutoAdminLogon
		WshShell.RegWrite strRegWinlogonBackup & "\Shell",		BU_Shell
		WshShell.RegWrite strRegWinlogonBackup & "\LegalNoticeCaption",	BU_LegalNoticeCaption
		WshShell.RegWrite strRegWinlogonBackup & "\LegalNoticeText",	BU_LegalNoticeText
	End Sub
	Private Sub RestoreWinlogonRegistry
		On Error Resume Next
		WshShell.RegWrite strRegWinlogon & "\DefaultUserName",		WshShell.RegRead(strRegWinlogonBackup & "\DefaultUserName")
		WshShell.RegWrite strRegWinlogon & "\DefaultDomainName",	WshShell.RegRead(strRegWinlogonBackup & "\DefaultDomainName")
		WshShell.RegWrite strRegWinlogon & "\DefaultPassword",		WshShell.RegRead(strRegWinlogonBackup & "\DefaultPassword")
		WshShell.RegWrite strRegWinlogon & "\AutoAdminLogon",		WshShell.RegRead(strRegWinlogonBackup & "\AutoAdminLogon")
		WshShell.RegWrite strRegWinlogon & "\Shell",			WshShell.RegRead(strRegWinlogonBackup & "\Shell")
		WshShell.RegWrite strRegWinlogon & "\LegalNoticeCaption",	WshShell.RegRead(strRegWinlogonBackup & "\LegalNoticeCaption")
		WshShell.RegWrite strRegWinlogon & "\LegalNoticeText",		WshShell.RegRead(strRegWinlogonBackup & "\LegalNoticeText")
		WshShell.RegDelete strRegWinlogonBackup & "\"
	End Sub
	Private Sub SetWinlogonRegistry(strUserName, strDomainName, strPassword, strShell)
		On Error Resume Next
		WshShell.RegWrite strRegWinlogon & "\DefaultUserName",		strUserName
		WshShell.RegWrite strRegWinlogon & "\DefaultDomainName",	strDomainName
		WshShell.RegWrite strRegWinlogon & "\DefaultPassword",		strPassword
		WshShell.RegWrite strRegWinlogon & "\AutoAdminLogon",		"1"
		WshShell.RegWrite strRegWinlogon & "\Shell",			strShell
		WshShell.RegDelete strRegWinlogon & "\LegalNoticeCaption"
		WshShell.RegDelete strRegWinlogon & "\LegalNoticeText"
	End Sub
	Private Sub CreateLocalAdminAccount(strAdminName, strAdminPwd)
		On Error Resume Next
		PackageLog "AutoLogonCls: Delete any previous " & strAdminName & " account"
		WshShell.Run "net user " & strAdminName & " /delete", 0, True
		Err.Clear
		PackageLog "AutoLogonCls: Creating local " & strAdminName & " account"
		WshShell.Run "net user " & strAdminName & " " & strAdminPwd & " /add", 0, True
		RuntimeErrLog
		PackageLog "AutoLogonCls: Adding local " & strAdminName & " account to local administrators group"
		WshShell.Run "net localgroup " & LocalGroup(cstAdministrators) & " " & strAdminName & " /add", 0, True
		RuntimeErrLog
	End Sub

	' Class Public
	'--------------
	Public Sub SetAutoLogon(strShell, bBackup)
		If bBackup Then
		   Call BackupWinlogonRegistry
		End If
		strAutoLogonPassword = GeneratePassword(14)
		Call CreateLocalAdminAccount(strAutoLogonAccount, strAutoLogonPassword)
		Call SetWinlogonRegistry(strAutoLogonAccount, sComputerName, strAutoLogonPassword, strShell)
	End Sub

	Public Sub RestoreAutoLogon
		Call RestoreWinlogonRegistry
	End Sub
	
	Public Sub DisableInput
		WshShell.RegWrite "HKLM\SYSTEM\CurrentControlSet\Services\Kbdclass\Start", "4" ,"REG_DWORD"
		WshShell.RegWrite "HKLM\SYSTEM\CurrentControlSet\Services\Mouclass\Start", "4" ,"REG_DWORD"
	End Sub
	
	Public Sub EnableInput
		WshShell.RegWrite "HKLM\SYSTEM\CurrentControlSet\Services\Kbdclass\Start", "1" ,"REG_DWORD"
		WshShell.RegWrite "HKLM\SYSTEM\CurrentControlSet\Services\Mouclass\Start", "1" ,"REG_DWORD"
	End Sub
	
	Public Property Get AutoLogonAccount
		AutoLogonAccount = strAutoLogonAccount
	End Property
End Class

'-------------------------------------------------------------------------------------------------------
Sub SetCleanupScript

   '-------------------
   ' Purpose:	Set the clean-up script after AutoLogon has run
   ' Type:	Sub
   ' Input:	None
   '-------------------

   On Error Resume Next

   PackageLog "AutoLogonClean: Creating Cleanup script"
   strCleanupScript = sSystemDrive & "\RunAsAdmin\xx_Cleanup.vbs"
   ' Create Cleanup for files from AutoLogon
   Set File = fso.OpenTextFile(strCleanupScript, 2,True)
   File.WriteLine "On Error Resume Next"
   File.WriteLine "Set WshShell	= WScript.CreateObject(" & Chr(34) & "Wscript.Shell" & Chr(34) & ")"
   File.WriteLine "Set fso		= CreateObject(" & Chr(34) & "Scripting.FileSystemObject" & Chr(34) & ")"
   File.WriteLine "fso.DeleteFolder " & Chr(34) & sSystemDrive & "\RunAsAdmin" & Chr(34) & ", True"
   File.WriteLine "fso.DeleteFolder " & Chr(34) & WshShell.ExpandEnvironmentStrings(WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\ProfilesDirectory")) & "\" & MyAutoLogon.AutoLogonAccount & "*" & Chr(34) & ", True"
   File.Close
   Set File = Nothing
   RuntimeErrLog

End Sub

'--------------------------------------------------------------------------------------------------------------
Sub SetNTFSPermissions(sFolderFileName, sNTFSPermissions, sAddOrReplacePermissions, bIncludeSubfolders)

   '-------------------

   ' Purpose:	Set NTFS Permissions on files and folders and choose if it must apply to subfolders or not
   ' Type:	Sub
   ' Input:
   '		sFolderFileName: Full path of the file or folder (Type: string)

   ' 		sNTFSPermissions: NTFS Permissions to set according to the xcacls.exe /G parameter (Type: string)
   ' 		sAddOrReplacePermissions: How security should apply (Type: string)
   '			Possible values are:
   ' 				AddPermissions: Adds the specified permissions
   ' 				ReplacePermissions: Replaces the specified permissions
   ' 		bIncludeSubfolders: Whether to include subfolders to apply permissions
   '-------------------

   On Error Resume Next

   'Placing quotes around the group names
   sNewSecurity = ""
   iStartGroupPosition = 0
   iEndGroupPosition = 1
   Do While InStr(iEndGroupPosition, sNTFSPermissions, ":", 1) > 0
      iEndGroupPosition = InStr(iEndGroupPosition, sNTFSPermissions, ":", 1)
      sNewSecurity = sNewSecurity & Chr(34) & Mid(sNTFSPermissions, iStartGroupPosition + 1, iEndGroupPosition - iStartGroupPosition - 1) & Chr(34)
      If InStr(iEndGroupPosition, sNTFSPermissions, " ", 1) > 0 Then
         iStartGroupPosition = InStr(iEndGroupPosition,sNTFSPermissions," ",1)
         sNewSecurity = sNewSecurity & Mid(sNTFSPermissions, iEndGroupPosition, iStartGroupPosition - iEndGroupPosition) & " "
         iEndGroupPosition = iStartGroupPosition
      ElseIf InStr(iEndGroupPosition, sNTFSPermissions, " ", 1) = 0 Then
         iStartGroupPosition = Len(sNTFSPermissions)
         sNewSecurity = sNewSecurity & Mid(sNTFSPermissions, iEndGroupPosition, iStartGroupPosition - iEndGroupPosition + 1)
         iEndGroupPosition = Len(sNTFSPermissions)
      End If
   Loop
   ' Defining which xcacls.exe file will be used
   If fso.FileExists(sWinDir & "\System32\xcacls.exe") Then
      sACLCommand = sWinDir & "\System32\xcacls.exe"
   Else
      If fso.FileExists(sCurrentFolder & "\INS\" & OSType & "\xcacls.exe") Then
         sACLCommand = sCurrentFolder & "\INS\" & OSType & "\xcacls.exe"
      Else
         sACLCommand = sCurrentFolder & "\INS\xcacls.exe"
      End If
   End If

   ' Check if the file or folder exists
   If fso.FileExists(sACLCommand) Then
      If fso.FolderExists(sFolderFileName) Then
         ' It is a folder
      ElseIf fso.FileExists(sFolderFileName) Then
         ' It is a file
      ElseIf (InStr(1, sFolderFileName, "?", vbTextCompare) > 0) Or (InStr(1, sFolderFileName, "*", vbTextCompare) > 0) Then
         ' Using wildcards
      Else
         Err.Raise 2010, "WSH", sFolderFileName & " not found !"
      End If
   End If
   RuntimeErrLog
   ' Building xcacls.exe command line parameters
   sACLCommandLineParameters = "/Y /C"
   If bIncludeSubfolders Then
      sACLCommandLineParameters = sACLCommandLineParameters & " /T"
   End If
   Select Case sAddOrReplacePermissions
      Case ReplacePermissions
         ' OK
      Case AddPermissions
         sACLCommandLineParameters = sACLCommandLineParameters & " /E"
      Case Else
         Err.Raise 2003, "WSH", "Unknown value '" & sAddOrReplacePermissions & "'"
   End Select
   RuntimeErrLog

   ' Executing the xcacls.exe command
   PackageLog sAddOrReplacePermissions & " NTFS Permissions on " & sFolderFileName & " : " & sNTFSPermissions & VbCrLf
   If InStr(sFolderFileName, " ") > 0 Then
      sFolderFileName = Chr(34) & sFolderFileName & Chr(34)
   End If
   RC = WshShell.Run(sComspec & " /c " & sACLCommand & " " & sFolderFileName & " " & sACLCommandLineParameters & " /G " & sNewSecurity & " >> " & sPackageLogFile, 0, True)
   If RC <> 0 Then
      Err.Raise 2001, "WSH", sACLCommand & " returned " & RC
   End If
   RuntimeErrLog
   WshShell.Run sComspec & " /c echo. >> " & sPackageLogFile, 0, True

End Sub

Sub SetINTFSPermissions(sFolderFileName, sNTFSPermissions, sAddOrReplacePermissions, bIncludeSubfolders)

   '-------------------
   ' Purpose:	Set NTFS Permissions (using icacls.exe) on files and folders and choose if it must apply to subfolders or not
   ' Type:	Sub
   ' Input:
   '		sFolderFileName: Full path of the file or folder (Type: string)
   ' 		sNTFSPermissions: NTFS Permissions to set according to the icacls.exe /grant parameter (Type: string)
   ' 		sAddOrReplacePermissions: How security should apply (Type: string)
   '			Possible values are:
   ' 				AddPermissions: Adds the specified permissions
   ' 				ReplacePermissions: Replaces the specified permissions
   ' 		bIncludeSubfolders: Whether to include subfolders to apply permissions
   '-------------------

   On Error Resume Next

   'Placing quotes around the group names
   sNewSecurity = ""
   iStartGroupPosition = 0
   iEndGroupPosition = 1
   Do While InStr(iEndGroupPosition, sNTFSPermissions, ":", 1) > 0
      iEndGroupPosition = InStr(iEndGroupPosition, sNTFSPermissions, ":", 1)
      sNewSecurity = sNewSecurity & Chr(34) & Mid(sNTFSPermissions, iStartGroupPosition + 1, iEndGroupPosition - iStartGroupPosition - 1) & Chr(34)
      If InStr(iEndGroupPosition, sNTFSPermissions, " ", 1) > 0 Then
         iStartGroupPosition = InStr(iEndGroupPosition,sNTFSPermissions," ",1)
         sNewSecurity = sNewSecurity & Mid(sNTFSPermissions, iEndGroupPosition, iStartGroupPosition - iEndGroupPosition) & " "
         iEndGroupPosition = iStartGroupPosition
      ElseIf InStr(iEndGroupPosition, sNTFSPermissions, " ", 1) = 0 Then
         iStartGroupPosition = Len(sNTFSPermissions)
         sNewSecurity = sNewSecurity & Mid(sNTFSPermissions, iEndGroupPosition, iStartGroupPosition - iEndGroupPosition + 1)
         iEndGroupPosition = Len(sNTFSPermissions)
      End If
   Loop

   ' Defining which icacls.exe file will be used
   If fso.FileExists(sWinDir & "\System32\icacls.exe") Then
      sACLCommand = sWinDir & "\System32\icacls.exe"
   Else
	  sACLCommand = sCurrentFolder & "\INS\icacls.exe"
   End If

   ' Check if the file or folder exists
   If fso.FileExists(sACLCommand) Then
      If fso.FolderExists(sFolderFileName) Then
         ' It is a folder
      ElseIf fso.FileExists(sFolderFileName) Then
         ' It is a file
      ElseIf (InStr(1, sFolderFileName, "?", vbTextCompare) > 0) Or (InStr(1, sFolderFileName, "*", vbTextCompare) > 0) Then
         ' Using wildcards
      Else
         Err.Raise 2010, "WSH", sFolderFileName & " not found !"
      End If
   End If
   RuntimeErrLog

   ' Building icacls.exe command line parameters
   sACLCommandLineParameters = "/C"
   If bIncludeSubfolders Then
      sACLCommandLineParameters = sACLCommandLineParameters & " /T"
   End If
   
   ' Executing the icacls.exe command
   PackageLog sAddOrReplacePermissions & " NTFS Permissions on " & sFolderFileName & " : " & sNTFSPermissions & VbCrLf
   If InStr(sFolderFileName, " ") > 0 Then
      sFolderFileName = Chr(34) & sFolderFileName & Chr(34)
   End If
   
   Select Case sAddOrReplacePermissions
      Case ReplacePermissions
		RC = WshShell.Run(sComspec & " /c " & sACLCommand & " " & sFolderFileName & " " & sACLCommandLineParameters & " /grant:r " & sNewSecurity & " >> " & sPackageLogFile, 0, True)
      Case AddPermissions
		RC = WshShell.Run(sComspec & " /c " & sACLCommand & " " & sFolderFileName & " " & sACLCommandLineParameters & " /grant " & sNewSecurity & " >> " & sPackageLogFile, 0, True)
      Case Else
         Err.Raise 2003, "WSH", "Unknown value '" & sAddOrReplacePermissions & "'"
   End Select
   RuntimeErrLog

   If RC <> 0 Then
		Err.Raise 2001, "WSH", sACLCommand & " returned " & RC
   End If
   RuntimeErrLog
   WshShell.Run sComspec & " /c echo. >> " & sPackageLogFile, 0, True
   
End Sub

'--------------------------------------------------------------------------------------------------------------
Sub ExecuteRunOnce

   '-------------------
   ' Purpose:	Execute the RunOnce values in the registry
   ' Type:	Sub
   ' Input:	None
   '-------------------

   On Error Resume Next

   Set Reg = GetObject("WinMgmts:!root/default:StdRegProv")
   Reg.EnumValues hexHKLM, "SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", sRegValues, 1
   If Not IsNull(sRegValues) Then
      For Each sRegVal In sRegValues
         Reg.GetStringValue hexHKLM, "SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", sRegVal, sRegValData
         PackageLog "Executing RunOnce Value '" & sRegVal & "': " & sRegValData
         If Left(sRegValData, 1) <> Chr(34) Then
            sRegValData = Chr(34) & sRegValData & Chr(34)
         End If
         WshShell.Run sRegValData, 0, True
         RuntimeErrLog
         Reg.DeleteValue hexHKLM, "SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", sRegVal
      Next
   Else
      PackageLog "No RunOnce values to execute."
   End If
   RuntimeErrLog
End Sub

'--------------------------------------------------------------------------------------------------------------
Function ConvertVersionToNumeric(strVersion)

   '-------------------
   ' Purpose:	Convert Version Number to a numeric value (for comparing)
   ' Type:	Function
   ' Input:	strVersion: Version number (Type: string)
   ' Output:	String containing the version number
   '-------------------

   On Error Resume Next

   arrVersion = Split(strVersion, ".")

   strVersionFull = ""
   For i = 0 To UBound(arrVersion)
       If Len(arrVersion(i)) > 5 Then
          Err.Raise 1234, "ConvertVersionToNumeric", "The version can not be converted ('" & arrVersion(i) & "' of '" & strVersion & "') contains to many chars"
       End If
       strVersionFull = strVersionFull + Right((String(5, "0") & arrVersion(i)), 5)
   Next
   For i = UBound(arrVersion) To 3
      strVersionFull = strVersionFull & String(5, "0")
   Next
   RuntimeErrLog

   ConvertVersionToNumeric = strVersionFull

End Function

'--------------------------------------------------------------------------------------------------------------
Function RetrieveCPUArchitecture

   '-------------------
   ' Purpose:	Retrieve the CPU Architecture
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns a string containing the CPU Architecture
   '			Possible values are:
   ' 				CPUx86
   ' 				CPUx64
   ' 				CPUia64
   '-------------------

   On Error Resume Next

   Set oCPUs = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT Architecture FROM Win32_Processor")
   For Each oCPU In oCPUs
      Select Case oCPU.Architecture
         Case 0 ' "x86"
            RetrieveCPUArchitecture = CPUx86
            Exit For
         Case 1, 2, 3
            ' 1 = "MIPS"
            ' 2 = "Alpha"
            ' 3 = "PowerPC"
            Err.Raise 1021, "RetrieveCPUArchitecture", "Unsupported CPU Architecture"
            RuntimeErrLog
            RetrieveCPUArchitecture = ""
            Exit For
         Case 6 ' "ia64"
            RetrieveCPUArchitecture = CPUia64
            Exit For
         Case 9 ' "x64"
            RetrieveCPUArchitecture = CPUx64
            Exit For
         Case Else
            Err.Raise 1021, "RetrieveCPUArchitecture", "Unknown CPU Architecture"
            RuntimeErrLog
            RetrieveCPUArchitecture = ""
            Exit For
      End Select
   Next
End Function     

'--------------------------------------------------------------------------------------------------------------
Function RetrieveOSArchitecture

   '-------------------
   ' Purpose:	Retrieve the OS Architecture
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns a string containing the OS Architecture
   '			Possible values are:
   ' 				OSx86
   ' 				OSx64
   '-------------------

   On Error Resume Next

   Select Case OSType
      Case OSNT4, OSW2K, OSXP, OSW2K3
         Set oCPUs = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT Architecture FROM Win32_Processor")
         For Each oCPU In oCPUs
            Select Case oCPU.Architecture
               Case 0 ' "x86"
                  RetrieveOSArchitecture = OSx86
                  Exit For
               Case 1, 2, 3
                  ' 1 = "MIPS"
                  ' 2 = "Alpha"
                  ' 3 = "PowerPC"
                  ' 6 = "ia64"
                  Err.Raise 1021, "RetrieveOSArchitecture", "Unsupported OS Architecture"
                  RuntimeErrLog
                  RetrieveOSArchitecture = ""
                  Exit For
               Case 6 ' "ia64"
                  RetrieveOSArchitecture = OSia64
                  Exit For
               Case 9 ' "x64"
                  RetrieveOSArchitecture = OSx64
                  Exit For
               Case Else
                  Err.Raise 1021, "RetrieveOSArchitecture", "Unknown OS Architecture"
                  RuntimeErrLog
                  RetrieveOSArchitecture = ""
                  Exit For
            End Select
         Next
      Case OSVista, OSW2K8, OSWin7, OSW2K8R2, OSWin8, OSWin81, OSW2K12, OSW2K12R2, OSWin10, OSWin2016
         Set oOSs = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT OSArchitecture FROM Win32_OperatingSystem")
         For Each oOS In oOSs
            If Instr(UCase(oOS.OSArchitecture),"32")>0 Then
				RetrieveOSArchitecture = OSx86
			ElseIf Instr(UCase(oOS.OSArchitecture),"64")>0 Then
                RetrieveOSArchitecture = OSx64
            Else
                Err.Raise 1021, "RetrieveOSArchitecture", "Unknown OS Architecture"
                RuntimeErrLog
                RetrieveOSArchitecture = ""
                Exit For
            End If
         Next
      Case Else
         Err.Raise 1022, "RetrieveOSArchitecture", "Unsupported OS Architecture"
         RuntimeErrLog
   End Select
End Function     

'--------------------------------------------------------------------------------------------------------------
Sub CopyShortcuts

   '-------------------
   ' Purpose:	Copy shortcuts from the Shortcuts folder
   ' Type:	Sub
   ' Input:	None
   '-------------------

   Dim ShortcutsFolders

   If Not bErrorOccured Then

      If OSArchitecture = ApplicationArchitecture Then
         ShortcutsFolders = sCurrentFolder & "\Shortcuts\Native"
      Else
         ShortcutsFolders = sCurrentFolder & "\Shortcuts\WOW64"
      End If
      If Not fso.FolderExists(ShortcutsFolders) Then
         ShortcutsFolders = sCurrentFolder & "\Shortcuts"
      End If

      PackageLog "Copying shortcuts..."
      If fso.FolderExists(ShortcutsFolders & "\AllUsersDesktop") Then
         PackageLog "Copying shortcuts to AllUsersDesktop"
         fso.CopyFolder ShortcutsFolders & "\AllUsersDesktop", sAllUsersDesktop ,True
      End If
      If fso.FolderExists(ShortcutsFolders & "\AllUsersPrograms") Then
         PackageLog "Copying shortcuts to AllUsersPrograms"
         fso.CopyFolder ShortcutsFolders & "\AllUsersPrograms", sAllUsersPrograms ,True
      End If
      If fso.FolderExists(ShortcutsFolders & "\AllUsersStartMenu") Then
         PackageLog "Copying shortcuts to AllUsersStartMenu"
         fso.CopyFolder ShortcutsFolders & "\AllUsersStartMenu", sAllUsersStartMenu ,True
      End If
   Else
      PackageLog "Not copying shortcuts (An error already occured)."
   End If
End Sub

'--------------------------------------------------------------------------------------------------------------
Class FileSystemObjectX

   '-------------------
   ' Purpose:	File System Object eXtension
   ' Type:	Class
   ' Properties:	None
   ' Methods:
   '		DeleteFile: Delete a file
   ' 		DeleteFolder: Delete a folder
   ' 		CreateFolder: Create a folder
   ' 		ReplaceInUseFile: Replace a file in use
   '-------------------

   Private fso

   Private Sub Class_Initialize
      On Error Resume Next
      Set fso = CreateObject("Scripting.FileSystemObject")
   End Sub

   Public Sub DeleteFile(strFileName)

      '-------------------
      ' Purpose: Delete a file without error if it wass already deleted
      '-------------------

      On Error Resume Next

      If fso.FileExists(strFileName) Then
          fso.DeleteFile strFileName, True
      End If
   End Sub

   Public Sub DeleteFolder(strFolderName)

      '-------------------
      ' Purpose: Delete a folder without error if it was already deleted
      '-------------------

      On Error Resume Next

      If fso.FolderExists(strFolderName) Then
          fso.DeleteFolder strFolderName, True
      End If
   End Sub

   Public Sub RenameFileAfterReboot(strSourceFileName, strDestinationFileName)

      '-------------------
      ' Purpose: Rename a file after rebooting (Use empty DestinationFileName to delete)
      '-------------------

      On Error Resume Next
      Return = objReg.GetMultiStringValue(&H80000002, "SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations", arrValues)
      If (Return = 0) And (Err.Number = 0) Then
         Redim Preserve arrValues(UBound(arrValues) + 2)
      Else
         Err.Clear
         objReg.CreateKey &H80000002,"SYSTEM\CurrentControlSet\Control\Session Manager"
         Redim arrValues(1)
      End If
      arrValues(UBound(arrValues) - 1) = "\??\" & strSourceFileName
      If strDestinationFileName = "" Then
         arrValues(UBound(arrValues)) = ""
      Else
         arrValues(UBound(arrValues)) = "!\??\" & strDestinationFileName
      End If
      objReg.SetMultiStringValue &H80000002, "SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations", arrValues
   End Sub

   Public Sub CreateFolder(strFolderName)

      '-------------------
      ' Purpose: Create a folder whether the parent folder exists or not
      '-------------------

      On Error Resume Next

      If Left(strFolderName, 2) = "\\" Then
        
         '-------------------
         ' UNC Path
         '-------------------

         Dim strShare

         strShare = "\\" & Split(Right(strFolderName, Len(strFolderName) - 2), "\", 3, vbTextCompare)(0) & "\" & Split(Right(strFolderName, Len(strFolderName) - 2), "\", 3, vbTextCompare)(1)

         If fso.FolderExists(strShare) Then
            Call CreateThisFolder(strFolderName)
         Else
            Err.Raise, 11002, "FileSystemObjectX", "The network path could not be found."
         End If
    
      ElseIf Right(Left(strFolderName, 3), 2) = ":\" Then
        
         '-------------------
         ' Normal Path
         '-------------------

         Dim strDrive
        
         strDrive = Left(strFolderName, 3)
        
         If fso.DriveExists(strDrive) Then
            Call CreateThisFolder(strFolderName)
         Else
            Err.Raise, 11001, "FileSystemObjectX", "The drive could not be found."
         End If
    
      Else
         Err.Raise, 11000, "FileSystemObjectX", "Invalid foldername."
      End If
   End Sub

   Public Sub ReplaceInUseFile(strSourceFile, strDestinationFile)

      '-------------------
      ' Purpose: Replace a file that is in use
      '-------------------

      On Error Resume Next

      Dim strNewSourceFile, objReg, arrValues

      If Left(strSourceFile, 2) = "\\" Then
         strNewSourceFile = strDestinationFile & "~" & Random(1000, 9999)
         If fso.FileExists(strSourceFile) Then
            fso.CopyFile strSourceFile, strNewSourceFile, False
         Else
            Err.Raise 2002, "ReplaceInUseFile", "File '" & strSourceFile & "' not found"
            Exit Sub
         End If
      Else
         strNewSourceFile = strSourceFile
      End If

      Return = objReg.GetMultiStringValue(&H80000002, "SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations", arrValues)
      If (Return = 0) And (Err.Number = 0) Then
         Redim Preserve arrValues(UBound(arrValues) + 2)
         arrValues(UBound(arrValues) - 1) = "\??\" & strNewSourceFile
         arrValues(UBound(arrValues)) = "!\??\" & strDestinationFile
         objReg.SetMultiStringValue &H80000002, "SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations", arrValues
      Else
         Err.Clear
         objReg.CreateKey &H80000002,"SYSTEM\CurrentControlSet\Control\Session Manager"
         objReg.SetMultiStringValue &H80000002, "SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations", Array("\??\" & strNewSourceFile, "!\??\" & strDestinationFile)
      End If
   End Sub

   Private Sub CreateThisFolder(strFolderName)

      '-------------------
      ' Create a folder Recursively
      '-------------------

      On Error Resume Next
    
      Dim strParentFolder
    
      strParentFolder = fso.GetParentFolderName(strFolderName)
    
      If Not fso.FolderExists(strFolderName) Then
         If Not fso.FolderExists(strParentFolder) Then
            Call CreateThisFolder(strParentFolder)
         End If
         Call fso.CreateFolder(strFolderName)
      End If
   End Sub

End Class

'--------------------------------------------------------------------------------------------------------------
Class clsSCCM

   '-------------------
   ' Purpose:	SCCM Class
   ' Type:	Class
   ' Properties:	None
   ' Methods:	IsTaskSequence: Returns a boolean whether the package is send using a Task Sequence
   '-------------------

   Private Sub Class_Initialize
   End Sub

   Private Sub Class_Terminate
   End Sub

   Public Function IsTaskSequence

      '-------------------
      ' Check if the package is send using a Task Sequence
      '-------------------

      On Error Resume Next
      Dim env, Result

      Set env = CreateObject("Microsoft.SMS.TSEnvironment")
      If Err.Number = 0 Then
         Result = True
      Else
         Err.Clear
         Result = False
      End If
      Set env = Nothing

      IsTaskSequence = Result
   End Function
End Class

'--------------------------------------------------------------------------------------------------------------
Function ExecAfterRebootIsEmpty

   '-------------------
   ' Purpose:	Check if 'ExecuteAfterReboot' is empty
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns a boolean that specifies if the 'ExecuteAfterReboot' value is empty
   '-------------------

   On Error Resume Next
   PackageLog "Check if ExecuteAfterReboot is empty..."

   strExecAR = WshShell.RegRead(sRegRatAgentTask & "\ExecuteAfterReboot")
   Err.Clear
   If Len(strExecAR) > 0 Then
      ExecAfterRebootIsEmpty = False
      PackageLog "Check if ExecuteAfterReboot is NOT empty..."
   Else
      ExecAfterRebootIsEmpty = True
      PackageLog "Check if ExecuteAfterReboot is empty..."
   End If
   RuntimeErrLog
End Function

'--------------------------------------------------------------------------------------------------------------
Function SystemUpTime

   '-------------------
   ' Purpose:	Find the system up time
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns an integer that specifies the number of seconds the system is up
   '-------------------

   On Error Resume Next
   Select Case OSType
      Case OSNT4, OSW2K
         Return = 0
      Case OSXP, OSW2K3, OSVista, OSW2K8, OSWin7, OSW2K8R2, OSWin8, OSWin81, OSW2K12, OSW2K12R2, OSWin10, OSWin2016
         Set objDT = CreateObject("WbemScripting.SWbemDateTime")
         Set oOSses = GetObject("WinMgmts:\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_OperatingSystem")
         For Each oOS In oOSses
            objDT.Value = oOS.LastBootUpTime
            Return = DateDiff ("s", objDT.GetVarDate(True), Now)
         Next
      Case Else
         Err.Raise 1043, "SystemUpTime", "Unsupported OSType '" & OSType & "'"
         RuntimeErrLog
   End Select
   If Err <> 0 Then
      Err.Clear
      Return = 0
      PackageLog "WARNING! SystemUpTime returned #" & Err.Number & " " & Err.Description
   End If
   RuntimeErrLog
   
   SystemUpTime = Return
End Function

'--------------------------------------------------------------------------------------------------------------
Function RetrieveOSProductType

   '-------------------
   ' Purpose:	Retrieve the Operating System product type
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns a string containing the OS Type
   '			Possible values are:
   ' 				OSClient
   ' 				OSServer
   '-------------------

   Set oOperatingSystems = GetObject("WinMgmts:").ExecQuery("SELECT ProductType FROM Win32_OperatingSystem")
   For Each oOS In oOperatingSystems
      Select Case oOS.ProductType
         Case 1
            RetrieveOSProductType = OSClient
         Case 2, 3
            RetrieveOSProductType = OSServer
         Case Else
            Err.Raise 1020, "RetrieveOSProductType", "Unknown OS ProductType"
            RuntimeErrLog
            RetrieveOSProductType = ""
      End Select
      Exit For
   Next
End Function

'--------------------------------------------------------------------------------------------------------------
Function RequiredWindowsInstallerVersion(strRequiredVersion)

   '-------------------
   ' Purpose:	Check if the required Windows Installer version is installed
   ' Type:	Function
   ' Output:	Boolean returning True if the if the required version is installed
   ' Input:	strRequiredVersion: Version of the required Windows Installer version (Type: string)
   '-------------------

   Dim Installer

   Set Installer = WScript.CreateObject("WindowsInstaller.Installer")

   If ConvertVersionToNumeric(Installer.Version) < ConvertVersionToNumeric(strRequiredVersion) Then
      RequiredWindowsInstallerVersion = False
   Else
      RequiredWindowsInstallerVersion = True
   End If
End Function

'--------------------------------------------------------------------------------------------------------------
Sub StopScriptExecution(strReason)

   '-------------------
   ' Purpose:	Stop the execution of the script with an error
   ' Type:	Sub
   ' Input:	strReason: The reason why the script execution is stopped (Type: string)
   '-------------------

   On Error Resume Next

   Err.Raise 156, "StopScriptExecution", strReason
   RuntimeErrLog
   EndLog
End Sub

'---------------------------------------------------------------------------------------------
Sub SkipScriptExecution(strReason)

   '-------------------
   ' Purpose:	Skip the execution of the script
   ' Type:	Sub
   ' Input:	strReason: The reason why the script execution is skipped (Type: string)
   '-------------------

   On Error Resume Next

   PackageLog "The execution of the script is skipped. Reason: " & strReason
   RuntimeErrLog
   EndLog
End Sub

'---------------------------------------------------------------------------------------------
Function DotNetVersionIsInstalled(strVersion)

   '-------------------
   ' Purpose:	Check if the specified .NET Framework version is installed
   ' Type:	Function
   ' Output:	Boolean returning True if the specified .NET Framework version is installed
   ' Input:	strVersion: Version of the .NET Framework (Type: string)
   '-------------------

   On Error Resume Next

   Dim bRegValue

   bRegValue = WshShell.RegRead("HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP\v" & strVersion & "\Install")
   If (Err.Number = 0) And (bRegValue = 1) Then
      DotNetVersionIsInstalled = True
   Else
      Err.Clear
      DotNetVersionIsInstalled = False
   End If

End Function

'--------------------------------------------------------------------------------------------------------------
Function WaitForProcessToTerminate(strProcessName, intMaxWaitTime)

   '-------------------
   ' Purpose:	Wait for a process to terminate for a maximum time
   ' Type:	Function
   ' Input:	strProcessName: Name of the process (Type: string)
   ' 		intMaxWaitTime: The maximum time in seconds to wait for termination of the process (Type: integer)
   ' Output:	Boolean returning True if the killing the process succeeded
   '-------------------

   On Error Resume Next

   Dim dStartTime

   dStartTime = Now
   Do While ProcessRunning(strProcessName)
      WScript.Sleep 5000
      If DateDiff( "s", dStartTime, Now) >= intMaxWaitTime Then
         Exit Do
      End If
   Loop

   If ProcessRunning(strProcessName) Then
      WaitForProcessToTerminate = False
   Else
      WaitForProcessToTerminate = True
   End If
   
End Function

'---------------------------------------------------------------------------------------------
Sub ExecuteUserInteraction(strFileName, intMaxRuntime)

   '-------------------
   ' Purpose:	Execute UserInteraction
   ' Type:	Sub
   ' Input:	strFileName: Name of the file to execute (Type: string)
   ' 		intMaxRuntime: The maximum time in seconds to run that will be passed to the strFileName (Type: integer)
   '-------------------

   On Error Resume Next

   Dim strFolderPath

   strFolderPath = WshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\INS\Scripting Toolbox\Path")
   If Err.Number = 0 Then
      If Right(strFolderPath, 1) = "\" Then
         strFolderPath = Left(strFolderPath, Len(strFolderPath) - 1)
      End If
      If fso.FolderExists(sCurrentfolder & "\UserInteraction") Then
         PackageLog "Processing UserInteraction..."
         fso.CopyFolder sCurrentfolder & "\UserInteraction", strFolderPath & "\UserInteraction", True
         WriteIniFile strFolderPath & "\UserInteraction.ini", "Main", "Execute", Chr(34) & strFolderPath & "\UserInteraction\" & strFileName & Chr(34) & " /MaxRuntime:" & intMaxRuntime
      Else
         Err.Raise 1065, "UserInteraction", "The folder '" & sCurrentfolder & "\UserInteraction' could not be found"
      End If
      RuntimeErrLog
   Else
      Err.Clear
      PackageLog "Executing UserInteraction..."
      WshShell.Run Chr(34) & sCurrentfolder & "\UserInteraction\" & strFileName & Chr(34) & " /MaxRuntime:" & intMaxRuntime, 1, False
      RuntimeErrLog
   End If
End Sub

'--------------------------------------------------------------------------------------------------------------
Sub TerminateProcessWithUserInteraction(strProcessName, strFileNameForUserInteraction, intMaxRuntime)

   '-------------------
   ' Purpose:	Terminate a Process with UserInteraction
   ' Type:	Sub
   ' Input:	strProcessName: Name of the process (Type: string)
   ' 		strFileNameForUserInteraction: Name of the file to execute (Type: string)
   ' 		intMaxRuntime: The maximum time in seconds to run that will be passed to the strFileNameForUserInteraction (Type: integer)
   '-------------------

   On Error Resume Next

   If ProcessRunning(strProcessName) Then
      PackageLog "The process is running. Waiting for termination..."
      Call ExecuteUserInteraction(strFileNameForUserInteraction, intMaxRuntime)
      If WaitForProcessToTerminate(strProcessName, intMaxRuntime + 30) Then
         PackageLog "The process was terminated."
      Else
         PackageLog "The process was not terminated. It will be killed now."
         Call KillProcess(strProcessName)
      End If
   End If
End Sub

'---------------------------------------------------------------------------------------------
Function SoftwareByDisplayNameIsInstalled(strDisplayName)

   '-------------------
   ' Purpose:	Returns if a software defined by name is installed
   ' Type:	Function
   ' Output:	Boolean returning True if the software is installed
   ' Input:	strDisplayName: Display Name of the software found in 'Add/Remove Programs' (Type: string)
   '-------------------

      On Error Resume Next

      bReturn = False
      sRegSubUnInstall = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
      objReg.EnumKey hexHKLM, sRegSubUnInstall, sRegUninstallKeys
      For i = 0 To UBound(sRegUninstallKeys)
         sFoundDisplayName = ""
         sFoundDisplayName = Trim(WshShell.RegRead(strHKLM & "\" & sRegSubUnInstall & "\" & sRegUninstallKeys(i) & "\DisplayName"))
         Select Case Err.Number
            Case 0
               ' OK, no error
            Case -2147024894
               ' Occures when the RegString 'DisplayName' does not exist
               Err.Clear
            Case Else
               ' An error occured
         End Select
         If sFoundDisplayName <> "" Then
            If UCase(sFoundDisplayName) = UCase(strDisplayName) Then
               bReturn = True
               Exit For
            End If
         End If
      Next

      SoftwareByDisplayNameIsInstalled = bReturn

End Function

'--------------------------------------------------------------------------------------------------------------
Function RetrievePattern(strString, strSearchPattern)

   '-------------------
   ' Purpose:	Retrieve a pattern in a string
   ' Type:	Function
   ' Output:	The string that is found according to the pattern
   ' Input:	strString: String in which to find the pattern (Type: string)
   ' 		strSearchPattern: Pattern to search for defined by a regular expression (Type: string)
   '-------------------

   On Error Resume Next

   Set regEx = New RegExp

   regEx.Pattern = strSearchPattern
   regEx.IgnoreCase = True
   regEx.Global = False

   Return = ""
   Set Matches = regEx.Execute(strString)
   For Each Match In Matches
      Return = Match.Value
   Next

   RetrievePattern = Return

End Function

'--------------------------------------------------------------------------------------------------------------
Sub SetXMLAttribute(strXMLFilePath, strNodePath, strAttribute, strAttributeValue)

   '-------------------
   ' Purpose:	Set an attribute in an XML File
   ' Type:	Sub
   ' Input:	strXMLFilePath: Name and path to the XML File (Type: string)
   ' 		strNodePath: XPath to the Node in the XML File (Type: string)
   ' 		strAttribute: Name of the attribute of the Node (Type: string)
   ' 		strAttributeValue: Value of the attribute of the Node (Type: string)
   '-------------------

   On Error Resume Next

   Set oXMLDoc = CreateObject("Microsoft.XMLDOM")
   oXMLDoc.async = False

   If oXMLDoc.Load(strXMLFilePath) Then
      Set Node = oXMLDoc.selectSingleNode(strNodePath)
      If Node Is Nothing Then
         ' Create the Node

         NodeElement = Right(strNodePath, Len(strNodePath)- InStrRev(strNodePath, "/"))
         strNodeParentPath = Left(strNodePath, InStrRev(strNodePath, "/") - 1)
         Set ParentNode = oXMLDoc.selectSingleNode(strNodeParentPath)

         NodeAttribute = RetrievePattern(NodeElement, "\[@.+='.+'\]")
         If NodeAttribute <> "" Then
            NodeName = Split(NodeElement, "[")(0)
            NodeAttributeName = Split(Split(NodeAttribute, "=")(0), "[@")(1)
            NodeAttributeValue = Split(NodeAttribute, "'")(1)

            Set Node = oXMLDoc.createNode(1, NodeName, "")
            Node.setAttribute NodeAttributeName, NodeAttributeValue
            ParentNode.appendChild Node
         Else
            Set Node = oXMLDoc.createNode(1, NodeElement, "")
            ParentNode.appendChild Node
         End If
      End If
      ' Set the Attribute
      Node.setAttribute strAttribute, strAttributeValue
      oXMLDoc.Save strXMLFilePath
      Set Node = Nothing
   Else
      Err.Raise 1027, "SetXMLAttribute", "Unable to load '" & strXMLFilePath & "'"
   End If

End Sub

'--------------------------------------------------------------------------------------------------------------
Function GetXMLValue(strXMLFilePath, strNodePath)

   '-------------------
   ' Purpose:	Get a value of a node of an XML File
   ' Type:	Function
   ' Output:	The string that is the node text
   ' Input:	strXMLFilePath: Name and path to the XML File (Type: string)
   ' 		strNodePath: XPath to the Node in the XML File (Type: string)
   '-------------------

   Set oXMLDoc = CreateObject("Microsoft.XMLDOM")
   oXMLDoc.async = False

   If oXMLDoc.Load(strXMLFilePath) Then
      Set Node = oXMLDoc.selectSingleNode(strNodePath)
      If Not Node Is Nothing Then
         GetXMLValue = Node.Text
      Else
         Err.Raise 1027, "GetXMLValue", "Unable to select the node '" & strNodePath & "'"
         GetXMLValue = ""
      End If
   Else
      Err.Raise 1027, "GetXMLValue", "Unable to load '" & strXMLFilePath & "'"
      GetXMLValue = ""
   End If

End Function

'--------------------------------------------------------------------------------------------------------------
Function GetApplicationArchitecture

   '-------------------
   ' Purpose:	Retrieve the Application Architecture
   ' Type:	Function
   ' Input:	None
   ' Output:	Returns a string containing the Application Architecture
   '			Possible values are:
   ' 				x86
   ' 				x64
   '-------------------

   On Error Resume Next

   If bApplicationNative64 Then
      GetApplicationArchitecture = x64
   Else
      GetApplicationArchitecture = x86
   End If

End Function     

Sub DetectPackageInstallLanguage

	Select case UCase(strLangArg)
		Case cstArabicSaudiArabiaLangCode
			sApplicationInstallLanguage = cstArabicSaudiArabia
		Case cstBulgarianLangCode
			sApplicationInstallLanguage = cstBulgarian
		Case cstChineseChinaLangCode
			sApplicationInstallLanguage = cstChineseChina
		Case cstChineseTaiwanLangCode
			sApplicationInstallLanguage = cstChineseTaiwan
		Case cstCroatianLangCode
			sApplicationInstallLanguage = cstCroatian
		Case cstDanishLangCode
			sApplicationInstallLanguage = cstDanish
		Case cstDutchBelgiumLangCode
			sApplicationInstallLanguage = cstDutchBelgium
		Case cstDutchNetherlandsLangCode
			sApplicationInstallLanguage = cstDutchNetherlands
		Case cstEnglishUSLangCode
			sApplicationInstallLanguage = cstEnglishUS
		Case cstEnglishGBLangCode
			sApplicationInstallLanguage = cstEnglishGB
		Case cstEstonianLangCode
			sApplicationInstallLanguage = cstEstonian
		Case cstFinnishLangCode
			sApplicationInstallLanguage = cstFinnish
		Case cstFrenchFranceLangCode
			sApplicationInstallLanguage = cstFrenchFrance
		Case cstGermanGermanyLangCode
			sApplicationInstallLanguage = cstGermanGermany
		Case cstGreekLangCode
			sApplicationInstallLanguage = cstGreek
		Case cstHebrewLangCode
			sApplicationInstallLanguage = cstHebrew
		Case cstHindiLangCode
			sApplicationInstallLanguage = cstHindi
		Case cstHungarianLangCode
			sApplicationInstallLanguage = cstHungarian
		Case cstItalianItalyLangCode
			sApplicationInstallLanguage = cstItalianItaly
		Case cstJapaneseLangCode
			sApplicationInstallLanguage = cstJapanese
		Case cstKazakhLangCode
			sApplicationInstallLanguage = cstKazakh
		Case cstKoreanLangCode
			sApplicationInstallLanguage = cstKorean
		Case cstNorwegianBokmalLangCode
			sApplicationInstallLanguage = cstNorwegianBokmal
		Case cstPolishLangCode
			sApplicationInstallLanguage = cstPolish
		Case cstPortuguesePortugalLangCode
			sApplicationInstallLanguage = cstPortuguesePortugal
		Case cstRomanianLangCode
			sApplicationInstallLanguage = cstRomanian
		Case cstRussianLangCode
			sApplicationInstallLanguage = cstRussian
		Case cstSerbianLatinLangCode
			sApplicationInstallLanguage = cstSerbianLatin
		Case cstSlovakLangCode
			sApplicationInstallLanguage = cstSlovak
		Case cstSlovenianLangCode
			sApplicationInstallLanguage = cstSlovenian
		Case cstSpanishSpainLangCode
			sApplicationInstallLanguage = cstSpanishSpain
		Case cstSwedishSwedenLangCode
			sApplicationInstallLanguage = cstSwedishSweden
		Case cstThaiLangCode
			sApplicationInstallLanguage = cstThai
		Case cstTurkishLangCode
			sApplicationInstallLanguage = cstTurkish
		Case cstUkranianLangCode
			sApplicationInstallLanguage = cstUkranian
		Case else
			sApplicationInstallLanguage = OSLanguage
	End Select

End Sub

'------------------------------------------------------------------------------------------------------
Function GetOfficeVersion
' Defines public variable sOfficeVersion
'------------------------------------------------------------------------------------------------------
Dim oRegistry 
Dim sKey 
Dim sAppExe 
Dim sValue 
Dim sMainOfficeVersion
Const HKEY_LOCAL_MACHINE = &H80000002   
sMainOfficeVersion = ""
Set oRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}//./root/default:StdRegProv") 
sKey = "Software\Microsoft\Windows\CurrentVersion\App Paths" 
sAppExe = "winword.exe" 
If OSArchitecture=OSx86 Then
		sKey = "Software\Microsoft\Windows\CurrentVersion\App Paths" 
	Else	
		strAddWow = "\Wow6432Node"
		sKey = "Software\Wow6432Node\Microsoft\Windows\CurrentVersion\App Paths" 
	End If
sKey = "Software\Microsoft\Windows\CurrentVersion\App Paths"
sAppExe = "winword.exe" 
oRegistry.GetStringValue HKEY_LOCAL_MACHINE, sKey & "\" & sAppExe, "", sValue 
If IsNull(sValue) Then
	GetOfficeVersion = False
Else
	GetOfficeVersion = True
	sMainOfficeVersion = fso.GetFileVersion(sValue)
	sOfficeVersion = Left(sMainOfficeVersion,2) & ".0"
End If


End Function

'------------------------------------------------------------------------------------------------------
Function GetEmrsnAdComputerLocation					
' Defines Public variables sAdDomain,sAdComputerLocation,sAdCorpDiv,sAdSub1,sAdSub2,sAdSub3
'------------------------------------------------------------------------------------------------------

	'Checking now where PC is in EMRSN AD
	' Constants required for name translate
	Const ADS_NAME_INITTYPE_GC = 3
	Const ADS_NAME_TYPE_NT4 = 3
	Const ADS_NAME_TYPE_1779 = 1

	Dim sPos 
	sAdCorpDiv=""
	sAdSub1=""
	sAdSub2=""
	sAdSub3=""
		
	'Get the NETBIOS name of the domain
	Dim objSystemInfo
	Err.Clear
	Set objSystemInfo = CreateObject("ADSystemInfo") 
	On Error Resume Next 
	sAdDomain = objSystemInfo.DomainShortName
	sErrMsg=Err.Description
	sErrNbr=Err.Number
	If Err.Number=0 Then
		EmersonLog "NETBIOS Domain: " & sAdDomain
		Dim objTrans
		Set objTrans = CreateObject("NameTranslate")
		' Initialize name translate using global catalog
		objTrans.Init ADS_NAME_INITTYPE_GC, ""
		' Input computer name (NT Format)
		objTrans.Set ADS_NAME_TYPE_NT4, sAdDomain & "\" & sComputerName & "$"
		sErrMsg=Err.Description
		sErrNbr=Err.Number
		If Err.Number=0 Then
			' Get Distinguished Name.
			sAdComputerLocation = objTrans.Get(ADS_NAME_TYPE_1779)
			sErrMsg=Err.Description
			sErrNbr=Err.Number
			If Err.Number=0 Then
				EmersonLog "Connected to domain, to get the computer object location"
			Else
				Err.Clear
				EmersonLog "Could not get computer location from the domain: " & sErrMsg
				EmersonLog "Retrieving computer object location from registry"
				sAdComputerLocation	= WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Distinguished-Name")
			End If
			EmersonLog "AD Location is: " & sAdComputerLocation
		Else
			Err.Clear
			EmersonLog "Could not get computer location from the domain: " & sErrMsg
			EmersonLog "Retrieving computer object location from registry"
			sAdComputerLocation	= WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Distinguished-Name")
		End If
		
		'Registry tree: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Distinguished-Name = 
		'result like: "CN=BEBRU-1KFE65,OU=Laptops,OU=Resources,OU=BE-Brussels,OU=Southern,OU=EMA,OU=PROCESS,DC=emrsn,DC=org"
		
	Else
		Err.Clear
		EmersonLog "Could not get domain name: " & sErrMsg
		EmersonLog "Retrieving computer object location from registry"
		sAdDomain="EMRSN"
		sAdComputerLocation	= WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Distinguished-Name")
	End If

	'Check if PC is in emrsn domain 
	if right(sAdComputerLocation, 16)=",DC=emrsn,DC=org" then	
		Dim sTempLoc
		sTempLoc = sAdComputerLocation
		'Get rid of last part ",DC=emrsn,DC=org"
		sTempLoc = left(sTempLoc, len(sTempLoc)-16)
			
		'look for last OU specification indicating corporate division
		'look for last comma in remaining string
		sPos=InstrRev(sTempLoc,",")
		'Take all after last comma
		sAdCorpDiv=right(sTempLoc,len(sTempLoc)-sPos-3)
		EmersonLog "Corporate Division is = " & sAdCorpDiv
		'Take all before last comma
		sTempLoc = left(sTempLoc,sPos-1)

		'look for last comma in remaining string
		sPos=InstrRev(sTempLoc,",")
		'Take all after last comma
		sAdSub1=right(sTempLoc,len(sTempLoc)-sPos-3)
		EmersonLog "AdSub1 is = " & sAdSub1
		'Take all before last comma
		sTempLoc = left(sTempLoc,sPos-1)

		'look for last comma in remaining string
		sPos=InstrRev(sTempLoc,",")
		'Take all after last comma
		sAdSub2=right(sTempLoc,len(sTempLoc)-sPos-3)
		EmersonLog "AdSub2 is = " & sAdSub2
		'Take all before last comma
		sTempLoc = left(sTempLoc,sPos-1)
			
		'look for last comma in remaining string
		sPos=InstrRev(sTempLoc,",")
		'Take all after last comma
		sAdSub3=right(sTempLoc,len(sTempLoc)-sPos-3)
		EmersonLog "AdSub3 is = " & sAdSub3
		'Take all before last comma
		sTempLoc = left(sTempLoc,sPos-1)
		
		GetEmrsnAdComputerLocation=True
	Else
		GetEmrsnAdComputerLocation=False
	End If

End Function

'------------------------------------------------------------------------------------------------------
Sub EnvironmentVariableSet(sVarName,sVarValue) ' Defines a User Environment Variable
'------------------------------------------------------------------------------------------------------
   On Error Resume Next

   Set objWMIService  = GetObject("winmgmts:\\.\root\cimv2")
   Set objVariable = objWMIService.Get("Win32_Environment").SpawnInstance_

   objVariable.Name = sVarName
   'UserName. This is the owner of the environment variable. 
   'To make this a system variable, set UserName to System; 
   'to make it a user-specific environment variable, set UserName to the user account name 
   '(for example, fabrikam\kenmyer).
   objVariable.UserName = WshShell.ExpandEnvironmentStrings("%USERDOMAIN%") & "\" & WshShell.ExpandEnvironmentStrings("%USERNAME%")
   objVariable.VariableValue = sVarValue
   objVariable.Put_

End Sub

'------------------------------------------------------------------------------------------------------
Sub EnvironmentVariableDelete(sVarName) ' Deletes an Environment Variable
'------------------------------------------------------------------------------------------------------
   On Error Resume Next

   Set objWMIService  = GetObject("winmgmts:\\.\root\cimv2")
   Set objVariable = objWMIService.Get("Win32_Environment").SpawnInstance_

	Set colItems = objWMIService.ExecQuery _
		("Select * from Win32_Environment Where Name = '" & sVarName & "'")

	For Each objItem in colItems
		objItem.Delete_
	Next

End Sub

'-------------------------------------------------------------------------------------------------------
Function ReplaceDotAndSpace(sStr)
'-------------------------------------------------------------------------------------------------------
	tmp = sStr
	tmp = Replace(tmp," ","_")
	tmp = Replace(tmp,".","_")	

	ReplaceDotAndSpace = tmp
End Function

'-------------------------------------------------------------------------------------------------------
Sub EmersonAdjustCU 'Prepare user component
'-------------------------------------------------------------------------------------------------------
   On Error Resume Next
   If sJobID = cstInstallJob Or sJobID = cstReinstallJob Then
      If fso.FolderExists(sCurrentfolder & "\CU") Then
         If Not sAdjustCUFolder = "" Then
            Err.Clear
            
            If Not fso.FolderExists (sAdjustCUFolder) Then 
               MainLog "Create folder " & sAdjustCUFolder
               MakeFolder sAdjustCUFolder
			   If OSType = OSNT4 Or OSType = OSW2K Or OSType = OSW2K3 Or OSType = OSXP Then
					SetSecurity ReplaceSecurity, sAdjustCUFolder, WindowsGroup(cstAdministrators) & ":F System:F " & WindowsGroup(cstEveryone) & ":R"
				Else
					SetISecurity ReplaceSecurity, sAdjustCUFolder, WindowsGroup(cstAdministrators) & ":(OI)(CI)F System:(OI)(CI)F " & WindowsGroup(cstEveryone) & ":(OI)(CI)R"
				End If
            End If
            
            If fso.FolderExists(sCurrentFolder & "\CU\Once") Then
               sTargetOnceDir = ReplaceDotAndSpace(sAdjustCUFolder & "\CU\Once\" & sPackageName)
               fso.DeleteFolder sTargetOnceDir & ".*", True  	
               sTargetOnceDir = sTargetOnceDir & "." & ReplaceDotAndSpace(sPackageVersion)
               MakeFolder sTargetOnceDir
               fso.CopyFolder sCurrentFolder & "\CU\Once", sTargetOnceDir, True
               fso.copyFile sCurrentFolder & "\Package.dat", sTargetOnceDir & "\",True
            End If
            
            If fso.FolderExists(sCurrentFolder & "\CU\Always") Then
               sTargetAlwaysDir = ReplaceDotAndSpace(sAdjustCUFolder & "\CU\Always\" & sPackageName)
               fso.DeleteFolder sTargetAlwaysDir & ".*", True
               sTargetAlwaysDir = sTargetAlwaysDir & "." & ReplaceDotAndSpace(sPackageVersion)
               MakeFolder sTargetAlwaysDir
               fso.CopyFolder sCurrentFolder & "\CU\Always", sTargetAlwaysDir, True
               fso.copyFile sCurrentFolder & "\Package.dat", sTargetAlwaysDir & "\",True
            End If

            PackageLog "User component folders copied to " & sAdjustCUFolder
            Err.clear
         Else
            MainErrLog "AdjustCUFolder parameter not defined in RAT!"
         End If
      End If
      Err.Clear

   Elseif sJobID = cstUninstallJob Then

      PackageLog "Delete user component folders"
      sTargetOnceDir = ReplaceDotAndSpace(sAdjustCUFolder & "\CU\Once\" & sPackageName) & "." & ReplaceDotAndSpace(sPackageVersion)
      sTargetAlwaysDir = ReplaceDotAndSpace(sAdjustCUFolder & "\CU\Always\" & sPackageName) & "." & ReplaceDotAndSpace(sPackageVersion)
      fso.DeleteFolder sTargetOnceDir , True
      fso.DeleteFolder sTargetAlwaysDir , True
      Err.clear

   End If
End Sub


'-------------------------------------------------------------------------------------------------------
Sub EmersonLog(message) 'Write messages to log and to the Ivanti task which started the package
'-------------------------------------------------------------------------------------------------------
  tmpErr = Err
  
  On Error Resume Next
  Dim iRC
  PackageLog message  
  
  Dim sTaskId
  sTaskId =  WshShell.ExpandEnvironmentStrings("%task_id%")
  If Len(sTaskId)>0 Then
	iRC = WshShell.Run(Chr(34) & "%LDMS_LOCAL_DIR%\..\sendtaskstatus.exe" & Chr(34) &" -Core=" & sIvantiEpmCoreNameUsedByAgent & " -taskId=" & sTaskId & " -message=" & Chr(34) & message & Chr(34),1,True)
  End If

  Err = tmpErr
End Sub

'-------------------------------------------------------------------------------------------------------
Sub EmersonUserLog(message) 'Write messages to log, use it in a CU script
'-------------------------------------------------------------------------------------------------------
  On Error Resume Next
  Set fileLog = fso.OpenTextFile(sPackageLogFile, 8, True)
  If IsNull(message) Then
    fileLog.WriteLine ""
  Else
    fileLog.WriteLine Now & " : " & vbTab & message
  End If
  fileLog.Close
End Sub


'------------------------------------------------------------------------------------------------------
Function AsciiToHex(sData) 'To convert an ascii string in its hexadecimal representation
'------------------------------------------------------------------------------------------------------
	' Turns ASCII string sData into array of hex numerics
 	Dim aTmp
 	For i = 1 To Len(sData)
   		aTmp = aTmp & Hex(Asc(Mid(sData, i)))
 	Next
 	ASCIItoHex = aTmp
End Function

'--------------------------------------------------------------------------------------------
'	Add PackageName and PackageVersion to specific Emerson LANDesk Registry Key
Sub AddPackagingFrameworkInfoToRegistry(sBaselineName, sPackageName, sPackageVersion)
'--------------------------------------------------------------------------------------------
	On Error Resume Next

	'Get rid of the entries made by previous version of the framework - START
	'EmersonLog "Delete Landesk registry key HKLM\Software\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName
	WshShell.RegWrite "HKLM\Software\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName, sPackageName
	WshShell.RegDelete "HKLM\Software\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName

	If OSArchitecture=OSx86 Then
		'ok, done
	Else	
		'EmersonLog "Delete Landesk registry key HKLM\Software" & strAddWow & "\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName
		WshShell.RegWrite "HKLM\Software" & strAddWow & "\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName, sPackageName
		WshShell.RegDelete "HKLM\Software" & strAddWow & "\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName
	End If
	'Get rid of the entries made by previous version of the framework - END
	
	EmersonLog "Writing Packaging Framework information"
	sRegKey = "HKLM\SYSTEM\Emerson\Packaging Framework\" & sBaselineName & "\Install Date"
	sRegValue = Year(Now) & "-" & Right("00" & Month(Now), 2) & "-" & Right("00" & Day(Now), 2) 
	'EmersonLog "Create a new String Value Registry Key " & sRegKey & " with value: " & sRegValue
	WshShell.RegWrite sRegKey, sRegValue, "REG_SZ"

	sRegKey = "HKLM\SYSTEM\Emerson\Packaging Framework\" & sBaselineName & "\Install Return Value"
	sRegValue = iPackageExitCode
	'EmersonLog "Create a new String Value Registry Key " & sRegKey & " with value: " & sRegValue
	WshShell.RegWrite sRegKey, sRegValue, "REG_SZ"

	sRegKey = "HKLM\SYSTEM\Emerson\Packaging Framework\" & sBaselineName & "\Application Version"
	sRegValue = sApplicationVersion
	'EmersonLog "Create a new String Value Registry Key " & sRegKey & " with value: " & sRegValue
	WshShell.RegWrite sRegKey, sRegValue, "REG_SZ"

	sRegKey = "HKLM\SYSTEM\Emerson\Packaging Framework\" & sBaselineName & "\Package Name"
	sRegValue = sPackageName
	'EmersonLog "Create a new String Value Registry Key " & sRegKey & " with value: " & sRegValue
	WshShell.RegWrite sRegKey, sRegValue, "REG_SZ"

	sRegKey = "HKLM\SYSTEM\Emerson\Packaging Framework\" & sBaselineName & "\Package Version"
	sRegValue = sPackageVersion
	'EmersonLog "Create a new String Value Registry Key " & sRegKey & " with value: " & sRegValue
	WshShell.RegWrite sRegKey, sRegValue, "REG_SZ"

End Sub

'--------------------------------------------------------------------------------------------
'	Add PackageName and PackageVersion to specific Emerson LANDesk Registry Key
Sub deletePackagingFrameworkInfoFromRegistry(sBaselineName, sPackageName)
'--------------------------------------------------------------------------------------------
	On Error Resume Next
	'Get rid of the entries made by previous version of the framework - START
	'EmersonLog "Delete Landesk registry key HKLM\Software\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName
	WshShell.RegWrite "HKLM\Software\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName, sPackageName
	WshShell.RegDelete "HKLM\Software\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName

	If OSArchitecture=OSx86 Then
		'ok, done
	Else	
		'EmersonLog "Delete Landesk registry key HKLM\Software" & strAddWow & "\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName
		WshShell.RegWrite "HKLM\Software" & strAddWow & "\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName, sPackageName
		WshShell.RegDelete "HKLM\Software" & strAddWow & "\Intel\LANDesk\Inventory\Custom Fields\" & sPackageName
	End If
	'Get rid of the entries made by previous version of the framework - END

	WshShell.RegWrite "HKLM\SYSTEM\Emerson\Packaging Framework\" & sBaselineName & "\Package Name", sPackageName
	WshShell.RegDelete "HKLM\SYSTEM\Emerson\Packaging Framework\" & sBaselineName

End Sub

'-------------------------------------------------------------------------------------------------------
' Functions to retrieve user variables in registry, which are written by the AdjustCU script
'-------------------------------------------------------------------------------------------------------
Function getUserDontExpirePassword
	On Error Resume Next
	getUserDontExpirePassword = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\DontExpirePassword")
End Function

Function getUserFirstName
	On Error Resume Next
	getUserFirstName = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\FirstName")
End Function

Function getUserLastName
	On Error Resume Next
	getUserLastName = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\LastName")
End Function

Function getUserFullName 
	On Error Resume Next
	getUserFullName = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\FullName")
End Function

Function getUserInitials 
	On Error Resume Next
	getUserInitials = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\Initials")
End Function

Function getUserDisplayName 
	On Error Resume Next
	getUserDisplayName = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\DisplayName")
End Function

Function getUserTitle 
	On Error Resume Next
	getUserTitle = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\Title")
End Function

Function getUserAddress
	On Error Resume Next
 	getUserAddress = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\StreetAddress")
End Function

Function getUserPostalCode
	On Error Resume Next
 	getUserPostalCode = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\PostalCode")
End Function

Function getUserCity
	On Error Resume Next
 	getUserCity = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\City")
End Function

Function getUserStateProvince
	On Error Resume Next
 	getUserStateProvince = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\StateProvince")
End Function

Function getUserCountry
	On Error Resume Next
 	getUserCountry = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\Country")
End Function

Function getUserCountryISO
	On Error Resume Next
 	getUserCountryISO = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\CountryISO")
End Function

Function getUserEmailAddress
	On Error Resume Next
	getUserEmailAddress = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\EmailAddress")
End Function

Function getUserTelephoneNumber
	On Error Resume Next
	getUserTelephoneNumber = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\TelephoneNumber")
End Function

Function getUserTelephoneMobile
	On Error Resume Next
	getUserTelephoneMobile = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\TelephoneMobile")
End Function

Function getUserSecondaryTelephoneNumber
	On Error Resume Next
	getUserSecondaryTelephoneNumber = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\SecondaryTelephoneNumber")
End Function

Function getUserHomePhone
	On Error Resume Next
	getUserHomePhone = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\HomePhone")
End Function

Function getUserDepartment
	On Error Resume Next
	getUserDepartment = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\Department")
End Function

Function getUserDivision
	On Error Resume Next
	getUserDivision = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\Division")
End Function

Function getUserManager
	On Error Resume Next
	getUserManager = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\Manager")
End Function

Function getUserCompany
	On Error Resume Next
	getUserCompany = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\Company")
End Function

Function getUserWWWHomePage
	On Error Resume Next
	getUserWWWHomePage = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\wWWHomePage")
End Function

Function getUserScriptPath
	On Error Resume Next
	getUserScriptPath = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\ScriptPath")
End Function

Function getUserCanonicalName
	On Error Resume Next
	getUserCanonicalName = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\CanonicalName")
End Function

Function getUserDistinguishedName
	On Error Resume Next
	getUserDistinguishedName = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\DistinguishedName")
End Function

Function getUserFaxNumber
	On Error Resume Next
	getUserFaxNumber = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\Fax")
End Function

Function getUserHomeDirectory
	On Error Resume Next
	getUserHomeDirectory = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\HomeDirectory")
End Function

Function getUserHomeMDB
	On Error Resume Next
	getUserHomeMDB = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\HomeMDB")
End Function

Function getUserHomeMTA
	On Error Resume Next
	getUserHomeMTA = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\HomeMTA")
End Function

Function getUseripPhone
	On Error Resume Next
	getUseripPhone = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\ipPhone")
End Function

Function getUserLegacyExchangeDN
	On Error Resume Next
	getUserLegacyExchangeDN = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\LegacyExchangeDN")
End Function

Function getUserMailNickName
	On Error Resume Next
	getUserMailNickName = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\MailNickName")
End Function

Function getUsermsExchangeHomeServerName
	On Error Resume Next
	getUsermsExchangeHomeServerName = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\msExchangeHomeServerName")
End Function

Function getUserPhysicalDeliveryOfficeName
	On Error Resume Next
	getUserPhysicalDeliveryOfficeName = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\PhysicalDeliveryOfficeName")
End Function

Function getUsertextEncodedORAddress
	On Error Resume Next
	getUsertextEncodedORAddress = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\textEncodedORAddress")
End Function

Function getUserLastChangeDate
	On Error Resume Next
	getUserLastChangeDate = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\LastChangeDate")
End Function

Function getUserPasswordLastChanged
	On Error Resume Next
	getUserPasswordLastChanged = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\PasswordLastChanged")
End Function

Function getUserExtensionAttribute(nr)
	On Error Resume Next
	getUserExtensionAttribute = WshShell.regRead("HKCU\Software\INS\AdjustCU\UserVars\extensionAttribute" & nr)
End Function

'-------------------------------------------------------------------------------------------------------
' Functions to retrieve user variables in registry, which are written by the AdjustCU script
'-------------------------------------------------------------------------------------------------------


'-------------------------------------------------------------------------------------------------------
Sub EmersonLandeskReboot(nextJob)
'-------------------------------------------------------------------------------------------------------
	On Error Resume Next
	If Not NextJob="" Then
		EmersonLog "EmersonLandeskReboot NextJob = " & nextJob
		EmersonLog "EmersonLandeskReboot Rebooting"
		
		RC1 = WshShell.Run(Chr(34) & sProgramFiles & "\Landesk\LDclient\sdclient.exe" & Chr(34) &" /onreboot /bat /p=" & Chr(34) & sCurrentFolder & "\INS\install.bat" & Chr(34) & " /cmds=" & nextJob ,1,True)
		RC2 = WshShell.Run(Chr(34) & sProgramFiles & "\Landesk\LDclient\sdclient.exe" & Chr(34) &" /reboot",1,True)

		If RC1 <> 0 Or RC2 <> 0 Then
			EmersonLog "Landesk returned an error, while trying to reboot: " & RC1 & " " & RC2 
			Err.Raise 2555
			MsgBox Err
		End If
	Else
		EmersonLog("Empty nextJob in EmersonLandeskReboot")
		Err.Raise 2555
		MsgBox Err
	End If
End Sub

'-------------------------------------------------------------------------------------------------------
Sub setAddRemovePrograms(name)
'-------------------------------------------------------------------------------------------------------
   PackageLog "Setting Add/Remove Programs (" & name & ")"
   If OSArchitecture = ApplicationArchitecture Then
      WshShell.regWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"& name & "\NoModify" ,"1", "REG_DWORD"
      WshShell.regWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"& name & "\NoRemove" ,"1", "REG_DWORD"
   Else
      WshShell.regWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"& name & "\NoModify" ,"1", "REG_DWORD"
      WshShell.regWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"& name & "\NoRemove" ,"1", "REG_DWORD"
   End If
End Sub

'-------------------------------------------------------------------------------------------------------
Sub deleteAddRemovePrograms(name)
'-------------------------------------------------------------------------------------------------------
   PackageLog "Deleting Add/Remove Programs (" & name & ")"
   WshShell.regWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & name & "\DisplayName",name
   WshShell.regDelete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & name & "\"

   Select Case OSArchitecture
      Case OSx86
         ' OK
      Case OSx64
         WshShell.regWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" & name & "\DisplayName",name
         WshShell.regDelete "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" & name & "\"
   End Select

End Sub

'-------------------------------------------------------------------------------------------------------
Sub ProcessARP
'-------------------------------------------------------------------------------------------------------
   If Not bErrorOccured Then
      Select Case sJobID
         Case cstInstallJob
            If fso.FolderExists(sCurrentfolder & "\CU") Then
               If sMSIProductCode <> "" Then
                  PackageLog "Processing Add/Remove Programs (for MSIProductCode)"
                  setAddRemovePrograms sMSIProductCode
               Else
                  PackageLog "Processing Add/Remove Programs (for ApplicationName)"
                  setAddRemovePrograms sApplicationName
               End If
            Else
               PackageLog "Nothing to process for Add/Remove Programs (No CU)"
            End If
         Case cstUninstallJob
            If sMSIProductCode <> "" Then
               PackageLog "Processing Add/Remove Programs (for MSIProductCode)"
               deleteAddRemovePrograms sMSIProductCode
            Else
               PackageLog "Processing Add/Remove Programs (for ApplicationName)"
               deleteAddRemovePrograms sApplicationName
            End If
      End Select
   Else
      PackageLog "Not processing Add/Remove Programs (An error already occured)."
   End If
End Sub

'-------------------------------------------------------------------------------------------------------
Sub ProcessLandeskRegistryKey
'-------------------------------------------------------------------------------------------------------
   Select Case sJobID
      Case cstInstallJob
         AddPackagingFrameworkInfoToRegistry sPackageName, sPackageVersion
      Case cstUninstallJob
         deletePackagingFrameworkInfoFromRegistry sPackageName
   End Select
End Sub


'-------------------------------------------------------------------------------------------------------
Function FixedLenghtNbr(nbrToConvert,NbrOfCharacters)
'-------------------------------------------------------------------------------------------------------
	'Purpose: Convert number to string, use specified number of characters, fill with leading 0 if number is actually having less characters
	'Parameters: 
	'nbrToConvert, e.g. 6
	'NbrOfCharacters, e.g. 2
	'Returns: "06"
	strNbr = Cstr(nbrToConvert)
	If Len(strNbr)>NbrOfCharacters Then 
		EmersonLog "Error in function, cannot fit " & nbrToConvert & " into " & NbrOfCharacters & " characters"
		strNbr = nbrToConvert
	Else
		Do while Len(strNbr)<NbrOfCharacters
			strNbr = "0" & strNbr
		Loop
	End If
	FixedLenghtNbr = strNbr
End Function

'-------------------------------------------------------------------------------------------------------
Function DecimalToBinary(intDecimal)
'-------------------------------------------------------------------------------------------------------
	Dim tmp
	Dim n

	n = intDecimal

	tmp = Trim(CStr(n Mod 2))
	n = n \ 2

	Do While n <> 0
	tmp = Trim(CStr(n Mod 2)) & tmp
	n = n \ 2
	Loop

	DecimalToBinary = tmp
  
End Function

Sub SendEmailSmtpText(strEmailFrom, strEmailTo, strEmailCc, strEmailSubject, strFileContainingMessageBody, strFileAttachment)

	'Example of use
	'SendEmailSmtpText "Cads@Emerson.com", "ITLandeskSupportEPM.EMA@Emerson.com", "", "Problem - on " & sComputer, "", ""
	
	On Error Resume Next
	Dim strSMTPEmailServerAddress, strMessageBody

	strSMTPEmailServerAddress = "inetmail.emrsn.net"
	
	EmersonLog "Sending e-mail Subject: " & strEmailSubject
	EmersonLog "From: " & strEmailFrom
	EmersonLog "To: " & strEmailTo
	EmersonLog "Cc: " & strEmailCc
	EmersonLog "text file containing message body: " & strFileContainingMessageBody
	EmersonLog "Having attached file: " & strFileAttachment
	Err.Clear
	Dim objMessage
	Set objMessage = CreateObject("CDO.Message")
	objMessage.Subject = strEmailSubject
	objMessage.From = strEmailFrom
	objMessage.To = strEmailTo
	If Len(strEmailCc)>0 Then
		objMessage.CC = strEmailCc
	End If
	
	If strFileContainingMessageBody="" Then
		strMessageBody = ""
	Else
		Dim objLog	
		Set objLog = fso.OpenTextFile(strFileContainingMessageBody, 1)
		strMessageBody = objLog.ReadAll
		objLog.Close
	End If

	'EmersonLog "E-mail body contains: " 
	'EmersonLog strMessageBody 
	
	objMessage.TextBody = strEmailSubject & vbCrLf & vbCrLf & strMessageBody
	
	If fso.FileExists(strFileAttachment) Then
		objMessage.AddAttachment strFileAttachment
	End If
	
	'This section provides the configuration information for the remote SMTP server.
	'Normally you will only change the server name or IP.
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 
	
	'Name or IP of Remote SMTP Server
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSMTPEmailServerAddress
	
	'Server port (typically 25)
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 	        
				
	'<Type of authentication, NONE, Basic (Base64 encoded), NTLM>
	'objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = NONE
	
	'Use SSL for the connection (False or True)
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False
	 
	'Connection Timeout in seconds (the maximum time CDO will try to establish a connection to the SMTP server)
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60
 
	'==End remote SMTP server configuration section==	        
	objMessage.Configuration.Fields.Update
	objMessage.Send
	sErrNbr = Err.Number
	sErrMsg = Err.Description
	Err.Clear
	If sErrNbr=0 Then
		EmersonLog "Mail was sent ok"
	Else
		EmersonLog "Error sending e-mail: " & sErrMsg
	End If
	
End Sub

Sub SendEmailSmtpHtml(strEmailFrom, strEmailTo, strEmailCc, strEmailSubject, strHtmlBody, strFileAttachment)

	'Example of use
	'strHtmlBody should be a string like
	'strHtmlMessage = "<HTML>"
	'strHtmlMessage = strHtmlMessage & "<HEAD>"
	'strHtmlMessage = strHtmlMessage & "<BODY>"
	'strHtmlMessage = strHtmlMessage & "<p><b>Hello</b></p>"
	'strHtmlMessage = strHtmlMessage & "<p>This is a test</p>"
	'strHtmlMessage = strHtmlMessage & "</BODY>"
	'strHtmlMessage = strHtmlMessage & "</HTML>"
	'SendEmailSmtpHtml "Cads@Emerson.com", "ITLandeskSupportEPM.EMA@Emerson.com", "", "Problem - on " & sComputer, strHtmlMessage, ""
	
	On Error Resume Next
	Dim strSMTPEmailServerAddress, strMessageBody

	strSMTPEmailServerAddress = "inetmail.emrsn.net"
	
	EmersonLog "Sending e-mail Subject: " & strEmailSubject
	EmersonLog "From: " & strEmailFrom
	EmersonLog "To: " & strEmailTo
	EmersonLog "Cc: " & strEmailCc
	EmersonLog "Body text: " 
	EmersonLog strHtmlBody
	EmersonLog "Having attached file: " & strFileAttachment
	Err.Clear
	Dim objMessage
	Set objMessage = CreateObject("CDO.Message")
	objMessage.Subject = strEmailSubject
	objMessage.From = strEmailFrom
	objMessage.To = strEmailTo
	If Len(strEmailCc)>0 Then
		objMessage.CC = strEmailCc
	End If

	'EmersonLog "E-mail body contains: " 
	'EmersonLog strMessageBody 
	
	objMessage.HTMLBody = strHtmlBody
	
	If fso.FileExists(strFileAttachment) Then
		objMessage.AddAttachment strFileAttachment
	End If
	
	'This section provides the configuration information for the remote SMTP server.
	'Normally you will only change the server name or IP.
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 
	
	'Name or IP of Remote SMTP Server
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSMTPEmailServerAddress
	
	'Server port (typically 25)
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 	        
				
	'<Type of authentication, NONE, Basic (Base64 encoded), NTLM>
	'objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = NONE
	
	'Use SSL for the connection (False or True)
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False
	 
	'Connection Timeout in seconds (the maximum time CDO will try to establish a connection to the SMTP server)
	objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60
 
	'==End remote SMTP server configuration section==	        
	objMessage.Configuration.Fields.Update
	objMessage.Send
	sErrNbr = Err.Number
	sErrMsg = Err.Description
	Err.Clear
	If sErrNbr=0 Then
		EmersonLog "Mail was sent ok"
	Else
		EmersonLog "Error sending e-mail: " & sErrMsg
	End If
	
End Sub

Sub ZipCreateNew(sZipFile)

	Dim oZipFile
	EmersonLog "Creating new zip file: " & sZipFile
    If fso.FileExists(sZipFile) Then 
		fso.DeleteFile sZipFile, True
	End If
	
	'Variables for function oFso.OpenTextFile(filename[, iomode[, create[, format]]])
	'iomode
	ForReading =  1 			' Open a file for reading only. You can't write to this file.
	ForWriting =  2 			' Open a file for writing.
	ForAppending =  8 			' Open a file and write to the end of the file.
	'format
	TristateUseDefault =  -2 	' Opens the file using the system default.
	TristateTrue = -1			' Opens the file as Unicode.
	TristateFalse =  0 			' Opens the file as ASCII.
	
	Set oZipFile = fso.OpenTextFile(sZipFile, ForAppending, True, TristateFalse)
	oZipFile.WriteLine Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0)
	oZipFile.Close
	
End Sub

Sub ZipAddFile(sZipFile, sFileToAdd)
	Set winShell = createObject("shell.application")
	
	'Add Source File to zip file that is already created with subprocedure ZipCreateNew
	EmersonLog "Adding " & sFileToAdd & " to the zip file " & sZipFile
	winShell.namespace(sZipFile).CopyHere sFileToAdd
	WScript.Sleep 3000
	
End Sub

Sub CleanAdjustCU(sFrequency,sSoftwareToClean)

	'sFrequency 	  = "Always" or "Once"
	'sSoftwareToClean = software name that we want to delete from AdjustCU
	Dim sStartFolder, oStartFolder, oSubFolders, sSubFolder, strKeyPath, strSubkey
	sStartFolder = "C:\Windows\INS\AdjustCU\CU\" & sFrequency
	EmersonLog "Checking in " & sStartFolder
	Set oStartFolder = fso.GetFolder(sStartFolder)
	Set oSubFolders = oStartFolder.SubFolders 
	For Each sSubFolder In oSubFolders
		EmersonLog "Checking " & sSubFolder
		If InStr(sSubFolder,sSoftwareToClean)>0 Then
			EmersonLog "Deleting old AdjustCU Folder: " & sSubFolder
			fso.DeleteFolder sSubFolder, True
 		End If 
	Next
	
	'The next cleanup in HKCU is only effective for the user profile doing the installation
	strKeyPath = "Software\INS\AdjustCU\" & sFrequency
	Dim oRegistry,arrSubkeys
	Set oRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
	oRegistry.EnumKey hexHKCU, strKeyPath, arrSubkeys
    For Each strSubkey In arrSubkeys
		If InStr (strSubkey,sSoftwareToClean) Then
			EmersonLog "Deleting old registries from AdjustCU: " & strKeyPath & strSubkey
			oRegistry.DeleteKey hexHKCU, strKeyPath & "\" & strSubkey
		End If
    Next

End Sub 

Function GetMsi(sSoftware)
	
	Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
	Set colItems = objWMIService.ExecQuery("Select * from Win32_Product",,48)
	Set objShell = WScript.CreateObject( "WScript.Shell" )

	Dim objItem 'as Win32_Product
	Dim sMsiCode
	
	sMsiCode = ""
	For Each objItem in colItems
	 If InStr(objItem.Description,sSoftware) Then
		EmersonLog "Description: " & objItem.Description
		EmersonLog "IdentifyingNumber: " & objItem.IdentifyingNumber
		EmersonLog "Language: " & objItem.Language
		EmersonLog "Name: " & objItem.Name
		EmersonLog "Version: " & objItem.Version
		sMsiCode =  Cstr(objItem.IdentifyingNumber)
		If objItem.Language <> 0 then
			Exit For
		End If 
	End If 
	Next
	GetMsi =  sMsiCode

End Function 

Sub RemoveApplication(sAppName, sAppMsiCode)
	Installed = MSIInstalled(sAppMsiCode)
	
	If Installed Then
		RC = WshShell.Run("msiexec /X" & sAppMsiCode & " REBOOT=ReallySuppress /qn /l*+ " & Chr(34) & sSetupLogFile & Chr(34),1,True)
		Select Case RC
		Case 0
				EmersonLog "Uninstallation " & sAppName & " Finished succesfully RC=" & RC
		Case 3010
				EmersonLog "Uninstallation " & sAppName & " Finished succesfully, but it requires a reboot, RC=" & RC
		Case Else
				Err.Raise RC, sAppName, "Error running setup, RC = " & RC
		End Select
		RuntimeErrLog
		
		EmersonLog sAppName & " Uninstall ended, RC = " & RC
	Else
		EmersonLog sAppName & " not found."
	End If

End Sub

Sub SendInstallStatusEmail(iReturnValue,sToOnFail,sToOnSuccess,arrFileList)

	'Example of use
	'Call SendInstallStatusEmail(RC, sPackageAuthor, "", Array(sWindir & "\INS\Logs\_MainLog.Log",sSetupLogFile))
	'Result of this example: 
	'	if RC=0 or 3010 ... sends a mail to sToOnSuccess (if specified)
	'	If RC<>0 and <>3010 sends a mail to sToOnFail (if specified)
	'	body text of mail is the contents of sPackageLogFile
	'	mail will contain a zip file in attachment containing all files specified in the array
	
	Dim sZipFile, sFile, sFrom, sSubject
	
	If (iReturnValue=0 Or iReturnValue=3010) And Len(sToOnSuccess)=0 Then
		'Nothing to send
	ElseIf Len(sToOnFail)=0 Then
		'Nothing to send
	Else
		sZipFile = sPackageName & " " & sPackageVersion
		sZipFile = Replace(sZipFile," ", "_") 
		sZipFile = WshShell.ExpandEnvironmentStrings("%temp%") & "\" & sZipFile & ".zip"
		ZipCreateNew sZipFile

		For each sFile in arrFileList
			ZipAddFile sZipFile, sFile
		Next
		
		sFrom = sPackageName & " " & sPackageVersion
		sFrom = Replace(sFrom," ", "_") & "@Emerson.com"
		If iReturnValue=0 Or iReturnValue=3010 Then
			sSubject = "Installation log Success on " & sComputerName & " - " & sApplicationName & " " & sApplicationVersion
			SendEmailSmtpText sFrom, sToOnSuccess, "", sSubject, sPackageLogFile, sZipFile
		Else
			sSubject = "Installation log Alert on " & sComputerName & " - " & sApplicationName & " " & sApplicationVersion
			SendEmailSmtpText sFrom, sToOnFail, "", sSubject, sPackageLogFile, sZipFile
		End If
		'Remove temporary zip file
		Call DeleteFile(sZipFile)
	End If
	
End Sub

Function OsPendingReboot

   '-------------------
   ' Purpose: Check if a reboot is pending
   ' Type: Function
   ' Input: None
   ' Output: Boolean that specifies if a reboot is pending
   '-------------------
	On Error Resume Next
	Dim bOsPendingReboot, sRegKeyValue
	bOsPendingReboot = False
	
	
	If bOsPendingReboot = False Then
		Set objSysInfo = CreateObject("Microsoft.Update.SystemInfo")
		bOsPendingReboot = objSysInfo.RebootRequired
		EmersonLog "Microsoft.Update.SystemInfo RebootRequired returns: " & bOsPendingReboot
	End If
		
	If bOsPendingReboot = False Then
		Dim bActiveComputerNameFound, sActiveComputerName
		bActiveComputerNameFound=RegKeyExist("HKLM\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName\ComputerName", sActiveComputerName)       
		If bActiveComputerNameFound Then
			If Not sComputerName=sActiveComputerName Then
				bOsPendingReboot = True
			End If
		End If
		EmersonLog "Pending computer rename returns: " & bOsPendingReboot
	End If
	
	If bOsPendingReboot = False Then
		RC = objReg.GetMultiStringValue(&H80000002, "SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations", arrValues)
		If (RC = 0) And (Err.Number = 0) Then
		  For Each strValue In arrValues
			 If InStr(UCase(strValue), UCase(sWindir)) > 0 Then
				bOsPendingReboot = True
			 End If
		  Next
		Else
		  Err.Clear
		End If
		EmersonLog "Pending file rename returns: " & bOsPendingReboot
	End If

	If bOsPendingReboot = False Then
		bOsPendingReboot=RegKeyExist("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired", sRegKeyValue)
		EmersonLog "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired returns: " & bOsPendingReboot
	End If
	
	If bOsPendingReboot = False Then
		bOsPendingReboot=RegKeyExist("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending", sRegKeyValue)
		EmersonLog "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending returns: " & bOsPendingReboot
	End If
	
	If bOsPendingReboot = False Then
		If fso.FileExists (sWindir & "\WinSxS\pending.xml") Then 
			bOsPendingReboot = True
		End If
		EmersonLog sWindir & "\WinSxS\pending.xml was found: " & bOsPendingReboot
	End If
	OsPendingReboot = bOsPendingReboot
	
End Function

Sub GetProfileSIDTweak (sTweakPath, sTweakValueName, sTweakType, sTweakValue)
	'sTweakPath  = HKCU path
	'sTweakValue = Registry value
	'sTweakType  = REG_SZ,REG_DWORD,REG_BINARY ...  
	On Error Resume Next 
	Set oRegistry=GetObject("winmgmts:\\" & sComputerName & "\root\default:StdRegProv") 
	sKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
	oRegistry.EnumKey hexHKLM, sKeyPath, aSubkeys
	 
	For Each oProfileSID In aSubkeys		
		If InStr (oProfileSID,"S-1-5-21") Then 
	    	RegWrite "HKEY_USERS\" & oProfileSID & "\" & sTweakPath, sTweakValueName, sTweakType, sTweakValue
	    End If
	Next
End Sub

Sub GetProfileSIDTweakDeleteCU (sTweakPath)
	'sTweakPath  = HKCU path
	'sTweakValue = Registry value
	'sTweakType  = REG_SZ,REG_DWORD,REG_BINARY ...  
	On Error Resume Next 
	Set oRegistry=GetObject("winmgmts:\\" & sComputerName & "\root\default:StdRegProv") 
	sKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
	oRegistry.EnumKey HKLM, sKeyPath, aSubkeys
	 
	For Each oProfileSID In aSubkeys		
		If InStr (oProfileSID,"S-1-5-21") Then 
	    	RegDeleteKey "HKEY_USERS\" & oProfileSID & "\" & sTweakPath
	    End If
	Next
End Sub

Sub GetProfileSIDTweakDelete (sTweakPath, sTweakValueName)
	'sTweakPath  = HKCU path
	'sTweakValue = Registry value
	'sTweakType  = REG_SZ,REG_DWORD,REG_BINARY ...  
	On Error Resume Next 
	Set oRegistry=GetObject("winmgmts:\\" & sComputerName & "\root\default:StdRegProv") 
	sKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
	oRegistry.EnumKey HKLM, sKeyPath, aSubkeys
	 
	For Each oProfileSID In aSubkeys		
		If InStr (oProfileSID,"S-1-5-21") Then 
	    	RegDelete "HKEY_USERS\" & oProfileSID & "\" & sTweakPath, sTweakValueName
	    End If
	Next
End Sub

Function RegWrite(reg_keyname, reg_valuename, reg_type, ByVal reg_value)
	Dim aRegKey, Return
	aRegKey = RegSplitKey(reg_keyname)
	If IsArray(aRegKey) = 0 Then
		RegWrite = 0
		Exit Function
	End If

	Return = RegWriteKey(aRegKey)
	If Return = 0 Then
		RegWrite = 0
		Exit Function
	End If

	Select Case reg_type
		Case "REG_SZ"
			Return = objReg.SetStringValue(aRegKey(0),aRegKey(1),reg_valuename,reg_value)
		Case "REG_EXPAND_SZ"
			Return = objReg.SetExpandedStringValue(aRegKey(0),aRegKey(1),reg_valuename,reg_value)
		Case "REG_BINARY"
			If IsArray(reg_value) = 0 Then reg_value = Array()
			Return = objReg.SetBinaryValue(aRegKey(0),aRegKey(1),reg_valuename,reg_value)
		Case "REG_DWORD"
			If IsNumeric(reg_value) = 0 Then reg_value = 0
			Return = objReg.SetDWORDValue(aRegKey(0),aRegKey(1),reg_valuename,reg_value)
		Case "REG_MULTI_SZ"
			If IsArray(reg_value) = 0 Then
				If Len(reg_value) = 0 Then
					reg_value = Array()
				Else
					reg_value = Array(reg_value)
				End If
			End If
			Return = objReg.SetMultiStringValue(aRegKey(0),aRegKey(1),reg_valuename,reg_value)
		Case Else
			RegWrite = 0
			Exit Function
	End Select

	If (Return <> 0) Or (Err.Number <> 0) Then
		RegWrite = 0
		Exit Function
	End If
	RegWrite = 1
End Function

Function RegWriteKey(RegKeyName)
	Dim Return
	If IsArray(RegKeyName) = 0 Then
		RegKeyName = RegSplitKey(RegKeyName)
	End If

	If (IsArray(RegKeyName) = 0) Or (UBound(RegKeyName) <> 1) Then
		RegWriteKey = 0
		Exit Function
	End If

	Return = objReg.CreateKey(RegKeyName(0),RegKeyName(1))
	If (Return <> 0) Or (Err.Number <> 0) Then
		RegWriteKey = 0
		Exit Function
	End If
	RegWriteKey = 1
End Function

Function RegDelete(reg_keyname, reg_valuename)
	Dim Return,aRegKey
	aRegKey = RegSplitKey(reg_keyname)
	If IsArray(aRegKey) = 0 Then
		RegDelete = 0
		Exit Function
	End If

	Return = objReg.DeleteValue(aRegKey(0),aRegKey(1),reg_valuename)
	If (Return <> 0) And (Err.Number <> 0) Then
		RegDelete = 0
		Exit Function
	End If
	RegDelete = 1
End Function

Function RegDeleteKey(reg_keyname)
	Dim Return,aRegKey
	aRegKey = RegSplitKey(reg_keyname)
	If IsArray(aRegKey) = 0 Then
		RegDeleteKey = 0
		Exit Function
	End If

	'On Error Resume Next
	Return = RegDeleteSubKey(aRegKey(0),aRegKey(1))
	'On Error Goto 0
	If Return = 0 Then
		RegDeleteKey = 0
		Exit Function
	End If
	RegDeleteKey = 1
End Function

Function RegDeleteSubKey(strRegHive, strKeyPath)
	Dim Return,arrSubkeys,strSubkey
    objReg.EnumKey strRegHive, strKeyPath, arrSubkeys
    If IsArray(arrSubkeys) <> 0 Then
        For Each strSubkey In arrSubkeys
            RegDeleteSubKey strRegHive, strKeyPath & "\" & strSubkey
        Next
    End If

	Return = objReg.DeleteKey(strRegHive, strKeyPath)
	If (Return <> 0) Or (Err.Number <> 0) Then
		RegDeleteSubKey = 0
		Exit Function
	End If
	RegDeleteSubKey = 1
End Function

Function RegSplitKey(RegKeyName)
	Dim strHive, strInstr, strLeft
	strInstr=InStr(RegKeyName,"\")
	If strInstr = 0 Then Exit Function
	strLeft=left(RegKeyName,strInstr-1)

	Select Case strLeft
		Case "HKCR","HKEY_CLASSES_ROOT"		strHive = &H80000000
		Case "HKCU","HKEY_CURRENT_USER"		strHive = &H80000001
		Case "HKLM","HKEY_LOCAL_MACHINE"	strHive = &H80000002
		Case "HKU","HKEY_USERS" 			strHive = &H80000003
		Case "HKCC","HKEY_CURRENT_CONFIG"	strHive = &H80000005
	  Case Else Exit Function
	End Select

    RegSplitKey = Array(strHive,Mid(RegKeyName,strInstr+1))
End Function

Function GetMsiForMsProductID(sProductID)

	Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
	Set colItems = objWMIService.ExecQuery("Select * from Win32_Product",,48)
	Set objShell = WScript.CreateObject( "WScript.Shell" )

	Dim objItem 'as Win32_Product
	Dim sMsiCode
	
	sMsiCode = ""
	For Each objItem in colItems
		'EmersonLog "Checking " & objItem.IdentifyingNumber & " " & Mid(objItem.IdentifyingNumber,11,4)
		If Mid(objItem.IdentifyingNumber,11,4)=sProductID Then
			EmersonLog "Description: " & objItem.Description
			EmersonLog "IdentifyingNumber: " & objItem.IdentifyingNumber
			EmersonLog "Language: " & objItem.Language
			EmersonLog "Name: " & objItem.Name
			EmersonLog "Version: " & objItem.Version
			sMsiCode =  Cstr(objItem.IdentifyingNumber)
			If objItem.Language <> 0 then
				Exit For
			End If 
		End If
	Next
	GetMsiForMsProductID =  sMsiCode

End Function

Function GetMsProductInstalled(ByVal sProductName, ByVal sProductCodeList, ByVal sMsProductMajorVersionFilter, ByRef iMsProductBitness, ByRef sMsProductVersion, ByRef sMsProductMsiCode, ByRef bC2R)

	'Purpose: 
	'	if sMsProductMajorVersionFilter="" returns True if any version of the specified Microsoft product was detected on the system
	'	if sMsProductMajorVersionFilter="n" returns True if version "n" (the characters of sMsProductVersion before the first dot) of the specified Microsoft product was detected on the system
	'Also defines 4 variables passed by reference:
	'iMsProductBitness: 32 or 64
	'sMsProductVersion: The product version in a syntax like 12.0.4518.1014
	'sMsProductMsiCode: The MSI code, if the software was installed using Msiexec
	'bC2R: If the installation was done using ClickToRun, this variable is set to True (indicating it is a Microsoft 365 Product)
	
	
	'http://support.microsoft.com/kb/832672   - 2003
	'http://support.microsoft.com/kb/928516   - 2007
	'http://support.microsoft.com/kb/2186281  - 2010
	'http://support.microsoft.com/kb/2786054  - 2013
	'https://support.microsoft.com/en-us/kb/3120274 - 2016

	Dim sDisplayName, sDisplayVersion
	Dim sPath, aSub, sKey, oReg
	Dim sReleaseVersion, sReleaseType, sMajorVersion, sMinorVersion, sProductID, sLanguageIdentifier, sBitnessCode, sOfficeFamilyID
	Dim sModifyPath
	Set oReg = GetObject("winmgmts:\\.\root\default:StdRegProv")
	Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
	
	Dim bMsProductInstalled
	bMsProductInstalled = False
	iMsProductBitness=0
	sMsProductMsiCode = ""
	sMsProductVersion = ""
	bC2R=False
	
	EmersonLog "Checking if Microsoft product " & sProductName & " is installed."
	If sMsProductMsiCode = "" Then
		Dim colItems, objItem
		Set colItems = oWMIService.ExecQuery("Select * from Win32_Product",,48)
		For Each objItem in colItems
			'EmersonLog "Checking " & objItem.IdentifyingNumber & " " & Mid(objItem.IdentifyingNumber,11,4)
			sProductID=Mid(objItem.IdentifyingNumber,11,4)
			If Instr(sProductCodeList, sProductID)>0 Then
				sMajorVersion = Left(objItem.Version,Instr(1,objItem.Version,".")-1)
				if sMajorVersion = sMsProductMajorVersionFilter or sMsProductMajorVersionFilter="" Then
					EmersonLog "Description: " & objItem.Description
					EmersonLog "IdentifyingNumber: " & objItem.IdentifyingNumber
					EmersonLog "Language: " & objItem.Language
					EmersonLog "Name: " & objItem.Name
					sMsProductVersion = objItem.Version
					EmersonLog "Version: " & sMsProductVersion
					sMsProductMsiCode =  Cstr(objItem.IdentifyingNumber)
					If objItem.Language <> 0 then
						Exit For
					End If 
				End If
			End If
		Next
	End If
	If sMsProductMsiCode = "" Then
		'ok, all values remain false, as initially set
	Else
		'There is an MSI based MsProduct found, now find out what bitness is
		bMsProductInstalled = True
		'Further analyze the GUID to get the bitness etc.
		'{BRMMmmmm-PPPP-LLLL-p000-D000000FF1CE}
		
		sReleaseVersion = Mid(sMsProductMsiCode,2,1)
		sReleaseType = Mid(sMsProductMsiCode,3,1)
		sMajorVersion = Mid(sMsProductMsiCode,4,2)
		sMinorVersion = Mid(sMsProductMsiCode,6,4)
		sProductID = Mid(sMsProductMsiCode,11,4)
		sLanguageIdentifier = Mid(sMsProductMsiCode,16,4)
		sBitnessCode = Mid(sMsProductMsiCode,21,1)
		sOfficeFamilyID = Mid(sMsProductMsiCode,27,11)
			
		EmersonLog "Microsoft Office Release version: " & sReleaseVersion
		EmersonLog "Release type: " & sReleaseType
		EmersonLog "Major version: " & sMajorVersion
		EmersonLog "Minor version: " & sMinorVersion
		EmersonLog "Product ID: " & sProductID
		EmersonLog "Language identifier: " & sLanguageIdentifier
		EmersonLog "Bitness code: " & sBitnessCode
		EmersonLog "Office Family ID: " & sOfficeFamilyID
		
		If sBitnessCode="1" Then 
			iMsProductBitness=64
		Else
			iMsProductBitness=32
		End If
	End If

	If sMsProductVersion="" Then
		sPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
		oReg.EnumKey hexHKLM, sPath, aSub

		' Loop through each key
		For Each sKey In aSub
			If RegKeyExist("HKEY_LOCAL_MACHINE\" & sPath & "\" & sKey & "\DisplayName", sDisplayName) Then
				If Instr(1,sKey, sProductName)> 0 Then
					bC2R=True
					sDisplayVersion = WshShell.RegRead("HKEY_LOCAL_MACHINE\" & sPath & "\" & sKey & "\DisplayVersion")
					sMajorVersion = Left(sDisplayVersion,Instr(sDisplayVersion,".")-1)
					If sMajorVersion = sMsProductMajorVersionFilter or sMsProductMajorVersionFilter="" Then
						sMsProductVersion = sDisplayVersion
						bMsProductInstalled = True
						sModifyPath = WshShell.RegRead("HKEY_LOCAL_MACHINE\" & sPath & "\" & sKey & "\ModifyPath")
						If Instr(1,LCase(sModifyPath),"repair platform=x86")>0 Then
							iMsProductBitness=32
						Else
							iMsProductBitness=64
						End If
					End If
				End If
			Else
				Err.Clear
			End If
		Next
		
	End If

	If sMsProductVersion="" Then
		sPath = "SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
		oReg.EnumKey hexHKLM, sPath, aSub

		' Loop through each key
		For Each sKey In aSub
			If RegKeyExist("HKEY_LOCAL_MACHINE\" & sPath & "\" & sKey & "\DisplayName", sDisplayName) Then
				If Instr(1,sKey, sProductName)> 0 Then
					bC2R=True
					sDisplayVersion = WshShell.RegRead("HKEY_LOCAL_MACHINE\" & sPath & "\" & sKey & "\DisplayVersion")
					sMajorVersion = Left(sDisplayVersion,Instr(sDisplayVersion,".")-1)
					If sMajorVersion = sMsProductMajorVersionFilter or sMsProductMajorVersionFilter="" Then
						sMsProductVersion = sDisplayVersion
						bMsProductInstalled = True
						sModifyPath = WshShell.RegRead("HKEY_LOCAL_MACHINE\" & sPath & "\" & sKey & "\ModifyPath")
						If Instr(1,LCase(sModifyPath),"repair platform=x86")>0 Then
							iMsProductBitness=32
						Else
							iMsProductBitness=64
						End If
					End If
				End If
			Else
				Err.Clear
			End If
		Next
		
	End If

	If bMsProductInstalled=False Then
		EmersonLog sProductName & " was not found"
	Else
		EmersonLog sProductName & " was found, bitness: " & iMsProductBitness & " version: " & sMsProductVersion & " Installed by C2R Installer: " & bC2R
	End If
	
	GetMsProductInstalled = bMsProductInstalled

End Function

Function RegKeyExist(ByVal sRegKeyLocation, ByRef sRegKeyValue)
	'Example: 
	'bRegKeyExist = RegKeyExist("HKEY_LOCAL_MACHINE\SOFTWARE\7-Zip\Path123123213",sRegKeyValue)  returns FALSE

	Dim sRegKeyExistMsg
	sRegKeyExistMsg="Unable to open registry key"
	On Error Resume Next
	sRegKeyValue = WshShell.RegRead(sRegKeyLocation)
	If Err.number<>0 Then
		RegKeyExist = False
		Err.Clear
	Else
		RegKeyExist = True
	End If
	
End Function

Function HotFixFound(sHotFixID)

	Dim bHotFixFound
	bHotFixFound=False
	Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
	Set colQuickFixes = objWMIService.ExecQuery("SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID='" & sHotFixID & "'")
	For Each objQuickFix in colQuickFixes
	 'EmersonLog "Computer: " & objQuickFix.CSName
	 'EmersonLog "Description: " & objQuickFix.Description
	 'EmersonLog "Hot Fix ID: " & objQuickFix.HotFixID
	 'EmersonLog "Installation Date: " & objQuickFix.InstallDate
	 'EmersonLog "Installed By: " & objQuickFix.InstalledBy
	 bHotFixFound=True
	Next
	HotFixFound = bHotFixFound

End Function

Function GetPowerShellVersion

	Dim sCommand, sParameters 
	sCommand="powershell.exe"
	sParameters="-noprofile -command $PSVersionTable.PSVersion.Major"
	Set Executor = WshShell.Exec(Chr(34) & sCommand & Chr(34) & " " & sParameters)
	Executor.StdIn.Close
	GetPowerShellVersion = Executor.StdOut.ReadAll

End Function

Function GetIvantiEpmCoreNameUsedByAgent

	'Purpose: 
	' Get the name of the Ivanti Endpoint Manager (EPM) core server used by an Ivanti agent
	'Input parameters (ByVal):
	' None
	'Returns:
	' Name of the core server
	'Example use:
	' sIvantiEpmCoreNameUsedByAgent = GetIvantiEpmCoreNameUsedByAgent
	
	Dim bIvantiEpmCoreNameUsedByAgentFound, sIvantiEpmCoreNameUsedByAgent
	bIvantiEpmCoreNameUsedByAgentFound = False
	If bIvantiEpmCoreNameUsedByAgentFound = False Then
		bIvantiEpmCoreNameUsedByAgentFound = RegKeyExist("HKLM\Software\WOW6432Node\Intel\LANDesk\LDWM\CoreServer",sIvantiEpmCoreNameUsedByAgent) 
	End If
	If bIvantiEpmCoreNameUsedByAgentFound = False Then
		bIvantiEpmCoreNameUsedByAgentFound = RegKeyExist("HKLM\Software\Intel\LANDesk\LDWM\CoreServer",sIvantiEpmCoreNameUsedByAgent) 
	End If
	
	If IsNull(sIvantiEpmCoreNameUsedByAgent)=False Then
		GetIvantiEpmCoreNameUsedByAgent = sIvantiEpmCoreNameUsedByAgent	
	Else
		GetIvantiEpmCoreNameUsedByAgent = ""
	End If
	
End Function

Sub SourcePathCleanup

	Dim sSourcePathTmp 
	On Error Resume Next
	sSourcePathTmp = sTemp & "\" & Replace(sPackageName," ","_")
	'Make sure the current path is not equal to the path we want to delete, set the current path to " & sWindir & "\Temp"
	WshShell.CurrentDirectory = sWindir & "\Temp"
	
	If fso.FolderExists(sSourcePathTmp) Then
		fso.DeleteFolder sSourcePathTmp, True 
	End If
	
End Sub

Sub ProgressMsg(sMessage, sWindowTitle)

	'Next line must be placed outside the function, to allow it to work
	'Dim oProgressMsg		'Public variable needed for Subprocedure ProgressMsg
	'Purpose: Show a pop-up message while the master script continues (when sMessage is defined)
	'         Allow the master script to remove the pop-up message when needed (when sMessage = "")
	
	Dim sTempVbs, oTempVbs
	sTempVbs = sTemp & "\ProgressMsg.vbs"
	
	On Error Resume Next
	oProgressMsg.Terminate()
	
    If sMessage = "" Then
		DeleteFile sTempVbs
    Else
	    Set oTempVbs = fso.CreateTextFile(sTempVbs, True)
	    oTempVbs.WriteLine "Set oWshShell = WScript.CreateObject(""Wscript.Shell"")"
	    oTempVbs.WriteLine "oWshShell.Popup """ & sMessage & """,,""" & sWindowTitle & """,64"
	    oTempVbs.Close

	    Set oProgressMsg = WshShell.Exec(sWindir & "\system32\wscript.exe """ & sTempVbs & """")
    End If
    
End Sub

Function StringToBoolean(strString)

	if strString = "0" Then 
		StringToBoolean = False
	Else
		StringToBoolean = True
	End If
	
End Function

Function GetFreeSpace(sDriveToCheck)

	'sDriveToCheck - the drive we are checking space available
	'Requires parameter like C:
 	Dim iDiskSpace
	Set objWMIService = GetObject("winmgmts:")
	Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='" & sDriveToCheck & "'")
	
	iDiskSpace = FormatGB(objLogicalDisk.FreeSpace)

	EmersonLog "Free space on " & sDriveToCheck & " " & iDiskSpace & " GB"
	GetFreeSpace = iDiskSpace
	
End Function

Function FormatGB(iSizeToCalculate)

  FormatGB = FormatNumber(iSizeToCalculate / (1024 * 1024 * 1024), 2,0,0,0)

End Function

Function FolderIsEmpty(strFolder)

	If fso.FolderExists(strFolder) Then
		 Set oFolder = fso.GetFolder(strFolder)
	   
		 If oFolder.Files.Count = 0 And oFolder.SubFolders.Count = 0 Then
			 FolderIsEmpty=True
		 Else
			 FolderIsEmpty=False

		End If
	End If

End Function

Function DefineScheduledTask(sTaskName, sTaskRunFile, sStartTime, sRepeatInterval)

	'Purpose: Create a local scheduled task
	'Parameters: 
	'	sTaskName: Name of the Scheduled task in the Task Scheduler
	'	sTaskRunFile: Name of the file to run
	'	sStartTime: either "Startup" or a number indicating in how many minutes from now the task should start
	'   sRepeatInterval either "None" or an interval in a valid format for XML, like "PT2H" = a two hour interval
	
	Dim bDefineScheduledTask, sCommand, sParameters, sTaskXmlFile, oTaskXml, sReturnCode
	
	If fso.FileExists(sTaskRunFile) Then
		EmersonLog "Define Scheduled Task " & sTaskName
		
		'delete in case previous is still around
		
		EmersonLog "Deleting previous scheduled task " & sTaskName & " if it would exist."
		sCommand = sWindir & "\System32\schtasks.exe"
		sParameters = "/Delete /TN " & Chr(34) &  sTaskName & Chr(34) & " /F"
		EmersonLog "Running: " & Chr(34) & sCommand & Chr(34) & " " & sParameters
		sReturnCode = oWshShell.Run(Chr(34) & sCommand & Chr(34) & " " & sParameters, 0, True)
		EmersonLog "The command returned: " & sReturnCode
		
		sTaskXmlFile = sLogFolderLocal & "\" & sTaskName & ".xml"
		'Delete file if it would already exist
		DeleteFile sTaskXmlFile
		EmersonLog "Create xml file " & sTaskXmlFile
		
		Dim dtmDateNow, dtmScheduleDate
		dtmDateNow = Now
		Dim oStream
		Set oStream = CreateObject("ADODB.Stream")
		oStream.CharSet = "UTF-16"
		oStream.Open
		oStream.WriteText"<?xml version=""1.0"" encoding=""UTF-16""?>",1
		oStream.WriteText"<Task version=""1.2"" xmlns=""http://schemas.microsoft.com/windows/2004/02/mit/task"">",1
		oStream.WriteText"	<RegistrationInfo>",1
		oStream.WriteText"		<Date>" & Year(dtmDateNow) & "-" & FixedLengthNbr(Month(dtmDateNow),2) & "-" & FixedLengthNbr(Day(dtmDateNow),2) & "T" & FixedLengthNbr(Hour(dtmDateNow),2) & ":" & FixedLengthNbr(Minute(dtmDateNow),2) & ":" & FixedLengthNbr(Second(dtmDateNow),2) & "</Date>",1
		oStream.WriteText"		<Author>SYSTEM</Author>",1
		oStream.WriteText"	</RegistrationInfo>",1


		oStream.WriteText"	<Triggers>",1
		If sStartTime="Startup" Then
			oStream.WriteText"		<BootTrigger>",1
		Else
			oStream.WriteText"		<TimeTrigger>",1
		End If

		If sRepeatInterval<>"None" Then
			oStream.WriteText"			<Repetition>",1
			oStream.WriteText"				<Interval>" & sRepeatInterval & "</Interval>",1
			oStream.WriteText"				<StopAtDurationEnd>false</StopAtDurationEnd>",1
			oStream.WriteText"		    </Repetition>",1
		End If
		If sStartTime="Startup" Then
			EmersonLog "Task will be run at startup"
			oStream.WriteText"			<Enabled>true</Enabled>",1
			oStream.WriteText"		</BootTrigger>",1
		Else
			EmersonLog "Task will be run after " & sStartTime & " minutes"
			dtmScheduleDate = DateAdd("n",sStartTime,Now)
			oStream.WriteText"			<StartBoundary>" & Year(dtmScheduleDate) & "-" & FixedLengthNbr(Month(dtmScheduleDate),2) & "-" & FixedLengthNbr(Day(dtmScheduleDate),2) & "T" & FixedLengthNbr(Hour(dtmScheduleDate),2) & ":" & FixedLengthNbr(Minute(dtmScheduleDate),2) & ":" & FixedLengthNbr(Second(dtmScheduleDate),2) & "</StartBoundary>",1
			oStream.WriteText"			<Enabled>true</Enabled>",1
			oStream.WriteText"		</TimeTrigger>",1
		End If	
		oStream.WriteText"	</Triggers>",1
		oStream.WriteText"	<Principals>",1
		oStream.WriteText"		<Principal id=""Author"">",1
		oStream.WriteText"			<UserId>S-1-5-18</UserId>",1
		oStream.WriteText"			<RunLevel>LeastPrivilege</RunLevel>",1
		oStream.WriteText"		</Principal>",1
		oStream.WriteText"	</Principals>",1
		oStream.WriteText"	<Settings>",1
		oStream.WriteText"		<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>",1
		oStream.WriteText"		<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>",1
		oStream.WriteText"		<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>",1
		oStream.WriteText"		<AllowHardTerminate>true</AllowHardTerminate>",1
		oStream.WriteText"		<StartWhenAvailable>true</StartWhenAvailable>",1
		oStream.WriteText"		<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>",1
		oStream.WriteText"		<IdleSettings>",1
		oStream.WriteText"			<StopOnIdleEnd>true</StopOnIdleEnd>",1
		oStream.WriteText"			<RestartOnIdle>false</RestartOnIdle>",1
		oStream.WriteText"		</IdleSettings>",1
		oStream.WriteText"		<AllowStartOnDemand>true</AllowStartOnDemand>",1
		oStream.WriteText"		<Enabled>true</Enabled>",1
		oStream.WriteText"		<Hidden>false</Hidden>",1
		oStream.WriteText"		<RunOnlyIfIdle>false</RunOnlyIfIdle>",1
		oStream.WriteText"		<WakeToRun>false</WakeToRun>",1
		oStream.WriteText"		<ExecutionTimeLimit>P3D</ExecutionTimeLimit>",1
		oStream.WriteText"		<Priority>7</Priority>",1
		oStream.WriteText"	</Settings>",1
		oStream.WriteText"	<Actions Context=""Author"">",1
		oStream.WriteText"		<Exec>",1
		oStream.WriteText"			<Command>" & sTaskRunFile & "</Command>",1
		oStream.WriteText"		</Exec>",1
		oStream.WriteText"	</Actions>",1
		oStream.WriteText"</Task>",1
		oStream.SaveToFile sTaskXmlFile, 2
		oStream.Close
		
		EmersonLog "Creating new scheduled task: " & sTaskName
		sCommand = sWindir & "\System32\schtasks.exe"
		sParameters = "/create /tn """ & sTaskName & """ /xml """ & sTaskXmlFile & """ /ru SYSTEM" 
		EmersonLog "Schedule to run " & sTaskRunFile & " at " & dtmScheduleDate

		EmersonLog "Running: " & Chr(34) & sCommand & Chr(34) & " " & sParameters
		sReturnCode = WshShell.Run(Chr(34) & sCommand & Chr(34) & " " & sParameters, 0, True)
		EmersonLog "The command returned: " & sReturnCode


		If sReturnCode=0 Then
			bDefineScheduledTask=True
		Else
			bDefineScheduledTask=False
		End If
		
	Else
		EmersonLog "Error scheduling task " & sTaskName & ". The file to run " & sTaskRunFile & " could not be found."
		bDefineScheduledTask=False
	End If
	
	DefineScheduledTask = bDefineScheduledTask

End Function
