'================================================================================
'
' SETUP ACTION: MSI INSTALL
'
' APPLICATION:  IBM i Access Client Solutions pmver English (US)
'
' AUTHOR:       Artur Borowiec HCL PL
' CREATED:      2016-08-16
'
' REVISION HISTORY:
' 2017-03-30 JAn Wnek new version 1.1.7.0
' 2017-08-31 Artur Borowiec HCL		New version 1.1.7.1
' 2017-11-22 Jan Wnek HCL PL		New version 1.1.7.2 and 11.12.0.0
' 2018-03-14 Michal Mazurek HCL PL	New version 1.1.7.3, templates updated
' 2020-02-12 Artur Borowiec HCL PL	New version 1.1.8.3
'
'================================================================================

Function Product()
    Product   = "{C68F4099-665C-49BA-B678-2113F743D034}"    ' Product code
End Function

Function ApplicationName()
    ApplicationName = "IBM i Access Client Solutions Pmver English (US)"	' Friendly name of application
End Function

Function SetupFile()
    SetupFile = ""    ' Main setup action executable
End Function

Function MSTFile()
    MSTFile   = ""    ' Optional setup transform file
End Function

Function CmdArgs()
    CmdArgs   = ""    ' Optional command line arguments
End Function

Function Processes(ByRef AskUser)
    Processes = ""    ' Comma separated list of process names and/or paths
    AskUser = True    ' True to ask user to close, False to terminate without asking
End Function

Function AcceptRC()
    AcceptRC  = "1641,3010"    ' Acceptable return codes (besides zero)
End Function

Sub BeforeSetupAction()
    ' <code to perform any custom actions before install/remove/repair/patch>
    ' If any errors occur, set SMSError to the corresponding error code
	
	On Error Resume Next
	
	Call ShowProgress()
	Call Loging("Starting installation of " & ApplicationName & vbnewline,1,0)
	
	'Checking if IBM iSeries Access 7.1 is installed. If Yes then skip installation of Windows Application Package.
	ProdID=WSHShell.RegRead("HKLM\Software\IBM\Client Access\CurrentVersion\ProductId")
	BlockingValues = "5761-XE1 ,5770-XE1,5722-XE1"
	If Not Instr(1, "," & BlockingValues & ",", "," & cstr(ProdID) & ",") > 0 then    
		Command = MediaFolder & "\iACS-WinAppPkg\Image64a\setup.exe" & " /l" &chr(34) & "1033" & chr(34) & " /s /v" & chr(34) & "/qn /l*v "& LogFolder() & "\IBM_iACS_WindowsApplicationPackage_Install.log" & chr(34)
		Call InstallApp("IBM_iACS_WindowsApplicationPackage",Command,TRUE)  
	End If
	
	'Main Install
	Command = "msiexec.exe /I " & chr(34) & MediaFolder & "\iACS\iACS.msi" & chr(34) & " /qn /l*v " & LogFolder() & "\IBM_iACS_Install.log"
	Call InstallApp("IBM iACS",Command,TRUE)
	
	'Modification of AcsConfig.properties file
	File = WSHShell.ExpandEnvironmentStrings("%PUBLIC%") & "\IBM\ClientSolutions\AcsConfig.properties"
	FileSource =  MediaFolder & "\AcsConfig.properties"
	FSO.CopyFile FileSource, File, True
	
End Sub

Sub IntermediateSetupAction(ActionIndex)
    ' <code to perform any custom actions between setup actions>
    ' If any errors occur, set SMSError to the corresponding error code
End Sub

Sub AfterSetupAction()
    ' <code to perform any custom actions after install/remove/repair/patch>
    ' If any errors occur, set SMSError to the corresponding error code
	
	Call Loging(vbnewline & "Installation finished successfully",0,0)
	Call CheckLog()	
	
End Sub

Sub UserSetupAction()
    ' <code to perform any user specific actions that are not part of the msi>
    ' This routine is executed only when the /user switch is passed to the script
End Sub

Function LogFolder()
	'ver.2.0 27-04-2018 JW 
	On error resume next
	LogFolder = WSHShell.ExpandEnvironmentStrings("%systemdrive%\Temp")
	If  Not FSO.FolderExists(LogFolder) Then
		FSO.CreateFolder(LogFolder)
	End if

	strLOG = Replace(TRIM(ApplicationName)," ","")

	invalidChars = Array ("<", ">", ":", "/", "\", "|", "*", "?","""",vbTab,vbCrLf)
	For Each c In invalidChars
		strLOG = Replace(strLOG,c, "")
	Next

	LogFolder = LogFolder & "\" & strLOG
	If  Not FSO.FolderExists(LogFolder) Then
		FSO.CreateFolder(LogFolder)
	End if
End Function

Sub CheckLog()
    If Instr(1, "," & AcceptRC & ",", "," & cstr(SMSError) & ",") > 0 Then SMSError = 0
    If SMSError = 0 Then  
        If FSO.FolderExists(LogFolder) Then
            FSO.DeleteFolder LogFolder, True   
        End if             
    End If
End Sub

Sub Loging(Message,level,intType)
	'ver1.4 2018-10-25
	Objarch32="Not Found"
	Objarch64="Not Found"
	On Error Resume Next
	'***********starting , initializing file******************'
	LogingFile = LogFolder & "\execLog.log"
	prefix  = Date & " - " & Time & " : "
	If Not FSO.FileExists(LogingFile) Then
		'*******specific information retrieving when file is created*********
		If UserLoggedOn() Then
			strUser = WSHshell.ExpandEnvironmentStrings("%USERNAME%")
		Else
			strUser = "NO"
		End IF

		Const REG_SITE = "HKLM\Software\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Site-Name"
		ComputerGetSite = WSHShell.RegRead(REG_SITE)

		strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & Product

		arrValueNames=Array("VolvoPkgVer","PkgVer")
		Arch =Array(32,64)
		For Each objArch in Arch
			Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
			oCtx.Add "__ProviderArchitecture", objArch
			Set oLocator = CreateObject("Wbemscripting.SWbemLocator")
			Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv")
			Set oInParams = oReg.Methods_("GetStringValue").InParameters
			oInParams.hDefKey = &h80000002
			oInParams.sSubKeyName = strKeyPath
			For Each value in arrValueNames
				oInParams.sValueName = Value
				Set oOutParams = oReg.ExecMethod_("GetStringValue", oInParams, , oCtx)
				if objArch=32 and not IsNull(oOutParams.sValue) Then
					Objarch32 = oOutParams.sValue
				End IF
				If objArch=64 and not IsNull(oOutParams.sValue)Then
					Objarch64 = oOutParams.sValue
				End IF
			Next
		Next

		'*******************************************************************
		Set objFile = FSO.CreateTextFile(LogingFile,True)
		objFile.Write prefix & "*****************STARTING LOGING*****************" & vbCrLf
		objFile.Write prefix & "UserLogedIn : " & strUser &vbCrLf
		objFile.Write prefix & "OS64bit     : " & OS64bit() &vbCrLf
		objFile.Write prefix & "Wscript used: " & Wscript.FullName &vbCrLf
		objFile.Write prefix & "Script used : " & WScript.ScriptFullName  &vbCrLf
		objFile.Write prefix & "Site used   : " & ComputerGetSite  &vbCrLf
		objFile.Write prefix & "Computer Information " & ComputerGetSite  &vbCrLf
		Set objWMIService = GetObject( "winmgmts:\\.\root\cimv2" )
		Set colItems = objWMIService.ExecQuery( "Select * from Win32_ComputerSystem" )
		For Each objItem in colItems
			objFile.Write prefix & "Name: " & objItem.Name &vbCrLf
			objFile.Write prefix & "Model: " & objItem.Model &vbCrLf
			objFile.Write prefix & "Domain: " & objItem.Domain &vbCrLf
		Next
		Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
		For Each objItem in colItems
			objFile.Write prefix & "System: " & objItem.Caption  &vbCrLf
			objFile.Write prefix & "Version: " & objItem.Version &vbCrLf
			objFile.Write prefix & "MUILanguages: " & objItem.MUILanguages &vbCrLf
			Converteddate = CDate(Mid(objItem.InstallDate, 5, 2) & "/" & Mid(objItem.InstallDate, 7, 2) & "/" & Left(objItem.InstallDate, 4) & " " & Mid (objItem.InstallDate, 9, 2) & ":" & Mid(objItem.InstallDate, 11, 2) & ":" & Mid(objItem.InstallDate, 13, 2))
			objFile.Write prefix & "System InstallDate: " & Converteddate &vbCrLf
		Next
		objFile.Write prefix & "32 bit GUID: " & Objarch32 &vbCrLf
		objFile.Write prefix & "64 bit GUID: " & Objarch64 &vbCrLf
		objFile.Write prefix & "*************************************************" & vbCrLf
		objFile.Close
	End if

	'*********** Main ******************'
	Set objFile = FSO.OpenTextFile(LogingFile,8,True,0)
	If level <> 0 then
		'level 1,2,3,.... is additional spaces with messages
		TempMessage=  Replace(Message,vbCrLf,(vbnewline & prefix & Space((level-1)*10)))
		strMessage = prefix &  Space((level-1)*10)&TempMessage
	Else
		'level 0 will means to terminate logging'
		TempMessage=  Replace(Message,vbCrLf,(vbnewline & prefix))
		strMessage = prefix &  TempMessage & vbnewline & prefix & "*****************FINISHED LOGING*****************"
	End If
	objFile.Write strMessage & vbNewLine
	WSHShell.LogEvent intType, Message & vbNewLine & vbNewLine & "Script: " & WScript.ScriptFullName
	objFile.Close

	'*********** finishing ******************'
	If level = 0 then
		'sending txt content to event viewer
		set objFile = FSO.GetFile(LogingFile)
		'checking size of message that will be sent to eventviewer- cant be more than 32766 bytes.
		roundUp = Round((CLNG(objFile.Size)/31000) + .5)     'determining on how many messages need to split'
		Set objTextFile = FSO.OpenTextFile(LogingFile,1)
		page = 1
		tmpSTR=""
		Do Until objTextFile.AtEndOfStream
			strLine = objTextFile.ReadLine
			tmpSTR=tmpSTR & vbNewLine& strLine
			If LEN(tmpSTR) > 31000 then
				WSHShell.LogEvent 8, tmpSTR & vbNewLine &vbNewLine & " exitlog page " & page & "/" & roundUp & " Script: " & WScript.ScriptFullName
				page=page+1
				tmpSTR="... exitlog page " & page & "/" & roundUp & "..."
			End If
		Loop
		WSHShell.LogEvent 8, tmpSTR & vbNewLine  & vbNewLine & " exitlog page " & page & "/" & roundUp &" Script: " & WScript.ScriptFullName
		objTextFile.Close
	End IF
End Sub

Sub InstallApp(AppName,Command,TerminateScript)
	'Ver. 1.1 AB
	Call Loging("Installation of " & AppName & " Commandline: " & Command,2,0)
	SMSError = WSHShell.Run(Command, 0, True)
	If Instr(1, "," & AcceptRC & ",", "," & cstr(SMSError) & ",") > 0 Then SMSError = 0
	If SMSError <> 0 Then
	Call Loging("Installation failed with error code: " & SMSError & vbnewline,2,1)
		If TerminateScript Then 
			Call Terminate(SMSError)  
		Else
			SMSError = 0
		End If                
	Else
		Call Loging("Installation successful" & vbnewline,2,0)
	End If  
End Sub

'//BEGIN TEMPLATE SETUP_ACTION_MSI_INSTALL_031
'================================================================================
'
' CAUTION! DO NOT REMOVE, CHANGE OR ADD CODE IN THIS SECTION!
'
' ALL CONTENT - INCLUDING THE 'BEGIN TEMPLATE' AND 'END TEMPLATE' TAGS - MAY BE
' REPLACED WITHOUT FURTHER NOTICE!
'
'================================================================================

Const SMSERROR_INVALID_PACKAGE_FOLDER = -1
Const SMSERROR_INVALID_INSTALL_STATE = -2
Const SMSERROR_MISSING_PKGVER_FILE = -3
Const ERROR_SUCCESS_REBOOT_REQUIRED = 3010

Dim FSO
Dim WSHShell
Dim PackageFolder
Dim MediaFolder
Dim ScriptFolder
Dim MSTFolder
Dim ISSFolder
Dim INFFolder
Dim SMSError
Dim MSIniReg
Dim PackageVersion
Dim CustomerFolderName
Dim bSkipNext: bSkipNext = False
Dim bSkipAll: bSkipAll = False
Dim bRebootReq: bRebootReq = False

On Error Resume Next

Set FSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = WScript.CreateObject("WScript.Shell")

SMSError = 0

Call GetPackageFolders
If SMSError <> 0 Then Call Terminate(SMSError)

Err.Clear 

If Argument("user") Then
    Call UserSetupAction
    If SMSError <> 0 Then 
        LogError "Error " & SMSError & " in module UserSetupAction - execution halted!", "Main"
        Call Terminate(SMSError)
    End If
Else
    Call VerifyInstallState
    If SMSError = 0 Then 
        Call GetPackageVersion
        If SMSError <> 0 Then Call Terminate(SMSError)
        Call TerminateProcesses
        Call BeforeSetupAction
        If SMSError <> 0 Then 
            LogError "Error " & SMSError & " in module BeforeSetupAction - execution halted!", "Main"
            Call Terminate(SMSError)
        End If
        Call PerformSetupAction
        If SMSError <> 0 Then Call Terminate(SMSError)
        Call AfterSetupAction
        If SMSError <> 0 Then 
            LogError "Error " & SMSError & " in module AfterSetupAction - execution halted!", "Main"
            Call Terminate(SMSError)
        End If
        Call SetClientVersion
    End If
End If

Call Terminate(0)

Sub GetPackageFolders()
    On Error Resume Next
    Err.Clear 
    PackageFolder = FSO.GetFile(WScript.ScriptFullName).ParentFolder.ParentFolder.ParentFolder.ParentFolder.ParentFolder.Path
    If Err.Number <> 0 Then
        SMSError = SMSERROR_INVALID_PACKAGE_FOLDER
        LogError "Unable to locate package root folder - execution halted!", "GetPackageFolders"
        Exit Sub
    End If
    CustomerFolderName = FSO.GetFile(WScript.ScriptFullName).ParentFolder.ParentFolder.ParentFolder.ParentFolder.Name
    MediaFolder = PackageFolder & "\Media"
    ScriptFolder = StrReverse(Split(StrReverse(WScript.ScriptFullName), "\", 2)(1))
    MSTFolder = StrReverse(Split(StrReverse(ScriptFolder), "\", 2)(1)) & "\Mst"
    INFFolder = StrReverse(Split(StrReverse(ScriptFolder), "\", 2)(1)) & "\Inf"
    ISSFolder = StrReverse(Split(StrReverse(ScriptFolder), "\", 2)(1)) & "\Iss"
End Sub

Sub GetPackageVersion()
    Dim objPkgFolder, objFile, strName, strExt, iVer, strVer, iMaxVer
    On Error Resume Next
    iMaxVer = 0
    Set objPkgFolder = FSO.GetFolder(PackageFolder)
    For Each objFile In objPkgFolder.Files 
        strName = UCase(Left(objFile.Name, InstrRev(objFile.Name, ".") - 1))
        strExt = UCase(Mid(objFile.Name, InStrRev(objFile.Name, ".")))
        If (Len(strName) = 3) And (strExt = ".TXT") Then
            iVer = CLng(strName)
            strVer = String(3 - Len(CStr(iVer)), "0") & CStr(iVer)
            If (strVer = strName) And (iVer > iMaxVer) Then iMaxVer = iVer
        End If
    Next
    If iMaxVer > 0 Then
        PackageVersion = String(3 - Len(CStr(iMaxVer)), "0") & CStr(iMaxVer)
    Else
        SMSERROR = SMSERROR_MISSING_PKGVER_FILE
        LogError "Unable to locate package version file(s) - execution halted!", "GetPackageVersion"
    End If
End Sub

Sub SetClientVersion()
    Dim strReg
    On Error Resume Next
    strReg = "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\" & Split(Product, "|")(Ubound(Split(Product, "|")))
    WSHShell.RegWrite strReg & "\VolvoPkgVer", PackageVersion
    WSHShell.RegWrite strReg & "\VolvoInstallDate", Now()
    WSHShell.RegWrite strReg & "\VolvoInstallScript", WScript.ScriptFullName
    WSHShell.RegWrite strReg & "\VolvoAppName", ApplicationName
End Sub

Function Argument(ByVal Arg)
    Dim i
    On Error Resume Next
    If Left(Arg, 1) <> "/" Then Arg = "/" & Arg
    If WScript.Arguments.Count > 0 Then
        For i = 0 To Wscript.Arguments.Count - 1
            If StrComp(WScript.Arguments(i), Arg, vbTextCompare) = 0 Then
                Argument = True
                Exit Function
            End If
        Next
    End If
    Argument = False
End Function

Sub SMSHardwareInventory()
    Const ACTION_ID_HARDWARE_INVENTORY = "{00000000-0000-0000-0000-000000000101}"
    Dim objApplet, colActions, objAction
    On Error Resume Next
    Set objApplet = CreateObject("CPAPPLET.CPAppletMgr")
    If Err.Number <> 0 Then Exit Sub
    Set colActions = objApplet.GetClientActions
    If Err.Number <> 0 Then Exit Sub
    For Each objAction In colActions
        If objAction.ActionID = ACTION_ID_HARDWARE_INVENTORY Then
            objAction.PerformAction
            Exit For
        End If
    Next
    Set objAction = Nothing
    Set colActions = Nothing
    Set objApplet = Nothing
End Sub

Sub VerifyInstallState()
    Const HKEY_LOCAL_MACHINE = &H80000002
    Const KEY_UNINSTALL = "Software\Microsoft\Windows\CurrentVersion\Uninstall\"
    Dim objReg, strValue, arrProduct, i
    On Error Resume Next
    If Product = "" Then Exit Sub
    Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
    arrProduct = Split(Product, "|")
    For i = 0 To UBound(arrProduct)
        If objReg.GetStringValue(HKEY_LOCAL_MACHINE, KEY_UNINSTALL & arrProduct(i), "", strValue) < 2 Then
            SMSError = SMSERROR_INVALID_INSTALL_STATE
            Exit For
        End If
    Next
End Sub

Sub Terminate(ExitCode)
    On Error Resume Next
    If Argument("hwinv") Then Call SMSHardwareInventory
    Call WScript.Quit(ExitCode)
End Sub

Sub TerminateProcesses()
    Dim strTitle, arrList, bAskUser, objWMI, strQuery, strItem, colProcesses, objProcess, objSC, sPath, lCompare, bMatch, bTerminate, lCount, strText, intOsLang
    On Error Resume Next
    If Processes(bAskUser) = "" Then Exit Sub
    intOsLang = GetOsLanguageId()
    Select Case intOsLang
    Case 1053 ' Swedish
        strTitle = Trim("Installationsprogrammet för " & ApplicationName)
    Case Else ' Default: English
        strTitle = Trim(ApplicationName & " Setup")
    End Select
    arrList = Split(WSHShell.ExpandEnvironmentStrings(Processes(bAskUser)), ",")
    Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate, (Debug)}!\\.\root\cimv2")
    strQuery = "select Name,ExecutablePath from Win32_Process"
    bTerminate = False
    lCount = 0
    Do
        Set colProcesses = objWMI.ExecQuery(strQuery)
        strProcesses = ""
        For Each objProcess In colProcesses
            Set objSC = WSHShell.CreateShortcut("c:\foo.lnk")  
            objSC.TargetPath = objProcess.ExecutablePath
            sPath = objSC.TargetPath  
            For Each strItem In arrList
                lCompare = 0
                bMatch = False
                If Left(strItem,1)="%" Then lCompare = lCompare or 1
                If Right(strItem,1)="%" Then lCompare = lCompare or 2
                Select Case lCompare
                Case 0
                    bMatch = (StrComp(objProcess.Name, strItem, vbTextCompare) = 0) Or (StrComp(sPath, strItem, vbTextCompare) = 0)
                Case 1
                    bMatch = (StrComp(right(objProcess.Name, Len(strItem)-1), Mid(strItem,2), vbTextCompare) = 0) Or (StrComp(right(sPath, Len(strItem)-1), Mid(strItem,2), vbTextCompare) = 0)  
                Case 2
                    bMatch = (StrComp(left(objProcess.Name, Len(strItem)-1), Left(strItem,Len(strItem)-1), vbTextCompare) = 0) Or (StrComp(left(sPath, Len(strItem)-1), Left(strItem,Len(strItem)-1), vbTextCompare) = 0)  
                Case 3
                    bMatch = (Instr(1, lcase(objProcess.Name), LCase(Mid(strItem, 2, Len(strItem)-2))) > 0) Or (Instr(1, lcase(sPath), LCase(Mid(strItem, 2, Len(strItem)-2))) > 0) 
                End Select
                If bMatch Then
                    If strProcesses <> "" Then strProcesses = strProcesses & ", "
                    strProcesses = strProcesses & UCase(objProcess.Name)
                    Exit For
                End If
            Next
        Next
        If strProcesses <> "" Then
            If Not bAskUser Or Not ShowNotifications() Then
                If lCount = 10 Then Exit Sub
                For Each objProcess In colProcesses
                    If Instr(1, ", " & strProcesses & ", ", ", " & ucase(objProcess.Name) & ", ") > 0 Then
                        Call objProcess.Terminate(0)        
                    End If
                Next
                lCount = lCount + 1
                WScript.Sleep 2000
            ElseIf bTerminate Then
                Select Case intOsLang
                Case 1053 ' Swedish
                    strText = "Följande program körs fortfarande:" & vbNewLine & vbNewLine & strProcesses & vbNewLine & vbNewLine & _
                              "Vill du att installationsprogrammet ska avsluta dessa program?" & vbNewLine & vbNewLine & _
                              "VARNING: Detta kan resultera i dataförlust då program avslutas utan meddelande om att spara öppna dokument!"
                Case Else ' Default: English
                    strText = "The following programs are still running:" & vbNewLine & vbNewLine & strProcesses & vbNewLine & vbNewLine & _
                              "Do you want setup to terminate the programs for you?" & vbNewLine & vbNewLine & _
                              "WARNING: This may result in loss of data as the programs will be terminated immediately without saving any open documents!"
                End Select
                If MsgBox(strText, vbYesNo Or vbCritical Or vbDefaultButton2, strTitle) = vbYes Then
                    For Each objProcess In colProcesses
                        If Instr(1, ", " & strProcesses & ", ", ", " & ucase(objProcess.Name) & ", ") > 0 Then
                            Call objProcess.Terminate(0)        
                        End If
                    Next
                    WScript.Sleep 2000
                End If
                bTerminate = False
            Else
                Select Case intOsLang
                Case 1053 ' Swedish
                    strText = strTitle & " kan inte fortsätta medan följande program körs:" & vbNewLine & vbNewLine & strProcesses & _
                              vbNewLine & vbNewLine & "Vänligen stäng ovanstående program före du fortsätter!"
                Case Else ' Default: English
                    strText = strTitle & " cannot continue while the following programs are running:" & vbNewLine & vbNewLine & strProcesses & _
                              vbNewLine & vbNewLine & "Please close the above programs before continuing!"
                End Select
                MsgBox strText, vbOKOnly Or vbExclamation, strTitle
                bTerminate = True
            End If
        End If
    Loop Until strProcesses = ""
End Sub

Sub PerformSetupAction()
    Dim InstallCmd
    Dim X
    on error resume next
    If SetupFile = "" Then Exit Sub
    Call IntermediateSetupAction(0)
    If SMSError <> 0 Then
        LogError "Error " & SMSError & " in module IntermediateSetupAction - execution halted!", "PerformSetupAction"
        Exit Sub
    End If
    For X = 1 To UBound(Split("|" & SetupFile, "|"))
        If bSkipNext Or bSkipAll Then
            bSkipNext = False
        Else
            InstallCmd = """" & MediaFolder & "\" & Split("|" & SetupFile, "|")(X) & """"
            If Split("|" & MSTFile, "|")(X) <> "" Then
                InstallCmd = InstallCmd & " TRANSFORMS=""" & MSTFolder & "\" & Split("|" & MSTFile, "|")(X) & """"
            End If
            InstallCmd = InstallCmd & " " & Split("|" & CmdArgs, "|")(X)
            WSHShell.CurrentDirectory = MediaFolder
            Err.Clear
            SMSError = WSHShell.Run(InstallCmd, 1, True)
            If SMSError = 0 Then SMSError = Err.Number
            If SMSError = ERROR_SUCCESS_REBOOT_REQUIRED Then 
                SMSError = 0
                bRebootReq = True
            End If
            If Instr(1, "," & AcceptRC & ",", "," & cstr(SMSError) & ",") > 0 Then SMSError = 0
            If SMSError = 0 Then 
                LogInfo "Successfully executed command: " & InstallCmd, "PerformSetupAction"
            Else
                LogError "Error " & SMSError & " executing command: " & InstallCmd & vbNewLine & vbNewLine & "Execution halted!", "PerformSetupAction"
                Exit For
            End If
        End If
        Call IntermediateSetupAction(X)
        If SMSError <> 0 Then
            LogError "Error " & SMSError & " in module IntermediateSetupAction - execution halted!", "PerformSetupAction"
            Exit For
        End If
    Next
End Sub

Sub SecEdit(Template)
    Dim Database
    Dim InfFile
    On Error Resume Next
    Database = FSO.GetSpecialFolder(0) & "\Security\Database\" & Split(Product, "|")(UBound(Split(Product, "|"))) & ".sdb"
    FSO.DeleteFile Database, True
    InfFile = InfFolder & "\" & Template
    SMSError = WSHShell.Run("secedit /configure /db """ & Database & """ /Cfg """ & InfFile & """ /areas REGKEYS FILESTORE /quiet", 1, True)
    If SMSError = 3 And OS64bit() Then
        ' Clear error that occurs when using SecEdit on a 64 bit client to set permissions on the 32 bit registry hive
        SMSError = 0
    ElseIf SMSError <> 0 Then
        LogError "Error " & SMSError & " applying security template: " & Template & vbNewLine & vbNewLine & "Execution halted!", "SecEdit"
    End If
End Sub

Sub ShowProgress()
    Call ShowProgressW7(ApplicationName)
End Sub

Sub ShowProgressW7(ApplicationName)
    Dim strTempFile
    strTempFile = WSHShell.ExpandEnvironmentStrings("%TEMP%\showprogress.ps1")
    Set objStream = FSO.CreateTextFile(strTempFile, True)
    objStream.WriteLine "[void][System.Reflection.Assembly]::LoadWithPartialName(""System.Windows.Forms"")"
    objStream.WriteLine "[void][System.Reflection.Assembly]::LoadWithPartialName(""System.Drawing"")"
    objStream.WriteLine "$Form1 = New-Object System.Windows.Forms.Form"
    objStream.WriteLine "$Form1.ClientSize = New-Object System.Drawing.Size(480, 100)"
    objStream.WriteLine "$Form1.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen"
    objStream.WriteLine "$Form1.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog"
    objStream.WriteLine "$Form1.MaximizeBox = $FALSE"
    objStream.WriteLine "$Form1.TopMost = $TRUE"
    objStream.WriteLine "$Form1.add_FormClosing([System.Windows.Forms.FormClosingEventHandler]{$_.Cancel=$true;$form1.windowstate=[System.Windows.Forms.FormWindowState]::minimized})"
    objStream.WriteLine "$Label1 = New-Object System.Windows.Forms.Label"
    objStream.WriteLine "$Label1.Location = New-Object System.Drawing.Point(20, 20)"
    objStream.WriteLine "$Label1.Size = New-Object System.Drawing.Size(440, 40)"
    If ApplicationName = "" Then
        Select Case GetOsLanguageId()
        Case 1053 ' Swedish
            objStream.WriteLine "$Form1.Text = ""Installation pågår..."""
            objStream.WriteLine "$Label1.Text = ""Vänta medan Windows konfigurerar din applikation..."""
        Case Else ' Default: English
            objStream.WriteLine "$Form1.Text = ""Installation in progress"""
            objStream.WriteLine "$Label1.Text = ""Please wait while Windows configures your application..."""
        End Select
    Else
        objStream.WriteLine "$Form1.Text = """ & ApplicationName & """"
        Select Case GetOsLanguageId()
        Case 1053 ' Swedish
            objStream.WriteLine "$Label1.Text = ""Vänta medan Windows konfigurerar " & ApplicationName & "..."""
        Case Else ' Default: English
            objStream.WriteLine "$Label1.Text = ""Please wait while Windows configures " & ApplicationName & "..."""
        End Select
    End If
    objStream.WriteLine "$ProgressBar1 = New-Object System.Windows.Forms.ProgressBar"
    objStream.WriteLine "$ProgressBar1.Location = New-Object System.Drawing.Point(20, 60)"
    objStream.WriteLine "$ProgressBar1.Size = New-Object System.Drawing.Size(440, 20)"
    objStream.WriteLine "$ProgressBar1.Style = [System.Windows.Forms.ProgressBarStyle]::Marquee"
    objStream.WriteLine "$ProgressBar1.MarqueeAnimationSpeed = 30"
    objStream.WriteLine "$Timer1 = New-Object System.Windows.Forms.Timer"
    objStream.WriteLine "$Timer1.Enabled = $TRUE"
    objStream.WriteLine "$Timer1.Interval = 1000"
    objStream.WriteLine "$Timer1.add_tick({$p = get-wmiobject win32_process -filter ""name='powershell.exe'"";$pp = get-process | where-object {$_.Id -eq $p.parentprocessid};if ($pp -eq $NULL) {$Form1.dispose()}})"
    objStream.WriteLine "$Form1.Controls.Add($Label1)"
    objStream.WriteLine "$Form1.Controls.Add($ProgressBar1)"
    objStream.WriteLine "$Form1.BringToFront()"
    objStream.WriteLine "[System.Windows.Forms.Application]::EnableVisualStyles()"
    objStream.WriteLine "[System.Windows.Forms.Application]::Run($Form1)"
    objStream.Close
    WSHShell.Run "powershell.exe -executionpolicy remotesigned -windowstyle hidden -file """ & strTempFile & """", 0, False
End Sub

Function OS64bit()
    OS64bit = WSHShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%") <> "x86" Or WSHShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITEW6432%") <> "%PROCESSOR_ARCHITEW6432%"
End Function

Function OSVersion()
    Dim objLocator, objWMI, colItems, objItem
    On Error Resume Next
    Set objLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objWMI = objLocator.ConnectServer(".", "root\CIMV2", "", "")
    Set colItems = objWMI.ExecQuery("Select Version from Win32_OperatingSystem", , 48)
    For Each objItem in colItems
        OSVersion = objItem.Version
        Exit For
    Next
End Function

Sub SkipNext()
    bSkipNext = True
    bSkipAll = False
End Sub

Sub SkipAll()
    bSkipNext = False
    bSkipAll = True
End Sub

Function ProgramFiles32()
    If WSHShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%") = "x86" Then
        ProgramFiles32 = GetSpecialFolder("PROGRAMFILES")
    Else
        ProgramFiles32 = GetSpecialFolder("PROGRAMFILESX86")
    End If
End Function    

Function ProgramFiles64()
    If WSHShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITEW6432%") = "%PROCESSOR_ARCHITEW6432%" Then
        ProgramFiles64 = GetSpecialFolder("PROGRAMFILES")
    Else
        ProgramFiles64 = WSHShell.ExpandEnvironmentStrings("%ProgramW6432%")
    End If
End Function

Function ShowNotifications()
    Select Case UCase(CustomerFolderName)
    Case "STOSTAD"
        ShowNotifications = UserLoggedOn()
    Case Else 
        ShowNotifications = UserLoggedOn() And PrgNotifications()
    End Select
End Function

Function PrgNotifications()
    Dim oWMIService, colPolicies, oPolicy
    PrgNotifications = True
    On Error Resume Next
    Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}\\.\root\ccm\policy\machine\requestedconfig")
    Set colPolicies = oWMIService.ExecQuery("Select PRG_PRF_RunNotification from CCM_SoftwareDistributionClientConfig where PolicySource = 'Local'")
    For Each oPolicy in colPolicies 
        If Not oPolicy.PRG_PRF_RunNotification Then
            PrgNotifications = False
            Exit Function
        End If
    Next
    If Err.Number <> 0 Then Err.Clear
    On Error Goto 0
End Function

Function UserLoggedOn()
If (Split(OSVersion(),".")(0) ="10") Then
	UserloggedOn = UserloggedonW10()
Else
	UserloggedOn = UserloggedonW7()
End if
End Function

Function UserLoggedOnW7()
    Dim oWMIService, colSessions
    Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")    
    Set colSessions = oWMIService.ExecQuery("Select LogonId From Win32_LogonSession Where LogonType = 2 Or LogonType = 10 Or LogonType = 11 Or LogonType = 12")
    UserLoggedOnW7 = colSessions.Count > 0
End Function

Function UserLoggedOnW10()
    Dim oWMIService, colSessions
    Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")    
    Set colSessions = oWMIService.ExecQuery("Select username From Win32_computerSystem where username is NOT NULL")
    UserloggedonW10 = colSessions.count > 0
End Function

Function GetSpecialFolder(FolderID)
    Dim Shell
    Set Shell = CreateObject("Shell.Application")
    Select Case UCase(FolderID)
    Case "APPDATA":    ' <user name>\Application Data (%appdata%)
        GetSpecialFolder = Shell.NameSpace(26).Self.Path 
    Case "COMMONAPPDATA": ' All Users\Application Data
        GetSpecialFolder = Shell.NameSpace(35).Self.Path
    Case "COMMONDESKTOP": ' All Users\Desktop
        GetSpecialFolder = Shell.NameSpace(25).Self.Path
    Case "COMMONFAVORITES": ' All Users\Favorites
        GetSpecialFolder = Shell.NameSpace(31).Self.Path
    Case "COMMONPROGRAMS": ' All Users\Start Menu\Programs
        GetSpecialFolder = Shell.NameSpace(23).Self.Path
    Case "COMMONSTARTMENU": ' All Users\Start Menu
        GetSpecialFolder = Shell.NameSpace(22).Self.Path
    Case "COMMONSTARTUP": ' All Users\Start Menu\Programs\Startup
        GetSpecialFolder = Shell.NameSpace(24).Self.Path
    Case "DESKTOP": ' <user name>\Desktop
        GetSpecialFolder = Shell.NameSpace(16).Self.Path
    Case "FAVORITES": ' <user name>\Favorites
        GetSpecialFolder = Shell.NameSpace(6).Self.Path
    Case "FONTS": ' Windows\fonts
        GetSpecialFolder = Shell.NameSpace(20).Self.Path
    Case "HISTORY": ' <user name>\Local Settings\History
        GetSpecialFolder = Shell.NameSpace(34).Self.Path
    Case "INTERNETCACHE": ' <user name>\Local Settings\Temporary Internet Files
        GetSpecialFolder = Shell.NameSpace(32).Self.Path
    Case "LOCALAPPDATA": ' <user name>\Local Settings\Application Data
        GetSpecialFolder = Shell.NameSpace(28).Self.Path
    Case "MYDOCUMENTS": ' <user name>\My Documents
        GetSpecialFolder = Shell.NameSpace(5).Self.Path
    Case "MYPICTURES": ' <user name>\My Documents\My Pictures
        GetSpecialFolder = Shell.NameSpace(39).Self.Path
    Case "USERPROFILE": ' <user name> (%userprofile%)
        GetSpecialFolder = Shell.NameSpace(40).Self.Path
    Case "PROGRAMFILES": ' C:\Program Files
        GetSpecialFolder = Shell.NameSpace(38).Self.Path
    Case "PROGRAMS": ' <user name>\Start Menu\Programs
        GetSpecialFolder = Shell.NameSpace(2).Self.Path
    Case "RECENT": ' <user name>\Recent
        GetSpecialFolder = Shell.NameSpace(8).Self.Path
    Case "SENDTO": ' <user name>\SendTo
        GetSpecialFolder = Shell.NameSpace(9).Self.Path
    Case "STARTMENU": ' <user name>\Start Menu
        GetSpecialFolder = Shell.NameSpace(11).Self.Path
    Case "STARTUP": ' <user name>\Start Menu\Programs\Startup
        GetSpecialFolder = Shell.NameSpace(7).Self.Path
    Case "SYSTEM": ' C:\Windows\system32
        GetSpecialFolder = Shell.NameSpace(37).Self.Path
    Case "TEMPLATES": ' <user name>\Templates
        GetSpecialFolder = Shell.NameSpace(21).Self.Path    
    Case "WINDOWS": ' C:\Windows
        GetSpecialFolder = Shell.NameSpace(36).Self.Path
    Case "PROGRAMFILESX86": ' C:\Program Files (x86) (only on x64)
        GetSpecialFolder = Shell.NameSpace(42).Self.Path
    Case "PROGRAMFILES_COMMON": ' C:\Program Files\Common
        GetSpecialFolder = Shell.NameSpace(43).Self.Path
    Case "PROGRAMFILES_COMMONX86": ' C:\Program Files (x86)\Common (only on x64)
        GetSpecialFolder = Shell.NameSpace(44).Self.Path
    End Select        
    Set Shell = Nothing
End Function

Function GetOsLanguageId()
    Dim oWMIService, colItems, oItem
    Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")    
    Set colItems = oWMIService.ExecQuery("Select OSLanguage From Win32_OperatingSystem")
    For Each oItem in colItems
        GetOsLanguageId = oItem.OSLanguage
    Next
End Function

Function RebootRequired()
    RebootRequired = bRebootReq
End Function

Sub LogInfo(Message, Module)
    WSHShell.LogEvent 0, Message & vbNewLine & vbNewLine & "Script: " & WScript.ScriptFullName & vbNewLine & "Module: " & Module
End Sub

Sub LogError(Message, Module)
    WSHShell.LogEvent 1, Message & vbNewLine & vbNewLine & "Script: " & WScript.ScriptFullName & vbNewLine & "Module: " & Module
End Sub

Sub LogWarning(Message, Module)
    WSHShell.LogEvent 2, Message & vbNewLine & vbNewLine & "Script: " & WScript.ScriptFullName & vbNewLine & "Module: " & Module
End Sub

'//END TEMPLATE
