Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2237
  • Last Modified:

WshShell.Exec never finishes. Simple code not working correctly.

I have created a script that gets a list of all the Scheduled Tasks, parses the results and restarts any failed Tasks.  The problem I am having is with the Set oExec = WshShell.Exec("schtasks /query /fo LIST /v") part of the script.  The oExec.Status never reaches 0.  So if I time out the wait the data I parse through is incomplete. Out of six Scheduled Tasks I get to parse about 2.8.  If I remove the time out of the script it stalls after doing the WshShell.Exec.  I have run this in debug mode and just can't see why it is not working.  Also if I redirect the output, "schtasks /query /fo LIST /v > taskfile.txt",  I get all the tasks listed in the text file.

Dim WshShell
Dim oExec
Dim MaxWaitTime
Dim CurrentWaitTime
Dim strLine
Dim strLineArrayTask
Dim strLineArrayResult
Dim strItem
Dim strTaskName
Dim strTaskArray
Dim strLastResult
Dim objEmail

MaxWaitTime = 20000
CurrentWaitTime = 0
Set WshShell = CreateObject("WScript.Shell")
      
'The tool is launched
Set oExec = WshShell.Exec("schtasks /query /fo LIST /v")
      
'We wait for the end of the process
Do While oExec.Status = 0
      WScript.Sleep 100
      CurrentWaitTime = CurrentWaitTime + 100
            If CurrentWaitTime >= MaxWaitTime Then
                  oExec.Terminate
                  Exit Do
            End if
Loop
      
'We scan the output for the TaksName and LastStatus
Do While oExec.StdOut.AtEndOfStream <> True
      strLine = oExec.StdOut.ReadLine
      Wscript.Echo strLine
            If instr(strLine,"TaskName:") <> 0 Then
            'Wscript.Echo "Found:TaskName: " & vbcrlf & strLine
               strLineArrayTask = split(trim(strLine))
            'For each strItem in strLinearrayTask
                  'msgbox strItem
            'Next
                  strTaskName = strLineArrayTask(29)
                  'MsgBox strTaskName
            Else If instr(strLine,"Last Result:") <> 0 Then
                  'Wscript.Echo "Found:Last Result: " & vbcrlf & strLine
                     strLineArrayResult = split(trim(strLine))
                  'For each strItem in strLinearrayTask
                  'msgbox strItem
                  'Next
                        strLastResult = strLineArrayResult(27)
                        'MsgBox strLastResult      
                        If (strLastResult) <> 0 Then
                              WshShell.Exec("schtasks /run /TN " & strTaskName)
                              Set objEmail = CreateObject("CDO.Message")
                              objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
                              objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "MailServer"    
                              objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
                              objEmail.Configuration.Fields.Update

                              objEmail.From = "email@address.com"
                              objEmail.To = "email2@address.com"
                              objEmail.Subject = "The " & strTaskName & " was restarted by the autostarter."
                              objEmail.Textbody = "The reason it was restarted was the Last Status when checked was " & strLastResult
                              objEmail.Send
                              Set objEmail = nothing  
                        End If
                  End If    
            End if
Loop
0
xtross
Asked:
xtross
  • 3
  • 3
1 Solution
 
RobSampsonCommented:
Try changing:
Set oExec = WshShell.Exec("schtasks /query /fo LIST /v")

to
Set oExec = WshShell.Exec("cmd /c schtasks /query /fo LIST /v")

Regards,

Rob.
0
 
xtrossAuthor Commented:
Using cmd /c schtasks /query /fo LIST /v had no affect on the script.
0
 
RobSampsonCommented:
Would there be any chance that, for certains tasks, the command is waiting for a password to be entered, because of an "access denied" issue?

If you run the same command from a command prompt manually, under the same user account that would run the script, does it complete, and how long does it take?

Regards,

Rob.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
xtrossAuthor Commented:
The same command runs fine in a command window.  There  is no prompt for anything when running schtasks.  I'm starting to think the file itself is corrupt.  It makes no sense.
0
 
RobSampsonCommented:
I wonder if instead of doing Exec, you could use Run, and output to a file for parsing.  The only drawback here is that you won't be able to kill the task via the script if it doesn't finish.

Try this:

'========================
Set WshShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")

' The tool is launched
strOutputFile = Replace(WScript.ScriptFullName, WScript.ScriptName, "") & "tasklist.txt"
' Create the empty file so we can get the short path
Set objTaskFile = objFSO.CreateTextFile(strOutputFile, True)
objTaskFile.Close
Set objTaskFile = Nothing
' Get the Short Path to pass to the command line
strOutputFile = objFSO.GetFile(strOutputFile).ShortPath
' The True parameter at the end will make the script wait for the process to complete
' You can also change the 1 to a 0 to hide the command window.
WshShell.Run "cmd /c schtasks /query /fo LIST /v > " & strOutputFile, 1, True
     
Const intForReading = 1
Set objTaskFile = objFSO.OpenTextFile(strOutputFile, intForReading, False)
'We scan the output for the TaksName and LastStatus
Do While objTaskFile.AtEndOfStream <> True
      strLine = objTaskFile.ReadLine
      ' do the other stuff
Loop
objTaskFile.Close
Set objTaskFile = Nothing
objFSO.DeleteFile strOutputFile, True
MsgBox "Done"
'=====================

Regards,

Rob.
0
 
xtrossAuthor Commented:
Never did solve this one.  I went with creating a file as suggested.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now