Jump to content

getting a successful result from command prompt


Recommended Posts

Hey all,

I searched through the help and forums and did not see anything, so sorry if it has been covered.

I might be going about this the wrong way, but here is my scenerio.

I have a couple of servers that need to restarted every week in a production environment. I am trying to automate this, as the restart requires a couple of services to be started. The windows automatic service function does not work with these services. So i am using the net start command, in cmd prompt. However I need it to email weather if it is unsuccessful. I have got the automation of the net start to work, and the email function to work. But I cannot see if it was successful, it just sends out a message. Netstart can be successful or fail. I cannot see what the command prompt says.

Do you guys know a way to read the message out of command prompt? Or do you know another way to start a service, and have it give a message that can be read, and only emailed when it is unsuccessful?

Thanks

Link to comment
Share on other sites

This function will return the output of a command as a string, perhaps it will give you ideas

#include <Constants.au3>

; Example
$result= _CMDreturn("ver")
msgbox(0,"Version",$result)

Func _CMDreturn($sCommand) ; This function returns the output of a DOS command as a string
    $cmdreturn = ""
    $stream = Run(@ComSpec & " /c " & $sCommand, @SystemDir, @SW_HIDE, $STDOUT_CHILD + $STDIN_CHILD)
    While 1 ; loop through the return from the command until there is no more
        $line = StdoutRead($stream)
        If @error Then ExitLoop
        $cmdreturn &= $line
    WEnd
    Return $cmdreturn
EndFunc   ;==>_CMDreturn

[edit] forgot to put in the include file for the constants

Edited by SpookMeister

[u]Helpful tips:[/u]If you want better answers to your questions, take the time to reproduce your issue in a small "stand alone" example script whenever possible. Also, make sure you tell us 1) what you tried, 2) what you expected to happen, and 3) what happened instead.[u]Useful links:[/u]BrettF's update to LxP's "How to AutoIt" pdfValuater's Autoit 1-2-3 Download page for the latest versions of Autoit and SciTE[quote]<glyph> For example - if you came in here asking "how do I use a jackhammer" we might ask "why do you need to use a jackhammer"<glyph> If the answer to the latter question is "to knock my grandmother's head off to let out the evil spirits that gave her cancer", then maybe the problem is actually unrelated to jackhammers[/quote]

Link to comment
Share on other sites

:facepalm:

I used _CMDreturn("ver") as an example... I could have used DIR or maybe even something like.... wait for it.... "NET START SOMESERVICE"

Hint: "NET START SOMESERVICE" is another one of those "example" things

Edited by SpookMeister

[u]Helpful tips:[/u]If you want better answers to your questions, take the time to reproduce your issue in a small "stand alone" example script whenever possible. Also, make sure you tell us 1) what you tried, 2) what you expected to happen, and 3) what happened instead.[u]Useful links:[/u]BrettF's update to LxP's "How to AutoIt" pdfValuater's Autoit 1-2-3 Download page for the latest versions of Autoit and SciTE[quote]<glyph> For example - if you came in here asking "how do I use a jackhammer" we might ask "why do you need to use a jackhammer"<glyph> If the answer to the latter question is "to knock my grandmother's head off to let out the evil spirits that gave her cancer", then maybe the problem is actually unrelated to jackhammers[/quote]

Link to comment
Share on other sites

It's probably easier to redirect output to a file. I could not get STDOUT to work with net start. This will show all the services that have started. Maybe you can run your net start script, wait a minute, and then run this function and have the output emailed to you. You can also search the output string for your service(s) name(s), and if they are not there, call your net start function again. This is a basic way of doing things, but you may also see about reading the event logs to determine why a service fails to start.

$EmailMessage = QueryStartedServices()
MsgBox(32, 'Started Services', $EmailMessage) ;For Testing

Func QueryStartedServices()
    Local $Header = @CRLF & '*** ' & @YEAR & '-' & @MON & '-' & @MDAY & '-' & @HOUR & ':' & @MIN & ':' & @SEC & ' ***' & @CRLF
    Local $Footer = '*************************************************'
    Local $oFile = @TempDir & '\netstart.txt'

    FileDelete($oFile) ;Delete Temporary File..maybe you want to keep this for auditing
    FileWrite($oFile, $Header) ;Header to show the Date/Time Query Started
    RunWait(@ComSpec & ' /c net start >> "' & $oFile & '"', @SystemDir, @SW_HIDE) ;List started Services
    FileWrite($oFile, $Footer) ;Footer for Seperation
    Return FileRead($oFile)
EndFunc

EDIT: I used a Header and footer i case you want to append the file instead of deleting it before every run. That way you can separate the number of runs more easily

Edited by Varian
Link to comment
Share on other sites

This works just fine for me:

#include <Constants.au3>
; Example
$result= _CMDreturn('net stop "Print Spooler"')
msgbox(0,"Version",$result)

$result= _CMDreturn('net start "Print Spooler"')
msgbox(0,"Version",$result)


Func _CMDreturn($sCommand) ; This function returns the output of a DOS command as a string
    $cmdreturn = ""
    $stream = Run(@ComSpec & " /c " & $sCommand, @SystemDir, @SW_HIDE, $STDOUT_CHILD + $STDIN_CHILD)
    While 1 ; loop through the return from the command until there is no more
        $line = StdoutRead($stream)
        If @error Then ExitLoop
        $cmdreturn &= $line
    WEnd
    Return $cmdreturn
EndFunc   ;==>_CMDreturn

[u]Helpful tips:[/u]If you want better answers to your questions, take the time to reproduce your issue in a small "stand alone" example script whenever possible. Also, make sure you tell us 1) what you tried, 2) what you expected to happen, and 3) what happened instead.[u]Useful links:[/u]BrettF's update to LxP's "How to AutoIt" pdfValuater's Autoit 1-2-3 Download page for the latest versions of Autoit and SciTE[quote]<glyph> For example - if you came in here asking "how do I use a jackhammer" we might ask "why do you need to use a jackhammer"<glyph> If the answer to the latter question is "to knock my grandmother's head off to let out the evil spirits that gave her cancer", then maybe the problem is actually unrelated to jackhammers[/quote]

Link to comment
Share on other sites

I like that function SpookMeister! (gotta hear the story behind that name)

I want to see if it will work with programs that put out info on the same line, like Scan32 or sdelete. I

have a Gui frontend for sdelete that I would love to use but it doesn't come out right because the

progress shows up on the same line

Link to comment
Share on other sites

This works just fine for me:

#include <Constants.au3>
; Example
$result= _CMDreturn('net stop "Print Spooler"')
msgbox(0,"Version",$result)

$result= _CMDreturn('net start "Print Spooler"')
msgbox(0,"Version",$result)


Func _CMDreturn($sCommand) ; This function returns the output of a DOS command as a string
    $cmdreturn = ""
    $stream = Run(@ComSpec & " /c " & $sCommand, @SystemDir, @SW_HIDE, $STDOUT_CHILD + $STDIN_CHILD)
    While 1 ; loop through the return from the command until there is no more
        $line = StdoutRead($stream)
        If @error Then ExitLoop
        $cmdreturn &= $line
    WEnd
    Return $cmdreturn
EndFunc   ;==>_CMDreturn
Thank you!!!

But it isn't working in scan.exe.

One question:

Is there other solution for return the output of a DOS command to Autoit?

If I do in DOS line command

scan c:\

It show all the files scanned in one msdos windows, but If I put:

scan c:\ >files_scanned.txt

When finalize the scan the file "files_scanned.txt" is all empy.

My question is: If one msdos program haven't returned nothing in one file output either it will return nothing in one function stsoutread?

any help?

Edited by Juanola
Link to comment
Share on other sites

If it's like the Mcafee commandline scanner, it puts the output onto the same line. This causes an issue with stdout. If you are append the stdout then you'll probably get the last line that has the progress output on the last line when the stream closes. For sdelete(command line disk/free space wipe utility), my last line is like "Cleaning free space on L:: 0%Cleaning free space on L:: 3%Cleaning free space on L:: 6%Cleaning free space on L:: 9%..." As you can see, some console commands resist redirection

Link to comment
Share on other sites

Yah i am retarded. i did not look that close at the script that was sent. I did not know about some of the constants varibles that drive some of it. After experimenting around it looks good.

Sorry to bother you.

:facepalm:

I used _CMDreturn("ver") as an example... I could have used DIR or maybe even something like.... wait for it.... "NET START SOMESERVICE"

Hint: "NET START SOMESERVICE" is another one of those "example" things

Link to comment
Share on other sites

I have been going through the code, and I have gotten it to work except for when there is an error. If everything starts successfully then it returns the results, however when there is an error then the script kills itself by this code:

While 1
         $line = StdoutRead($stream)
    If @error then exitloop
        $cmdreturn &= $line

Which it is supposed to do, so it does not continuosly loop. But when the error that gets outputted is

The requested service has already been started.

More help is available by typing NET HELPMSG 2182.

Then nothing is returned. I have it set up now so that when the loop stops then an error email is sent out, which works, but I would like to base alerts on what error is displayed. The biggest one being, if it has been started already or could not be started. That is a big difference for us.

I have tried to get rid of error check but it gets stuck in an infinite loop. Any ideas or thoughts?

Link to comment
Share on other sites

Try this:

#include <Constants.au3>
; Example Usage
$result= _CMDreturn('net stop "Print Spooler"')
msgbox(0,"Version",$result)

$result= _CMDreturn('net start "Print Spooler"')
msgbox(0,"Version",$result)

Func _CMDreturn($sCommand) ; This function returns the output of a DOS command as a string
    $cmdreturn = ""
    $stream = Run(@ComSpec & " /c " & $sCommand, @SystemDir, @SW_HIDE, $STDERR_MERGED + $STDIN_CHILD)
    While 1 ; loop through the return from the command until there is no more
        $line = StdoutRead($stream)
        If @error Then ExitLoop
        $cmdreturn &= $line
    WEnd
    Return $cmdreturn
EndFunc   ;==>_CMDreturn

You should get the error in the output as well now... and be able to parse it accordingly.

P.S. Sorry for being a bit of a wiseass in that earlier post... <shrug> it happens sometimes.

[u]Helpful tips:[/u]If you want better answers to your questions, take the time to reproduce your issue in a small "stand alone" example script whenever possible. Also, make sure you tell us 1) what you tried, 2) what you expected to happen, and 3) what happened instead.[u]Useful links:[/u]BrettF's update to LxP's "How to AutoIt" pdfValuater's Autoit 1-2-3 Download page for the latest versions of Autoit and SciTE[quote]<glyph> For example - if you came in here asking "how do I use a jackhammer" we might ask "why do you need to use a jackhammer"<glyph> If the answer to the latter question is "to knock my grandmother's head off to let out the evil spirits that gave her cancer", then maybe the problem is actually unrelated to jackhammers[/quote]

Link to comment
Share on other sites

dont worry about it, i was being a dumbass and not looking at things.

wow thanks for the help that looks groovy...ive been killing myself all day trying to get that. It looks like you just swapped $STDOUT_CHILD to $STDERR_MERGED you mind if i ask what the difference is?

Link to comment
Share on other sites

It is explained in the help file for Run (which is where I found it)

Basically it merges the data streams for STDOUT and STDERR

[u]Helpful tips:[/u]If you want better answers to your questions, take the time to reproduce your issue in a small "stand alone" example script whenever possible. Also, make sure you tell us 1) what you tried, 2) what you expected to happen, and 3) what happened instead.[u]Useful links:[/u]BrettF's update to LxP's "How to AutoIt" pdfValuater's Autoit 1-2-3 Download page for the latest versions of Autoit and SciTE[quote]<glyph> For example - if you came in here asking "how do I use a jackhammer" we might ask "why do you need to use a jackhammer"<glyph> If the answer to the latter question is "to knock my grandmother's head off to let out the evil spirits that gave her cancer", then maybe the problem is actually unrelated to jackhammers[/quote]

Link to comment
Share on other sites

Thanks for all of the help, I have gotten the script to work well to auto start the service. However we had a problem with a server on fri that noone noticed so they asked me if there was a way to continuosly monitor to see if the service is running. I have gotten it to work for awhile, but after the script runs for 2 minutes it generates an error. here is the script:

While $check = 1
$result= _CMDreturn('sc query "aawservice"');call command prompt function
$string = StringRegExp($result, 'RUNNING', 1); look at string that is returned.
If @error == 0 Then
    $check = 1
Else
    $check = 2
EndIf
 if $check = 2 Then
     MsgBox(0,"error",$result)
 EndIf 
 sleep(20000); wait 20 seconds and try again
 WEnd

The error shows that result is blank. I have tried to sleep for longer to see if that resovles it, but after some time it just spits out a blank error. Anyone have any ideas? Does a while loop just run for a certain period of time? The end result is if the state is not running, then call the start program to try and start it.

Link to comment
Share on other sites

I couldn't get StringRegExp to work, but I found a work-around you could try...

Basically add the pipe and "findstr "STATE"" (case-sensitive) to your command and it will return just that one line that tells you what state the service is in. It will then search that line for the word RUNNING and if it finds it will return the location and store it in $loc. If it can't find it, $loc will be 0. Sorry it's so messy but I have to get going to work... Good luck!

While $check = 1
$result= _CMDreturn('sc query "aawservice" | findstr "STATE"')

;$string = StringRegExp($result, 'RUNNING', 1); look at string that is returned.

$loc = StringInStr($result, "RUNNING")          ;Where in the string is "RUNNING" located?

If $loc Then                                    ;$loc will be non-zero if the string was found
    $string = StringTrimRight(StringTrimLeft($result, $loc - 1), 3) 
Else
    MsgBox(0, "Error", "String 'RUNNING' not found.")
;Do other stuff here or whatever...
EndIf

MsgBox(0,"$string = ",$string)

Sleep(20000); wait 20 seconds and try again
WEnd
Link to comment
Share on other sites

What problem did you have with stringregexp?

I have it working. I does search and finds the word 'Running' and will run through the loop a number of times. It seems to stop working though, as it runs more. The probmel seems to be in $result kind of like it is not reading anything in, as I read what is stored in there and it is blank. Its odd, like it is running too many times. I will mess around with your example though and see if I can make that work better. thanks for the advice.

Link to comment
Share on other sites

Ok so I have tried switching over to _CMDreturn('sc query "aawservice" | findstr "STATE"')

instead of the stringregexp, but it seems to have the same error, after a period of time it just stops working. Does anyone know what could be causing this?

Thanks

Link to comment
Share on other sites

Perhaps your check interval is stepping on itself.. try checking one per min etc...

[u]Helpful tips:[/u]If you want better answers to your questions, take the time to reproduce your issue in a small "stand alone" example script whenever possible. Also, make sure you tell us 1) what you tried, 2) what you expected to happen, and 3) what happened instead.[u]Useful links:[/u]BrettF's update to LxP's "How to AutoIt" pdfValuater's Autoit 1-2-3 Download page for the latest versions of Autoit and SciTE[quote]<glyph> For example - if you came in here asking "how do I use a jackhammer" we might ask "why do you need to use a jackhammer"<glyph> If the answer to the latter question is "to knock my grandmother's head off to let out the evil spirits that gave her cancer", then maybe the problem is actually unrelated to jackhammers[/quote]

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...