retrieve output from external command - vbscript

I have a command
commande = "cmd /c sc query state= all | findstr SERVICE_NAME | find /c /I "&LISTENER&"$"
and I want to retrieve content to treat later in my script.

You need a WshScriptExec object for that, so you can read its StdOut property upon completion:
Set sh = CreateObject("WScript.Shell")
Set cmd = sh.Exec("...")
Do While cmd.Status <> 1
WScript.Sleep 100
Loop
output = cmd.StdOut.ReadAll

Here's an adapted version of a complex script (stolen from original documentation by Microsoft MSDN). It grabs both StdOut and StdErr streams from executed command prompt window:
option explicit
On Error GoTo 0
Dim strResult
myCmdExec "%comspec% /C dir /B /AD xxw*"
myCmdExec "%comspec% /C dir /B /AD fil*"
myCmdExec "cmd /c sc query state= all | findstr SERVICE_NAME | find /I /c ""pcasvc"""
myCmdExec "cmd /c sc query state= all | findstr SERVICE_NAME | findstr /I ler$"
Private Sub myCmdExec( commande)
strResult = commande & vbNewLine
Dim WshShell, oExec, xExitCode, input, allInput
allInput = ""
Set WshShell = CreateObject( "WScript.Shell")
Set oExec = WshShell.Exec( commande)
Do While True
input = ReadAllFromAny( oExec)
If input = -1 Then
If oExec.Status = 1 Then Exit Do
WScript.Sleep 100
Else
allInput = allInput & input
End If
Loop
xExitCode = oExec.ExitCode
If xExitCode <> 0 Then strResult = strResult & "Warning: Non-zero "
strResult = strResult & "exit code " & CStr( xExitCode) & vbNewLine _
& String( 30, "-") & vbNewLine
Wscript.Echo strResult & allInput & String( 30, "=") & vbNewLine
End Sub
Function ReadAllFromAny( oExec)
If Not oExec.StdOut.AtEndOfStream Then
ReadAllFromAny = oExec.StdOut.ReadAll
Exit Function
End If
If Not oExec.StdErr.AtEndOfStream Then
ReadAllFromAny = oExec.StdErr.ReadAll
Exit Function
End If
ReadAllFromAny = -1
End Function
Output:
==>cscript D:\VB_scripts\SO\30320862.vbs
%comspec% /C dir /B /AD xxw*
Warning: Non-zero exit code 1
------------------------------
File Not Found
==============================
%comspec% /C dir /B /AD fil*
exit code 0
------------------------------
files
==============================
cmd /c sc query state= all | findstr SERVICE_NAME | find /I /c "pcasvc"
exit code 0
------------------------------
1
==============================
cmd /c sc query state= all | findstr SERVICE_NAME | findstr /I ler$
exit code 0
------------------------------
SERVICE_NAME: Spooler
SERVICE_NAME: TrustedInstaller
==============================
==>

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * From Win32_Service")
For Each objItem in colItems
If Lcase(objitem.Name) = "audiosrv" Then
msgbox objitem.name & " " & objitem.status & " " & objitem.state
objitem.StartService
End If
Next
Is a better way to do what you want.
Output
---------------------------
---------------------------
Audiosrv OK Running
---------------------------
OK
---------------------------

Related

How to determine what vbscripts are running in background

I wrote a vbscript to determine what are the vbscripts running in background but when I execute my script . it only opens the folder of my script not the other scripts location or folder . What should I do?? Please help
Myscript.vbs
Set objShell = CreateObject("Wscript.Shell")
strPath = Wscript.ScriptFullName
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(strPath)
strFolder = objFSO.GetParentFolderName(objFile)
strPath = "explorer.exe /e," & strFolder
objShell.Run strPath
Please help guys . I am very new to vbscript .
I have for you an old vbscript since 2015 that can tell you what vbscript is running in the background with its command line of course to get their paths and you have a possiblity to choose what vbscript you want to kill and you get in the end of the script a log file for this.
So you can give a try for this first, and i will edit and update it for any modifications in order to answer your question.
Option Explicit
Dim Titre,Copyright,fso,ws,NomFichierLog,temp,PathNomFichierLog,OutPut,Count
If AppPrevInstance() Then
MsgBox "There is an existing proceeding !" & VbCrLF & CommandLineLike(WScript.ScriptName),VbExclamation,_
"There is an existing proceeding !"
WScript.Quit
Else
Copyright = "[Hackoo "& chr(169) & " 2015]"
Set fso = CreateObject("Scripting.FileSystemObject")
Set ws = CreateObject( "Wscript.Shell" )
NomFichierLog="Killed_Process.txt"
temp = ws.ExpandEnvironmentStrings("%temp%")
PathNomFichierLog = temp & "\" & NomFichierLog
Set OutPut = fso.CreateTextFile(temp & "\" & NomFichierLog,1)
Call Find("wscript.exe")
Call Explorer(PathNomFichierLog)
End If
'***************************************************************************************************
Function Explorer(File)
Dim ws
Set ws = CreateObject("wscript.shell")
ws.run "Explorer "& File & "\",1,True
end Function
'***************************************************************************************************
Sub Find(MyProcess)
Dim colItems,objItem,Processus,Question,Msg
Titre = " Process(es) "& DblQuote(MyProcess) &" running "
Set colItems = GetObject("winmgmts:").ExecQuery("Select * from Win32_Process " _
& "Where Name like '%"& MyProcess &"%' AND NOT commandline like " & CommandLineLike(WScript.ScriptFullName) & "",,48)
Count = 0
For Each objItem in colItems
Count= Count + 1
Processus = objItem.CommandLine
Question = MsgBox ("Would do you like to kill this script : " & DblQuote(Processus) & " ?" ,VBYesNO+VbQuestion,Titre+Copyright)
If Question = VbYes then
objItem.Terminate(0)'To kill the process
OutPut.WriteLine Processus
else
Count= Count - 1 'decrementing the count of -1
End if
Next
OutPut.WriteLine String(100,"*")
If Count > 1 Then
Msg = " were killed"
Else
Msg = " was killed"
End if
OutPut.WriteLine count & Titre & Msg
OutPut.WriteLine String(100,"*") & VbCrLF
End Sub
'**************************************************************************
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'**************************************************************************
Function AppPrevInstance()
With GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")
With .ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE " & CommandLineLike(WScript.ScriptFullName) & _
" AND CommandLine LIKE '%WScript%' OR CommandLine LIKE '%cscript%'")
AppPrevInstance = (.Count > 1)
End With
End With
End Function
'**************************************************************************
Function CommandLineLike(ProcessPath)
ProcessPath = Replace(ProcessPath, "\", "\\")
CommandLineLike = "'%" & ProcessPath & "%'"
End Function
'**************************************************************************
EDIT : Extract_CommandLine.bat
Copy and paste this code as batch file in order to extract the command line of each process.
Set ProcessNames="cmd.exe" "mshta.exe" "powershell.exe" "cscript.exe" "wscript.exe"
You can add or remove the process name from the variable ProcessNames between the double quotes.
#echo off
Title Extract CommandLine Of Running Processes by Hackoo 2020
Mode 110,10 & color 0A
Set "TmpFile=%~n0_Abs_cmdline.txt"
Set "LogFile=%~n0_cmdline.txt
If Exist "%TmpFile%" Del "%TmpFile%"
If Exist "%LogFile%" Del "%LogFile%"
Set ProcessNames="cmd.exe" "mshta.exe" "powershell.exe" "cscript.exe" "wscript.exe"
SetLocal EnableDelayedExpansion
for %%A in (%ProcessNames%) Do (
Call :GetCommandLine %%A ProcessCmd
If defined ProcessCmd (
echo !ProcessCmd!>con
echo !ProcessCmd!>>"%TmpFile%"
)
)
Timeout /T 3 /NoBreak>nul
If Exist "%TmpFile%" Call :Extract "%TmpFile%" "%LogFile%"
If Exist "%LogFile%" Start "" "%LogFile%"
If Exist "%LogFile%" Call :ExplorerIT "%LogFile%"
Exit
::---------------------------------------------------------------------------------------------------------------
:GetCommandLine <ProcessName> <ProcessCmd>
Set "ProcessCmd="
for /f "tokens=2 delims==" %%P in (
'wmic process where caption^="%~1" get commandline /format:list ^| findstr /I "%~1" ^| find /I /V "%~nx0" 2^>nul'
) do (
if not defined %2 Set "%2=%%P"
)
Exit /b
::---------------------------------------------------------------------------------------------------------------
:Extract <InputData> <OutPutData>
(
echo Data = WScript.StdIn.ReadAll
echo Data = Extract(Data,"(^?^!.*(\x22\w^)^)\b.*(\w^).*(\.ps1^|\.hta^|\.vbs^|\.vbe^|\.cmd^|\.bat^|\.lnk^)"^)
echo WScript.StdOut.WriteLine Data
echo Function Extract(Data,Pattern^)
echo Dim oRE,oMatches,Match,Line
echo set oRE = New RegExp
echo oRE.IgnoreCase = True
echo oRE.Global = True
echo oRE.Pattern = Pattern
echo set oMatches = oRE.Execute(Data^)
echo If not isEmpty(oMatches^) then
echo For Each Match in oMatches
echo Line = Line ^& chr(34^) ^& Trim(Match.Value^) ^& chr(34^) ^& vbcrlf
echo Next
echo Extract = Line
echo End if
echo End Function
)>"%tmp%\%~n0.vbs"
cscript /nologo "%tmp%\%~n0.vbs" < "%~1" > "%~2"
If Exist "%tmp%\%~n0.vbs" Del "%tmp%\%~n0.vbs"
exit /b
::-----------------------------------------------------------------------------------------------------------
:ExplorerIT <LogFile>
#For /f "delims=" %%a in ('Type "%~1"') do (
Start "SelectFile" Explorer /select,"%%~a"
)
Exit /B
::-----------------------------------------------------------------------------------------------------------

Run any file with vbs at a specific time

Is it possible to run any type of file (like,. mp3, doc, exe..) with a Vbscript file at a specific time?
I looked in many places but there were no success..
Give a try for this example that can schedule Notepad to be executed everyday at 10:00 AM
So, you need just to modify those 3 arguments in this script to yours :
TaskName
App_FullPath
strTime
Option Explicit
Dim TaskName,App_FullPath,strTime
TaskName = "Execute_Notepad"
App_FullPath = "C:\windows\notepad.exe"
strTime = "10:00"
Call CreateTask(TaskName,App_FullPath,strTime)
'*****************************************************************
Sub CreateTask(TaskName,App_FullPath,strTime)
Dim ws,strtask,exitcode
Set ws = CreateObject("Wscript.Shell")
strtask = "schtasks /create /sc Daily /tn "& qq(TaskName) & _
" /tr "& qq(App_FullPath) & _
" /st " & strTime & " /f"
exitcode = ws.Run(strtask, 0, True)
If exitcode <> 0 Then
WScript.Echo "External command failed: " & Hex(exitcode)
Else
wscript.echo "Success !"
End If
End Sub
'*****************************************************************
Function qq(str)
qq = chr(34) & str & chr(34)
End Function
'*****************************************************************
Edit : Batch file to show or delete a numbered task names
#echo off
Mode 100,3 & color 0A
Title Delete Tasks with their time tasks execution by Hackoo 2017
:Menu
Mode 100,3 & color 0A
cls & echo(
echo Type the time with this format "hh:mm" or a task name to show or delete for scheduled Tasks
set /a "count=0"
set /p "strTime="
cls & echo(
echo Please wait a while ... looking for a scheduled Tasks for "%strTime%"
Setlocal EnableDelayedExpansion
#for /f "tokens=1 delims=," %%a in ('schtasks /query /fo csv ^| find /I "%strTime%"') do (
set /a "Count+=1"
set "TaskName[!Count!]=%%~a"
)
Rem Display numbered Task Names
Mode 90,30 & cls & echo(
#for /L %%i in (1,1,%Count%) do (
set "Task=[%%i] - !TaskName[%%i]:~1!"
echo !Task!
)
If not defined Task (
Mode 90,3 & Color 0C
echo(
echo No Scheduled Tasks found with this criteria
Timeout /T 3 /nobreak >nul & goto Menu
)
echo(
Rem Asking user if he wants to delete or not the numbered task names
echo Type the number of the task to delete !
set /p "Input="
#for /L %%i in (1,1,%Count%) Do (
If "%INPUT%" EQU "%%i" (
schtasks /delete /tn "!TaskName[%%i]:~1!"
)
)
echo(
echo Type any key to show and delete another task !
Pause>nul
Goto Menu
In this vbscript you can change 4 arguments :
TaskName
AppFullPath
StartTime
Frequency
Option Explicit
Dim TaskName,AppFullPath,StartTime,Frequency
'************* Four params can be changed here********************
TaskName = "Execute Notepad by Hackoo"
AppFullPath = "C:\windows\notepad.exe"
StartTime = "10:00"
Frequency = "Minute"
REM The value of frequency can be taken
Rem as "MINUTE", "HOURLY", "DAILY", "WEEKLY" or "MONTHLY"
REM https://technet.microsoft.com/en-us/library/bb490996.aspx
REM Don't change anything under this line
'************************** Main *********************************
Call CreateTask(TaskName,AppFullPath,StartTime,Frequency)
'*****************************************************************
Sub CreateTask(TaskName,AppFullPath,StartTime,Frequency)
Dim ws,strtask,exitcode
Set ws = CreateObject("Wscript.Shell")
strtask = "schtasks /create /sc "& Frequency &" /tn "& qq(TaskName) & _
" /tr "& qq(AppFullPath) & _
" /st " & StartTime & " /f"
exitcode = ws.Run(strtask, 0, True)
If exitcode <> 0 Then
WScript.Echo "External command failed: " & Hex(exitcode)
Else
wscript.echo "The Task "& qq(TaskName) & " is created successfully !"& vbcrlf &_
"to be run "& qq(Frequency) &" with a StartTime at " & qq(StartTime) & ""
End If
End Sub
'*****************************************************************
Function qq(str)
qq = chr(34) & str & chr(34)
End Function
'*****************************************************************

VBScript and PSExec

Hi I m having problems reading the output provided by WScript.Shell and PSExec. My goal is to be able to read what PSExec.exe returns as text so I can perform some validation with InStr.
The Code is similar to this:
Const WshFinished = 1
Const WshFailed = 2
Dim cmdLine, strComputer
strComputer = "\\SomeComputer"
cmdLine = "psexec " & strComputer & " cmd /C " & """RD " & """%PROGRAMFILES%\APPFOLDER""" & " /S /Q | RD " & """%PROGRAMFILES%\COMMON FILES\APPFOLDER""" & " /S /Q | RD " & """%SYSTEMROOT%\temp\APPFOLDER""" & " /S /Q"""
Set WSH = WScript.CreateObject("WScript.Shell")
WSH.Exec(cmdLine)
Do While WSH.Status = 0
WScript.Sleep 100
Loop
Select Case WSH.Status
Case WshFinished
strOutput = WSH.StdOut.ReadAll
Case WshFailed
strOutput = WSH.StdErr.ReadAll
End Select
Wscript.Echo strOutput
If (InStr(strOutput, "validation text") > 0) Then
'Do Stuff
End IF
The Problem is that strOutput variable comes always empty and I can't perform text validation using - If (InStr(strOutput, "validation text") > 0)
Any Ideas?
Have you considered sending the output from psexec to an output file and then reading the output file from your vbscript?
psexec \\remotemachine command.exe >C:\temp\output.txt 2>&1
will execute command.exe and send output from stdOut and stdErr directly into the file output.txt in C:\temp. You can amend this for your own command.

What's the difference between FSO.DeleteFolder() method and oWS.Run "%comspec% /c rmdir ...", 1, True?

I got a vbs that I wrote.
Set FSO = CreateObject("Scripting.FileSystemObject")
Set oWS = CreateObject("WScript.Shell")
Set objFolderUsers = FSO.GetFolder("\\"& strComputer &"\C$\Users\").Subfolders
...
Later, I do something like :
For Each objFlder In objFolderUsers
user = Right(objFlder, Len(objFlder) - InStrRev(objFlder, "\"))
temp = objFlder & "\AppData\Local\Temp\"
'That's the line !...
If FSO.FolderExists(temp) Then FSO.DeleteFolder(temp)
If Not IsExcludeProfile(user) Then
If Left(objFlder.DateLastModified, 4) <= minYear Then
oWS.Run "%comspec% /c rmdir " & objFlder & " /s /q", 0, True
oWS.Run "%comspec% /c net user " & user & " /delete", 0, True
End If
End If
Next
my question is : Is there a difference between FSO.DeleteFolder(temp) and oWS.Run "%comspec% /c rmdir " & temp, 1, True because when I do the first all things are OK but when I do the second (the oWS.Run) AND objFlder = "Default" it is all deleted, not just the Temp as I want ...
Try to put enclosing quotes in the file name passed to the rmdir, because blank spaces may terminate the string that it receives before its end:
oWS.Run "%comspec% /c rmdir """ & objFlder & """ /s /q", 0, True
Just reminding that "" inside a string literal in vbs means a single " in the contents of the string.

Run a command and capture the output in vbscript

I am trying to run the following command and return the output of it using VBscript:
dir /A-d "C:\Windows\Minidump" | find /c "/"
And I have the following script but it does not work (probably because of " charachters:
Wscript.Echo runCMD("dir /A-d "C:\Windows\Minidump" | find /c "/"")
Function runCMD(strRunCmd)
Set objShell = WScript.CreateObject("WScript.Shell")
Set objExec = objShell.Exec(strRunCmd)
strOut = ""
Do While Not objExec.StdOut.AtEndOfStream
strOut = strOut & objExec.StdOut.ReadLine()
Loop
Set objShell = Nothing
Set objExec = Nothing
runCMD = strOut
End Function
Any suggestions on how to achieve this?
dir is intrinsic; you need %comspec%.
Double quotes need to be escaped by double double quotes in VBScript:
Wscript.Echo runCMD("%comspec% /c dir /A-d ""C:\Windows\Minidump"" | find /c ""/""")

Resources