I am new to packaging and scripting so please excuse me if I don't understand everything. I hope I have posted to the correct board. I have a script that I am trying to run under Altiris. The intent is to check for the presence of Serena VM, uninstall the previous version (if installed) and then install a newer version. I have tested this script manually on five PCs (double clicking on the VBS file name and also by typing a cscript command from a command window). All five PCs are running Win XP SP3; it works correctly on all five PCs. I then deployed the script with Altiris; it runs correctly on four of the five PCs. A cscript window opens, it kicks off the uninstall of the previous version which uninstalls correctly. It then proceeds to install the new version which also appears to install correctly. On four of the five test PCs, the cscript window closes and from an Altiris perspective, the package installed correctly. On the fifth PC, the cscript window that opens stays open and does not close. Consequently the task times out on Altiris and the package appears to fail.

The command line from Altiris is cscript.exe "Serena_Version_Manager_8.2.1.382_Install.vbs" . I have the package setup to run under the system account regardless if a user is logged on or not. I'll copy the script below for reference. I've checked the patch level of the cscript on the fifth PC; it is version 5.7.0.18066 which matches the other four PCs. If there is a scripting error, I'd like to know it as I can't deploy this package if it doesn't work. BTW, the WritetoLogFile just before the Wscript.Quit command appears in the log file but the window doesn't close. Any ideas?

'-----------------------------------------------------------------------------------------------------------
'COMMON VARIABLES
'-----------------------------------------------------------------------------------------------------------
On Error Resume Next
Dim objFSO, WshShell
Dim SourceFolder
Dim VBSLogFileName,n
Dim InstallCmds(50,2)
'
' Following are for uninstalling previous version of Serena VM
'
dim regKeyType : regKeyType = "HKLM"
dim regKey : regKey = "SOFTWARE"
dim regSubKey : regSubKey = "Serena VM Web Client"
dim regKeyValueName : regKeyValueName = "CurrentVersion"
dim regKeyValueHolder : regKeyValueHolder = "?"
Dim z : z = "Maybe"
Public CmdLine, StatusCmdLine, ProductCode, IgnoreError,AppVendorName,Application_Name,AppVersion,LogFilePath
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("wscript.shell")
SourceFolder = objFSO.GetParentFolderName(WScript.ScriptFullName)
AppVendorName = "Serena"
ApplicationName = "Version_Manager"
AppVersion = "8.2.1.382"
VBSLogFileName = GetDir() & "\" & AppVendorname & "_" & ApplicationName & "_" & AppVersion & "_" & "_VBS_Install.log"
MSILogFileName = GetDir() & "\" & AppVendorname & "_" & ApplicationName & "_" & AppVersion & "_" & "_MSI_Install.log"
WI_Buildlog = WshShell.ExpandEnvironmentStrings("%windir%") & "\_WI\Buildlogs\WI_Master_Build.log"
ProductCode = ""
'Change to 'False' if you want the commands to run even if the MSI has already been installed
CheckProductCode = False
'-----------------------------------------------------------------------------------------------------------
'INSTALL COMMANDS TO BE MODIFIED
'-----------------------------------------------------------------------------------------------------------
n = 0 'Initialize counter.
' Run Install Commands
n = n + 1
InstallCmds(n,0) = Chr(34) & SourceFolder & "\Setup\vmwebclient.exe" & Chr(34)
InstallCmds(n,1) = False 'Run this script as a detached process
InstallCmds(n,2) = False 'Ignore script exit/return code
'n = n + 1
'InstallCmds(n,0) = Chr(34) & SourceFolder & "\Setup\<RunAnotherInstallOrScript" & Chr(34)
'InstallCmds(n,1) = False 'Run this script as a detached process
'InstallCmds(n,2) = False 'Ignore script exit/return code
'-----------------------------------------------------------------------------------------------------------
' MAIN
'-----------------------------------------------------------------------------------------------------------
' Delete Previous Log file
If objFSO.FileExists(VBSLogFileName) Then objFSO.DeleteFile(VBSLogFileName)
WritetoLogFile "-----------------------------------------------------------------------------------------------------------"
If DoesRegistryKeyExist(regKeyType, regKey, regSubKey) = True Then
z = "True"
WritetoLogFile "Existing release found. Registry key=" & regKeyType & "\" & regKey & "\" & regSubKey
If DoesRegistryValueExist(regKeyType, regKey & "\" & regSubKey, regKeyValueName, regKeyValueHolder) = True then
WritetoLogFile " Release Information=" & regKeyType & "\" & regKey & "\" & regSubKey & "\" & regKeyValueName & " = " & regKeyValueHolder
Else
WritetoLogFile " Unable to determine existing release; continuing with uninstallation"
End If
If mid(regKeyValueHolder,1,4) = "8,1," Then
CmdLine = Chr(34) & SourceFolder & "\Setup\8.1.1.900\Uninstall.exe" & Chr(34)
' WritetoLogFile = "uninstall command line = " & CmdLine
Else
CmdLine = Chr(34) & SourceFolder & "\Setup\Uninstall.exe" & Chr(34)
End If
WritetoLogFile = "...Uninstall command line = " & CmdLine
ReturnCode = WshShell.Run(CmdLine, 0, Wait)
WritetoLogFile " RETURN CODE after attempting uninstallation: " & ReturnCode
Else
z = "False"
WritetoLogFile "No existing release of Serena Version Manager found. Continuing with installation."
End If
Do Until (z = "False")
If DoesRegistryKeyExist(regKeyType, regKey, regSubKey) = False then z = "False"
WritetoLogFile "...Waiting one second for registry key to be deleted from uninstallation process..."
wscript.sleep (1000)
Loop
'Executing Actions...
If CheckProductCode = False Then
Execute_Installation
Else
RegValue = WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & ProductCode & "\UninstallString")
If InStr(ucase(RegValue), ucase(ProductCode)) Then
WritetoLogFile "MSI Product Code " & ProductCode & " found. Exiting install."
WScript.Quit(0)
Else
WritetoLogFile "MSI Product Code " & ProductCode & " not found. Continuing installation"
Execute_Installation
End If
End If
WritetoLogFile "Installation should be complete. Issuing Wscript.Quit command"
WScript.Quit

'-----------------------------------------------------------------------------------------------------------
' EXECUTE INSTALLATION
'-----------------------------------------------------------------------------------------------------------
Function Execute_Installation()
On Error Resume Next
Dim ReturnCode, Wait, RegKey, ProductName
For x = 1 to UBound(InstallCmds)
If InstallCmds(x,0) <> "" Then
ReturnCode = 0
Wait = True
CmdLine = InstallCmds(x,0)
StatusCmdLine = Replace(CmdLine,"""","")
If InstallCmds(x,1) = True Then Wait = False
IgnoreError = InstallCmds(x,2)
WritetoLogFile "-----------------------------------------------------------------------------------------------------------"
WritetoLogFile "Executing Command Line String: " & CmdLine
ReturnCode = WshShell.Run(CmdLine, 0, Wait)
WritetoLogFile " RETURN CODE after EXECUTION : " & ReturnCode

'Checking for Action Errors
If IgnoreError = False Then
If ReturnCode <> 0 And ReturnCode <> 3010 Then
WritetoLogFile " IgnoreError set to 'False'. Exiting the install with a state of 'Failed'."
WritetoLogFile "-----------------------------------------------------------------------------------------------------------"
WritetoMasterLogFile AppVendorname & " " & ApplicationName & " " & AppVersion & " installed UNSUCCESSFUL with exit code of " & ReturnCode
WScript.Quit(1)
Else
WritetoMasterLogFile AppVendorname & " " & ApplicationName & " " & AppVersion & " installed successfully with exit code of " & ReturnCode
End If

End If
WritetoLogFile "-----------------------------------------------------------------------------------------------------------"
Else
Exit For
End If
Next
End Function
'-----------------------------------------------------------------------------------------------------------
' CHECK FOR LOG DIR
'-----------------------------------------------------------------------------------------------------------
Function GetDir()
On Error Resume Next
WindowsDir = WshShell.ExpandEnvironmentStrings("%windir%")
Dir01 = "\_WI" : Dir02 = "\BuildLogs" : Dir03 = "\Apps" : Dir04 = "\" & AppVendorname & "_" & ApplicationName & "_" & AppVersion

If Not objFSO.FolderExists(WindowsDir & Dir01) Then objFSO.CreateFolder(WindowsDir & Dir01) End If
If Not objFSO.FolderExists(WindowsDir & Dir01 & Dir02) Then objFSO.CreateFolder(WindowsDir & Dir01 & Dir02) End If
If Not objFSO.FolderExists(WindowsDir & Dir01 & Dir02 & Dir03) Then objFSO.CreateFolder(WindowsDir & Dir01 & Dir02 & Dir03) End If
If Not objFSO.FolderExists(WindowsDir & Dir01 & Dir02 & Dir03 & Dir04) Then objFSO.CreateFolder(WindowsDir & Dir01 & Dir02 & Dir03 & Dir04) End If
GetDir = WindowsDir & Dir01 & Dir02 & Dir03 & Dir04
End Function
'-----------------------------------------------------------------------------------------------------------
' WRITE TO LOG FILE
'-----------------------------------------------------------------------------------------------------------
Function WritetoLogFile(LogString)
On Error Resume Next
Dim FormatedLogLineString : Dim NewFolderName
FormatedLogLineString = Now & " | " & LogString
If objFSO.FileExists(VBSLogFileName) Then
Set objTextFile = objFSO.OpenTextFile(VBSLogFileName , ForAppending, True)
objTextFile.WriteLine(FormatedLogLineString)
objTextFile.close
Else
Set objFile = objFSO.CreateTextFile(VBSLogFileName)
objFile.WriteLine(FormatedLogLineString)
objFile.close
End If
End Function
'-----------------------------------------------------------------------------------------------------------
' WRITE TO MASTER LOG FILE
'-----------------------------------------------------------------------------------------------------------
Function WritetoMasterLogFile(LogString)
On Error Resume Next
Dim FormatedLogLineString : Dim NewFolderName
FormatedLogLineString = Now & " | " & LogString
If objFSO.FileExists(WI_Buildlog) Then
Set objTextFile = objFSO.OpenTextFile(WI_Buildlog , ForAppending, True)
objTextFile.WriteLine(FormatedLogLineString)
objTextFile.close
Else
Set objFile = objFSO.CreateTextFile(WI_Buildlog)
objFile.WriteLine(FormatedLogLineString)
objFile.close
End If
End Function
Function DoesRegistryKeyExist(LNGHKEY, strKey, strSubkey)
Const HKCR = &H80000000
Const HKCU = &H80000001
Const HKLM = &H80000002
Const HKUSERS = &H80000003
DoesRegistryKeyExist = False
Dim reg, aSubkeys, s, hkroot
If LNGHKEY = "HKLM" Then hkRoot = HKLM
If LNGHKEY = "HKCU" Then hkRoot = HKCU
If LNGHKEY = "HKCR" Then hkRoot = HKCR
If LNGHKEY = "HKUSERS" Then hkRoot = HKUSERS
Set reg = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
reg.EnumKey hkroot, strKey, aSubkeys
If Not IsNull(aSubkeys) Then
For Each s In aSubkeys
If lcase(s)=lcase(strSubkey) Then
DoesRegistryKeyExist = True
Exit Function
End If
Next
End If
End Function
Function DoesRegistryValueExist(LNGHKEY, strKeyPath, strKeyValueName, strKeyValue)
Const HKCR = &H80000000
Const HKCU = &H80000001
Const HKLM = &H80000002
Const HKUSERS = &H80000003
const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
const REG_MULTI_SZ = 7
DoesRegistryValueExist = False
strKeyValue = ""
Dim reg, s, hkroot, arrValueNames, arrValueTypes, i

If LNGHKEY = "HKLM" Then hkRoot = HKLM
If LNGHKEY = "HKCU" Then hkRoot = HKCU
If LNGHKEY = "HKCR" Then hkRoot = HKCR
If LNGHKEY = "HKUSERS" Then hkRoot = HKUSERS
Set objReg = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
objReg.EnumValues hkroot, strKeyPath, arrValueNames, arrValueTypes
If Not IsNull(aSubkeys) Then
For i = 0 to uBound(arrValueNames)
If arrValueNames(i) = strKeyValueName Then
DoesRegistryValueExist = True
Select Case arrValueTypes(i)
Case REG_SZ
objReg.GetStringValue hkroot,strKeyPath,arrValueNames(i),strKeyValue
Case REG_EXPAND_SZ
objReg.GetExpandedStringValue hkroot,strKeyPath,arrValueNames(i),strKeyValue
Case REG_BINARY
objReg.GetBinaryValue hkroot,strKeyPath,arrValueNames(i),strKeyValue
Case REG_DWORD
objReg.GetDWORDValue hkroot,strKeyPath,arrValueNames(i),strKeyValue
Case REG_MULTI_SZ
objReg.GetMultiStringValue hkroot,strKeyPath,arrValueNames(i),arrMultiStringValues
For Each strKeyValue In arrMultiStringValues
x = strKeyValue
Next
End Select
End If
Next
End If
End Function
0 Comments   [ + ] Show Comments

Comments

Please log in to comment

Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.

Answers

0
I hope I have posted to the correct boardNope! :) There is a 'Scripting' forum, here. A moderator may move the thread.

I don't know Altiris at all but have you tried explicitly setting the script's return value by using 'WScript.Quit(True)' instead of just 'WScript.Quit'?

The code could do with some tidying. For example, you have defined some routines as functions but don't use them as functions: they don't return any value. To avoid the many WScript.Quit statements, consider setting the function's return value to 'False' (or better, DON'T set it to True) and then test that value in the main section. For example:blnReturn = SomeFunction(strSomeValue)

If Not blnReturn Then
'// Show error message
WScript.Quit(False)
End If

WScript.Quit(True)

Function SomeFunction(ByVal strValue)
Dim strSomeOtherValue

SomeFunction = False

strSomeOtherValue = DoSomeManipulationOrOther

If strSomeOtherValue <> strSomeValue Then
Exit Function
End If
End Function


Also, avoid code repetition where possible. For example, you could declare your registry hive values as global constants, rather than in each function that uses them. Better yet, get hold of the registry class file from JSWare. It abstracts the WMI registry provider into a neat set of functions. Definitely one for the library. Similarly, the log file details would perhaps be better as globals.

On the same point, consider tidying up things like "----------------------------------------------------------------" with 'String(40, "-")' or, better, used as a global variable:Const strSeparator = String(40, "-")

Although very much a personal thing, and even given that VBScript's default data type is a Variant which it coerces into what it thinks is the actual data type, you may want to begin using a prefix which indicates the variable's data type, as in the above example which uses 'str' to indicate that 'strSeparator' is a string. It helps to avoid coding errors where you might try comparing a string to an integer.
BTW, there is a 'CODE' tag which should be used for, er, code posts and for other lengthy texts.
Answered 12/30/2009 by: VBScab
Red Belt

Please log in to comment
0
Thanks for the coding tips, VBScab. A lot of this is cobbled together from scripts a consultant left behind plus other things I've picked up along the way in the past couple of months. I will take a few minutes to clean it up.

I downloaded procexp.exe to get a view of what was executing before I started the package install plus a view of what was running once the install completed (but with the cscript window still open as above). The only additional tasks that showed up were wmiprvse.exe and cscript.exe. Once I closed the cscript window both tasks went away.

I compared the versions of wmiprvse.exe and cscript.exe with the versions on the other four PCs; they are identical. That is what has me baffled. I hesitate to re-image the machine as it is a machine belonging to my power-user of Serena. If any other PCs are out there with the same problem, the re-image would only mask the issue. This package will have to deploy to over 200 users; that is what has got me scratching my head.
Answered 12/30/2009 by: dadman53
Senior Yellow Belt

Please log in to comment
0
Did you change the 'WScript'Quit' statement to see if that fixes the problem?
Answered 12/31/2009 by: VBScab
Red Belt

Please log in to comment
0
Tried that... didn't help.
Answered 12/31/2009 by: dadman53
Senior Yellow Belt

Please log in to comment
2
I find that typically, when a script times out in a deployment scenario, it's because a prompt has shown up on the target machine (which will be in the system account, which means you probably won't be able to see it,) and is waiting for a response before it will continue. I also notice that you're running several executables, but have not disabled security zone checks in the script. It could well be that your first four machines had different security configurations than the fifth.

Try adding the following code to the beginning of your script to turn off zone checking:

Set objEnv = objShell.Environment("PROCESS")
objEnv("SEE_MASK_NOZONECHECKS") = 1


and this line at the end to turn it back on:

objEnv.Remove("SEE_MASK_NOZONECHECKS")


I didn't look through everything in detail, but that's the first thing that jumped out at me that could be going wrong.
Answered 01/04/2010 by: Jsaylor
Second Degree Blue Belt

Please log in to comment
0
Jsaylor... thanks for the tip. Unfortunately it didn't help. I added it at these statements just after the initial Dim statements:

Set objShell = CreateObject("WScript.Shell")
Set objEnv = objShell.Environment("PROCESS")
objEnv("SEE_MASK_NOZONECHECKS") = 1

and then added

objEnv.Remove("SEE_MASK_NOZONECHECKS")

immediately prior to the Wscript.Quit(True). Task manager shows I still have an extra Wscript.exe running after the script comes to an end.
Answered 01/05/2010 by: dadman53
Senior Yellow Belt

Please log in to comment
0
Another thing I found... I added some debugging logic. At the beginning of the script I added logic to capture all active processes where the processname = "wscript.exe". I write the process name, process ID, process owner, and command line to the log file. Then just in front of the Wscript.Quit(True) I inserted the same statements. When I ran the script I found that the only occurence of wscript.exe that showed up in the process list was this particular script. What baffles me is that even after the wscript.quit command is issued and the script appears to end, the same process ID shows up in task manager. I had thought that maybe it was spawning another wscript.exe somewhere along the way but that is not the case. When I changed the code to call another VBS script to perform the uninstall of the previous version and a second script to install the new version (instead of executing the exe directly) those scripts ended successfully but left the main one still showing up in the task manager. I've even put in wscript.echo commands after the wscript.quit(true) command to see if the script is indeed ending at the wscript.quit. The echos are never executed. I am at a loss to explain it.
Answered 01/05/2010 by: dadman53
Senior Yellow Belt

Please log in to comment
0
You're just never getting to wscript.quit, something along the line is hanging. Asides from analyzing every single line and guessing what might be going wrong, you could try to add an echo (they need to be distinct, but it can be as simple as numbers, wscript.echo "1", wscript.echo "2", etc...) to each if/then block. Then when you run the script, you can click through the script one echo at a time until you get to the point where nothing happens anymore.

Then you've at least narrowed it down to between lines X and X.

EDIT: Also, whoops, for some reason I thought your shell object was called objshell, that's why we don't post suggestions without sleep folks!
Answered 01/05/2010 by: Jsaylor
Second Degree Blue Belt

Please log in to comment
0
Early on I tried the echo immediately before the Wscript.Quit... even used my WritetoLogFile immediately before the Wscript.Quit. I know I am making it to the statement immediately before the quit. I've even put in an echo immediately after the quit and it doesn't get executed. I am really beginning to wonder what might be wrong the PC SW. As I stated above, this script works successfully on 4 out of 5 PCs. I've spent a lot of time on this and am beginning to wonder if it is worth it.

Just for grins I added the following in front of the quit.

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = 'wscript.exe'")
For Each objProcess in colProcessList
objProcess.Terminate()
Next

That works, but I really hate using a sledge hammer to fix this.
Answered 01/06/2010 by: dadman53
Senior Yellow Belt

Please log in to comment
0
If you can be sure you're making it to the quit statement, (IE, add an echo before it, echo displays,) then have you tried turning off "on error resume next"? You can turn it off by adding "On error goto 0" just before the quit statement, that will let you see if it's throwing an error. It could be that there's some shenanigans with the WSH engine on that PC.
Answered 01/06/2010 by: Jsaylor
Second Degree Blue Belt

Please log in to comment
0
Alright, here's what I did. I inserted the following:

WScript.Echo ("Getting ready to burp")
On Error Goto 0
burp
WScript.Quit(True)

I get the echo pop-up. I click OK to continue. Then I get the expected pop-up from Windows Script Host for a Type Mismatch: "burp". I click OK. But wscript.exe is still active in the task manager. Any other machine I try this on, wscript.exe goes away after clicking OK. But not this one machine. All machines (including the failing one) have wscript.exe at version 5.7.0.18066, size=155,648, and a modified date of May 8, 2008 @ 6:24:44 AM.

Any other ideas?
Answered 01/06/2010 by: dadman53
Senior Yellow Belt

Please log in to comment
0
I assume you also tried it without an obviously bad line before the wscript call? I was leaning towards wscript failing to instantiate the quit method for whatever reason.

Other than that, try reregistering the script engine maybe?

"regsvr32 scrrun.dll" from a command prompt.

You may also consider feeding the machine in question into a wood chipper.
Answered 01/06/2010 by: Jsaylor
Second Degree Blue Belt

Please log in to comment
0
In all functions I put in "on error resume next" then just before each end function statement I added "if err.number <> 0 then wscript.echo ("function name " & err.number)". It didn't kick anything out. In the main line code after all the Dims I added an "on error resume next" and then "if err.number <> 0 then wscript.echo ("descriptive text " & err.number) placed through out the code all the way down to the quit. It successfully intercepted the burp and echoed that error (13) but no other errors were intercepted.

You are right about shredding the machine. Unfortunately we have a few bajillion more of them around the company. Since this package will be deployed to over 200 machines I've got to find out why this thing fails. If it were a handful, I would just manually install the software and move on with my life. I may end up having to deploy this thing as is and go back and fix the ones that fail. I've spent way too much time on this as is.
Answered 01/06/2010 by: dadman53
Senior Yellow Belt

Please log in to comment
0
Are you certain that the same conditions will exist on other machines? It could very well be a fluke.
Answered 01/06/2010 by: Jsaylor
Second Degree Blue Belt

Please log in to comment
0
Re-registering the script engine didn't help. I'm trying the system file checker right now.
Answered 01/06/2010 by: dadman53
Senior Yellow Belt

Please log in to comment
0
The deal is I don't know what the conditions are on this machine that make it fail. The other four that I have been testing on have been imaged with XP SP3 within the past 6 months. This particular machine had XP SP2 on it; to prove that wasn't the problem I applied SP3 to it. We have a variety of Win2K, XP SP2, and XP SP3 machines in the company. We have a project underway to apply SP3 to the 200 or so PCs that are at SP2 level but I've already seen that it doesn't fix this particular problem. I can't get the PC owner to agree to allowing me to reimage the machine (yet) as he has other SW installed on it. My concern is that if I reimage this machine to solve the problem, how many others will I find when I try to deploy this thing.
Answered 01/06/2010 by: dadman53
Senior Yellow Belt

Please log in to comment
0
System file checker didn't find anything and/or solve the problem.
Answered 01/06/2010 by: dadman53
Senior Yellow Belt

Please log in to comment
Answer this question or Comment on this question for clarity