Solved

VBscript/Wscript - MS DOS Help - retrieving error code from PSEXEC, equivalent of "runwait"?

Posted on 2007-04-10
2
9,535 Views
Last Modified: 2009-01-09
This is yet another question related to previous questions I posted. I have a script that removes symantec from a specified list of computers. Symantec is removed using the PSEXEC tool from Microsoft.
The way the script works is like this:
I have a list of computers in computer.txt. This is stored in an array.
I also have a list of Uninstall keys for Symantec stored in an array. The reason I have multiple uninstall keys is because some client computers have different versions of symantec installed on their computer. To uninstall them, I need to set the UninstallPW key to false. I also need the specific uninstall key to remove it. So for each computer, run the PSEXEC command for each key:

psexec \\" & strComputer & " MsiExec.exe /norestart /q /x " & strSymantecKey & " REMOVE=ALL

This somewhat works. The first problem is it doesn't seem to perform like a "runwait".. where it waits until the uninstall is done before executing the next command. It basically just runs right after the other without waiting for it to be done. I'm afraid this could cause problems during the uninstall.

The second problem is that when this runs, the command prompt opens for a split second and closes. I would like to have one continuous command window open at all times until the script is completely done. Is there a way to do this?

The third problem is this. When the psexec command finishes, it returns an error code in the command line. I would like to keep track of this in a log. But I don't know how to RETRIEVE the error code from the command line back to VBscript. Can anyone help me figure out how to retrieve the error code, and if the error code is 0 (successful) then exit out the for loop and go to next computer?

My main concern right now is retreiving the error and logging. Thanks!

Here is my code:

'Remove Symantec Remotely and Silently
'Results are stored in a log file: symantec.log

'--------------- Create Log File ----------------

'Open up the path to save the information into a text file
Dim Stuff, myFSO, WriteStuff, timeStamp
timeStamp = Time()

Set myFSO = CreateObject("Scripting.FileSystemObject")
Set WriteStuff = myFSO.OpenTextFile("symantec.log", 2, True)

Dim objShell: Set objShell=CreateObject("Wscript.Shell")

Dim startMsg
startMsg = "STARTING SCRIPT, YO!" & vBCrLF & "You do not neet to click OK until it is done." &_
           vbcrlf & "When the script is done, it will say DONE, YO! Check symantec.log for results."

objShell.Popup startMsg, 3
'WScript.Echo startMsg

WriteStuff.WriteLine("Starting Script, yo!" & vbcrlf)

'-------------------- Grab computer names from Computer.txt and store in array ----------------

strComputers = ""

On Error Resume Next

'Initialize global constants and variables.
Const FOR_READING = 1
g_strHostFile = "computer3520.txt"

'Read computer names for install from text file.
Set objFSO = CreateObject("Scripting.FileSystemObject")

If objFSO.FileExists(g_strHostFile) Then
  Set objTextStream = objFSO.OpenTextFile(g_strHostFile, FOR_READING)
Else
  WScript.Echo "ERROR: Input file " & g_strHostFile & " not found."
  WScript.Quit
End If

'Loop through list of computers and perform tasks on each.
Do Until objTextStream.AtEndOfStream
  readingInComputer= objTextStream.ReadLine
'  Wscript.Echo VbCrLf & readingInComputer
 
 strComputers = strComputers + readingInComputer +","
Loop

objTextStream.Close

arrComputers = Split(strComputers , ",")
 

'----------------------------- Symnantec Piece---------------------------------
'Pre condition:  arrComputers must be populated from Computer.txt


'------- Insert all Available Keys Here-------------------
Dim strSymantecKeys
strSymantecKeys="{5a633ed0-e5d7-4d65-ab8d-53ed43510284},{46B63F23-2B4A-4525-A827-688026BE5E40},{BA4B71D1-898E-4306-AE87-8BA7A596F0ED}.{a011a1dc-7f1d-4ea8-bd11-0c5f9718e428},{473af7d0-b864-4699-9974-df570c5b6dce},{a011a1dc-7f1d-4ea8-bd11-0c5f9718e428},{50e125d1-88e5-48ce-80ae-98ec9698e639},{D75D48AF-E2D5-49EF-9571-EE7AFB6565B4}"
'---------------------------------------------------------
Const HKEY_LOCAL_MACHINE = &H80000002

arrSymantecKeys = Split(strSymantecKeys, ",")


For Each strComputer in arrComputers

On Error Resume Next
       '---- If computername is blank then exit loop ---
        If strComputer = "" Then
           exit for
        End If
 
 '----------- Set Uninstall Password & LockUnloadSvcs Registry Key Values-------

 Set objReg = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

 'objShell.Popup "Error = " & err.number & "!!!", 1

 ' ----If getObject fails, server is offline or doesn't exist -------------
 If err.number <> 0 then
      err.clear

        objShell.Popup "ERROR: "& strComputer & " is offline or access is denied", 1
      'wscript.echo "ERROR: "& strComputer & " is offline or access is denied"
      
      'write to log file
      WriteStuff.WriteLine(timeStamp & "  " & strComputer & " - ERROR! It is offline or doesn't exist.")
      On Error GoTo 0

 '------ Else GO ahead and remove Registry Keys ---------------------
 Else
   On Error GoTo 0

'   strKeyPath = "SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\AdministratorOnly\Security"
'   ValueName = "LockUnloadServices"

'   objReg.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, ValueName, strValue

'   If strValue<>0 Then
'      objReg.setDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, ValueName, 0
      'WScript.Echo strComputer & ": LockUnloadServices set to: " & strValue
'   End If

'   ValueName = "UseVPUninstallPassword"

'   objReg.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, ValueName, strValue

'   If strValue<>0 Then
'     objReg.setDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, ValueName, 0
     'WScript.Echo strComputer & ": UninstallPW set to: " & strValue
'   End If

   '----- Run MSIEXEC to remove Symantec -------------

  For Each strSymantecKey in arrSymantecKeys

     'objShell.run "%comspec% /k psexec \\" & strComputer & " MsiExec.exe /norestart /q /x " & strSymantecKey & " REMOVE=ALL", 8, true
      objShell.run "psexec \\" & strComputer & " MsiExec.exe /norestart /q /x " & strSymantecKey & " REMOVE=ALL", 8, true
     'objShell.Run "%comspec% /k rem "
  Next

  'Print to log file
   WriteStuff.WriteLine(timeStamp & " - " & strComputer & " - Symantec Removed.")

  'objShell.Popup strComputer & " - Symantec Removed", 1
  'WScript.Echo strComputer & " - Symantec Removed"


 End If


SET objReg=Nothing
 
 
Next


'Write to log file and close it
WriteStuff.WriteLine(vbcrlf & "Script is Done, yo!
WriteStuff.Close
SET WriteStuff = NOTHING
SET myFSO = NOTHING
SET objShell = NOTHING

'Let user know the script is done!
WScript.Echo "SCRIPT IS DONE, YO!!!"
0
Comment
Question by:ThinkPaper
2 Comments
 
LVL 65

Accepted Solution

by:
RobSampson earned 500 total points
Comment Utility
ThinkPaper,

As far as catching the error code goes, I would probably suggest running a batch file using
wshShell.Run "cmd /c pathtobatchfile.bat"
with the batch file having the following:
rem ==========
@echo off
psexec \\d23rbb1sring ipconfig /all > F:\Temp\ipc.txt
echo %errorlevel% > Error.txt
type Error.txt
rem ==========

You could then use vbs to open the Error.txt and read the error code.  Using a batch file
like this would also allow you to use one continuous command prompt for your commands.

As far as having PSExec act like a Run...Wait command goes, I have done something similar
to this by using a process monitoring script:
'==========================
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")

boolStillRunning = True

Do While boolStillRunning = True
      Set colProcess = objWMIService.ExecQuery ("Select Name from Win32_Process")
      boolStillRunning = False
      For Each objProcess in colProcess
            If objProcess.Name = "msiexec.exe" Then
                  boolStillRunning = True
            End If
      Next
      Wscript.Sleep 5000
Loop
'==========================

Then you could run the next command, but this could get tricky if you do put
all of the commands in the same batch file.....it's kind of like switching between
vbs and batch files alot....

Hope that helps.

Rob.
0
 
LVL 16

Author Comment

by:ThinkPaper
Comment Utility
Thanks for the info. Unfortunately I wasn't able to put it to good use, since our SRR started, but this'll help me in the future. =)
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

How to remove superseded packages in windows w60 or w61 installation media (.wim) or online system to prevent unnecessary space. w60 means Windows Vista or Windows Server 2008. w61 means Windows 7 or Windows Server 2008 R2. There are various …
Several part series to implement Internet Explorer 11 Enterprise Mode
This video Micro Tutorial explains how to clone a hard drive using a commercial software product for Windows systems called Casper from Future Systems Solutions (FSS). Cloning makes an exact, complete copy of one hard disk drive (HDD) onto another d…
With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now