I'm trying to write a cmd that will stop all instances of PostgreSQL on my server
net start | find /I "postgres"
returns all my running instance
I thought this would work
net start | find /I "postgres" | net stop
no luck
I also looked at
for /F "delims=" %A in ('net start | find /I "postgres"') do echo %A
There must be some way to do this
As far as I know the cmd does not provide text trimming function, right? I tried PowerShell with
net start | ? { $_.Contains("postgres")} | % { net stop $_.Trim() }
and works (with UAC of course).
To explain,
? is alias of Where-Object, whilst
% is alias of ForEach-Object, and
$_ is to mention piped element. In this case, every element from traversing array by ForEach-Object(%) is piped into inner expression.
These aliases and commands are available for a help text by Get-Help {func} or man {func}.
wmic service where name='lanmanserver' call stopservice
does lanmanserver, adjust to your program.
wmic /?
wmic service get /?
wmic service call /?
Or same objects in vbscript.
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * From Win32_Service")
For Each objItem in colItems
'msgbox objItem.caption
If LCase(objItem.name) = "lanmanserver" then msgbox objItem.stopservice
Next
Related
I am trying to create an automated process that will clean user data on every login to a laptop. The main parts are finished and I am in the polishing phase. I have two batch files run on startup that cleans user data from the profile being logged into and they both work. My issue comes with the the cmd window that appears behind my dialogue box (See picture).
Researching how to get this cmd box to be invisible lead me to VBS. I did find a solution for that, but now the dialogue box does not show at all. I believe it is probably because the VBS script is making all windows prompts invisible.
Bottom line is, how can I get my dialogue box to appear without the CMD window opening with it?
The VBScript is currently running under the common startup folder here:
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
Deletion script:
#echo off
::Set color of script
color 0a
::Title
title Loaner data wipe
set userpreserve="Administrator,All Users,Default,Public,barfiej"
::All files and folders within the parent folders below will be deleted.
c:
del /S /F/ Q "C:\Users\%USERNAME%\AppData\Local\Microsoft\Outlook\*"
del /S /F/ Q "C:\Users\%USERNAME%\Contacts\*"
del /S /F/ Q "C:\Users\%USERNAME%\Desktop\*"
del /S /F/ Q "C:\Users\%USERNAME%\Documents\*"
del /S /F/ Q "C:\Users\%USERNAME%\Downloads\*"
del /S /F/ Q "C:\Users\%USERNAME%\Favorites\*"
del /S /F/ Q "C:\Users\%USERNAME%\Links\*"
del /S /F/ Q "C:\Users\%USERNAME%\Music\*"
del /S /F/ Q "C:\Users\%USERNAME%\OneDrive\*"
del /S /F/ Q "C:\Users\%USERNAME%\OneDrive - Six Continents Hotels, Inc\*"
del /S /F/ Q "C:\Users\%USERNAME%\Pictures\*"
del /S /F/ Q "C:\Users\%USERNAME%\Saved Games\*"
del /S /F/ Q "C:\Users\%USERNAME%\Searches\*"
del /S /F/ Q "C:\Users\%USERNAME%\Videos\*"
::Clear credential manager
For /F "tokens=1,2 delims= " %G in ('cmdkey /list ^| findstr Target') do cmdkey /delete %H
Dialogue box cmd:
powershell -Command "Add-Type -AssemblyName System.Windows.Forms; C:\ProgramData\LoanerBatchFile\dialogue_box.ps1;"
dialogue_box.ps1:
Add-Type -AssemblyName System.Windows.Forms
[System.windows.forms.messagebox]::show("Welcome to your loaner computer.
`nPlease keep the follow the following instructions while using the loaner laptop.
`n- Save all documents to OneDrive. Data is set to be removed from the user profile at each logoff
`n- Use Webmail
`n- Please keep the computer clean
`n- Be sure to return loaner when picking up your computer");
VBS script:
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\ProgramData\LoanerBatchFile\UserDataDeletion.bat" & Chr(34), 0
WshShell.Run chr(34) & objShell.Run("C:\ProgramData\LoanerBatchFile\dialogue.bat") & Chr(34), 0
Set WshShell = Nothing
You can try the alternative way:
$wsh = New-Object -ComObject Wscript.Shell
[Void]$wsh.PopUp("Message content here")
As a followup to my initial comment above.
Untested, because I've nothing to test this concept on, but, roughly something like...
Add-Type -AssemblyName System.Windows.Forms
& cmd.exe set userpreserve="Administrator,All Users,Default,Public,barfiej"
# All files and folders within the parent folders below will be deleted.
'C:\Users\%USERNAME%\AppData\Local\Microsoft\Outlook\*',
'C:\Users\%USERNAME%\Contacts\*',
'C:\Users\%USERNAME%\Desktop\*',
'C:\Users\%USERNAME%\Documents\*',
'C:\Users\%USERNAME%\Downloads\*',
'C:\Users\%USERNAME%\Favorites\*',
'C:\Users\%USERNAME%\Links\*',
'C:\Users\%USERNAME%\Music\*',
'C:\Users\%USERNAME%\OneDrive\*',
'C:\Users\%USERNAME%\OneDrive - Six Continents Hotels, Inc\*',
'C:\Users\%USERNAME%\Pictures\*',
'C:\Users\%USERNAME%\Saved Games\*',
'C:\Users\%USERNAME%\Searches\*',
'C:\Users\%USERNAME%\Videos\*' |
ForEach { Remove-Item -Path $PSItem -Recurse -Force}
<#
https://learn.microsoft.com/en-us/archive/blogs/rmilne/script-to-clear-credman
#>
& cmd.exe For /F "tokens=1,2 delims= " %G in ('cmdkey /list ^| findstr Target') do cmdkey /delete %H
[System.windows.forms.messagebox]::show(
"Welcome to your loaner computer.
`nPlease keep the follow the following instructions while using the loaner laptop.
`n- Save all documents to OneDrive. Data is set to be removed from the user profile at each logoff
`n- Use Webmail
`n- Please keep the computer clean
`n- Be sure to return loaner when picking up your computer"
)
Again, put this in logon/startup scheduled task assigned to RunOnce, or at logon.
I get two results when I run this:
tasklist /FI "imagename eq PROCESS.exe"
Image Name PID Session Name Session# Mem Usage
========================= ======== ================ =========== ============
PROCESS.exe 2760 Console 1 8,156 K
PROCESS.exe 20160 Console 1 9,060 K
But I only want to kill ONE of them...
If I open up the Task Manager, I can see that each of my processes have different descriptions.
So all I need to do, is somehow filter by process description.
Can anyone help, please?
Thank you!
Use the following to distinguish the processes according to their own process ID and their parent process ID:
wmic process get processid,parentprocessid,executablepath | find "PROCESS"
This way, you can find the process ID to kill.
wmic grants access to additional process properties.
Use wmic process get /? to find out what is available.
Another potentially helpful tool is PsList of Microsoft/Sysinternals.
If you want to filter your process list by the window title, just use
tasklist /FI "windowtitle eq Title"
As addition to #Axel's answer with WMI - the same for description:
WMIC Process WHERE "Description='Only One'" GET ProcessID
And in VBS:
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Process WHERE Description = 'My Desc'",,48)
For Each objItem in colItems
'Do Stuff
Next
Another possible value for description is the assembly's description which is retrievable with PowerShell. Use Get-Process to obtain the assembly path and retrieve its description with [System.Diagnostics.FileVersionInfo]::GetVersionInfo($File).FileDescription.
I have a batch file that I use every time I start my work PC. Basically, it kills all the bloatware that the IT department puts on the PC that run as my user account that I never even use using taskkill, installs a small program, then loads all the programs I actually need at once. Problem is, one of the programs that I run, the IT department recently thought it would be helpful to install a "helper" program to automate some things within the program that I already know how to do and can do it fairly quickly manually. Problem is, the helper program actually has the reverse effect and slows the actual program down. We are of course complaining to IT about it but it'll probably take them months to fix it, if ever. In the meantime, I found out that the helper program runs as it's own process under my user account, which means I can kill it, and everything runs smoothly again. Problem is, how the program runs. I launch the program normally and this happens:
Process A loads. Process A loads process B. Process A kills itself. Process B loads process C. Process C loads process D, E, and F (the helper programs). Process B kills itself, while leaving C, D, E, and F in memory (program is fully loaded at this point)
How can I have the batch file just wait for process B to kill itself, before proceeding with the taskkill commands to kill processes D, E, and F? Since the command line only sees process A when directly calling the EXE, it resumes the batch file in under a second since A kills itself that quickly. I can't just use timeout or some other generic time waster because the load time of the program is too volatile, what with network issues, program updates, etc.
I built something exactly like this a few years ago, but unfortunately don't have the code with me and don't have access to a Windows machine at the moment.
However, it should be fairly simple, and will be along these lines (just tweak the code to get it work or let me know if there are any issues; I can't test it but should be able to fix them if I know what they are):
rem Usage: :killprocesswithwait [pid]
call :killprocesswithwait 1234
:killprocesswithwait
set pid=%1
taskkill /pid %pid%
:iloop
ping 127.0.0.1 -n 2 > nul
for /f "tokens=*" %%a in ('tasklist /fi "PID eq %pid%" ^| find /i %pid%') do (
if /i "%%a"=="" (
goto :eof
) else (
goto :iloop
)
)
This waits for a any and all programs to exit and checks if Notepad and restarts it if it is.
It surely would be better to wait for the three programs to start. Change Win32_ProcessStopTrace to Win32_ProcessStartTrace.
Set WshShell = WScript.CreateObject("WScript.Shell")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM Win32_ProcessStopTrace")
Do
Set objReceivedEvent = objEvents.NextEvent
msgbox objReceivedEvent.ProcessName
If lcase(objReceivedEvent.ProcessName) = lcase("Notepad.exe") then
Msgbox "Process exited with exit code " & objReceivedEvent.ExitStatus
WshShell.Run "c:\Windows\notepad.exe", 1, false
End If
Loop
And this lists processes and terminate any called calculator.
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")
For Each objItem in colItems
'msgbox objItem.ProcessID & " " & objItem.CommandLine
If objItem.name = "Calculator.exe" then objItem.terminate
Next
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q36241667.txt"
SET "filename2=%sourcedir%\q36241667_2.txt"
:dloop
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
tasklist|FIND "%%a" >NUL
IF ERRORLEVEL 1 timeout /t 1 >nul&GOTO dloop
)
FOR /f "usebackqdelims=" %%a IN ("%filename2%") DO ECHO(%%a
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I used files named q36241667.txt & q36241667_2.txt containing some dummy data for my testing.
Suppose filename1 contains
processa.exe
processb.exe
processc.exe
processd.exe
processe.exe
then the for loop will wait until all of the processes are running before proceeding.
filename2 contains the kill commands required (echoed for demo purposes)
If this routine is simply started in your startup routine, then it could itself trigger start commands to kill any unwanted processes.
I use a similar routine to back up critical directories to a ramstick on start-up.
Thanks guys, I actually took Ruslan's answer and simplified and changed it a bit. This works great. Waits for exe3 to load since it's the last one to load, then kills all 3. Didn't need to set the variables so removed those and completely forgot about putting it in a loop.
:start
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq exe3.exe"') DO IF %%x == exe3.exe goto found
goto start
:found
taskkill /f /fi "blah1.exe"
taskkill /f /fi "blah2.exe"
taskkill /f /fi "blah3.exe"
can someone think of a solution for something like this? :
Program/script logic: It would constantly monitor the windows OS for a process starting within it (***1.exe) (I guess it could constantly run via task scheduler to do the constant monitoring?) , while it sees that ***1.exe is running, it would kill/end another process ***2.exe, and once ***1.exe would go away, it would no longer be stopping the ***2.exe process.
I think it could be either a bash script, powershell script, or a windows service?
Thanks!!!
You can use the Register-CimIndicationEvent cmdlet to register for events raised by Win32_ProcessStartTrace WMI class:
# Define which events to listen for
$NewProcessQuery = "SELECT ProcessId,ProcessName FROM Win32_ProcessStartTrace WHERE ProcessName LIKE '%1.exe'"
# Define the code to run every time a new process is created
$ProcessAction = {
# See if any instances of *2.exe processes are running
if(($TargetProcess = Get-CimInstance -ClassName Win32_Process -Filter "Name LIKE '%2.exe'"))
{
# Terminate them
$TargetProcess |Invoke-CimMethod -MethodName Terminate
}
}
# Register for the event
Register-CimIndicationEvent -Query $NewProcessQuery -SourceIdentifier ProcessCreated
So since the solution above was for only windows 2012 and up, I decided to try another solution. This should work for regular processes, but I'll have to try something else rather than %ERRORLEVEL% because the process I'm monitoring is originally an msi installer and seems like it returns and errorlevel of 1 all the time (running or not) while regular processes return 0 or 1 depending on the status. The process I'm ending starts back up automatically, that's the reason there's no start service command included in here, timeout was set to 62 seconds because the service starts back up automatically every 60 seconds, a /NOBREAK can be added if wanted to eliminate the possibility of user input starting it (if this would be ran without a task scheduler,etc.)
:loop_check
TIMEOUT /T 62
TASKLIST /FI "IMAGENAME eq process.exe" 2>NUL | find /I /N "process.exe">NUL
IF "%ERRORLEVEL%"=="0" (
GOTO stop_process2
) ELSE (
GOTO loop_check
)
:stop_process2
ECHO killing task
TASKKILL /F /IM process2.exe
GOTO loop_check
Read my previous reply/comment before this one for more clarity. This is the final solution that worked for me. A star(*) is included at the end of the 'BeginningOfApplicationName' because the installer/msi I'm detecting has sometimes different names based on it's version, so it finds/finishes the ending (wildcard). Since the name of the process I'm monitoring can have different names, I couldn't compare it to a static string, so I'm comparing it to INFO: , seems thats what windows (2008 and 2012!) both print out when a process is not found.
#ECHO OFF
SETLOCAL EnableExtensions
:loop_check
TIMEOUT /T 62
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq BeginningOfApplicationName*"') DO IF %%x == INFO: (
GOTO loop_check
) ELSE (
GOTO stop_process
)
:stop_process
TASKKILL /F /IM process.exe
GOTO loop_check
Quite simply, how does one determine whether or not Tomcat is running in Windows, using the command prompt?
I am writing a batch script that must do this. This is the Bash version:
RESULT=`netstat -na | grep $2 | awk '{print $7}' | wc -l`
Where $2 is the port.
I am looking for something similar to that. Using Cygwin is out of the question, of necessity this script must be able to run on machines that only have Tomcat.
Test the status of the Tomcat Service with the SC command. MJB already suggested to test the service status with SC, yet another batch script (without FOR loop) for testing the status:
#ECHO OFF
SC query tomcat5 | FIND "STATE" | FIND "RUNNING" > NUL
IF ERRORLEVEL 1 (
ECHO Stopped
) ELSE (
ECHO Running
)
If you are not sure if the service name is tomcat5 you can list all service names with
SC query state= all | FIND "SERVICE_NAME"
You could use tasklist to check if the tomcat executable is running. For example:
#echo off
tasklist /FI "IMAGENAME eq tomcat.exe" | find /C /I ".exe" > NUL
if %errorlevel%==0 goto :running
echo tomcat is not running
goto :eof
:running
echo tomcat is running
:eof
It is also possible to check a remove server using the options /S, /U and /P. See tasklist /? for details.
Using WMIC
#echo off
wmic process list brief | find /i "tomcat.exe"
set result=%ERRORLEVEL%
if "%result%"=="1" echo "not running"
if "%result%"=="0" echo "running"
note : /i is to make the find operation case-insensitive.
This is the Windows version of the netstat based UNIX/LINUX solution asked in the question:
#echo off
netstat -na | find "LISTENING" | find /C /I ":8080" > NUL
if %errorlevel%==0 goto :running
echo tomcat is not running
goto :eof
:running
echo tomcat is running
:eof
Well, I am not very good with scripts but perhaps you could use this as a starting point:
netstat -a -n | findstr :8005
To get if someone is listening in port 8005. That is Tomcat's default port for remote administration, i.e. startup or shutdown.
Alternatively you could use the port that the http server listens to.
Hope this helps
use netstat -a in command prompt.
You'll find 8080 port listed there.
If you run Tomcat for Windows not like a service and don't want to exploit JMX the best way is
for /F %%I in ('tasklist /FI "WINDOWTITLE eq Tomcat" /NH') do if %%I==java.exe goto alreadyRun
where:
Tomcat - the window title of the Tomcat's terminal window by default
java.exe - the name of the Tomcat's processe. NOT tomcat.exe.
Yet another option, since this is probably running as a service
FOR /F "tokens=4 delims= " %%A IN ('SC QUERY tomcat5 ^| FIND "STATE"') DO SET status=%%A
echo "%status%"
status can be things like STOPPED, RUNNING ...
I check it by calling a vb script from command line
cscript //nologo checkurl.vbs | findstr "200"
IF errorlevel 1 GOTO :not_running
Save the below script as checkurl.vbs and replace the ip with machines ip
' Create an HTTP object
myURL = "http://10.1.1.1:8080/"
Set objHTTP = CreateObject( "WinHttp.WinHttpRequest.5.1" )
' Download the specified URL
objHTTP.Open "GET", myURL, False
On Error Resume Next
objHTTP.Send
intStatus = objHTTP.Status
If intStatus = 200 Then
WScript.Echo intStatus
Else
WScript.Echo "Error Connecting"
End If
I had problems with using sc query command, because even if tomcat crashed, the service would still be shown as running where in actual the port was not accessible
You can try searching for the process and extracting the line
For example:
ps|grep tomcat