@echo off

rem For user options, search for text ChangeMe!

rem This batch file has 3 dependancies (which all come with XP/2003)
rem %windir%\system32\Tasklist.exe
rem %windir%\system32\Taskkill.exe
rem System Service: Event Log (tasklist and taskkill will not run without it)
rem Kill.bat can still list/kill processes on a remote 2000 machine, it just can't
rem run in a 2000 shell.

title Kill.bat


If NOT exist "%Windir%\System32\tasklist.exe" (
	echo Tasklist.exe not found in %windir%\system32\...
	echo Kill.bat was designed for use on Windows XP/2003...
	echo Exiting...
	goto end
)

If NOT exist "%Windir%\System32\taskkill.exe" (
	echo Taskkill.exe not found in %windir%\system32\...
	echo Kill.bat was designed for use on Windows XP/2003...
	echo Exiting...
	goto end
)


rem These are declerations (don't touch).  Look a bit further down for user config changes.
set rsys=
set rsysPrefix=
set rusr=
set rpwd=
set rpwdPrefix=
set UseRSysInUsername=
set rusrPrefix1=
set rusrPrefix2=
set UseSvc=
set FilterType=
set DefaultFilter=
set ShowCmd=
set DefPrefix=
set DefSuffix=
set UsePre=
set UseSuf=
set LoopKill=
set ListOnly=
set KillCurTime=%Time::=-%
set KillCurTime=%KillCurTime:.=-%


If "%1" == "/?" goto Help
If "%1" == "-?" goto Help
If "%1" == "--?" goto Help
If "%1" == "?" goto Help
If /I "%1" == "help" goto Help
If /I "%1" == "RESET" goto Reset
If /I "%1" == "-RESET" goto Reset


rem Environment Options (touch these as you wish)
rem -----------------------------------------------------------------------------------------------
rem (ChangeMe!) - Automatic login
rem Set the below, to automatically use Sys/Usr/Pwd options.
rem CAN be over-ridden by command line *and* by Use Previous, if enabled.
rem i.e. If I wanted the user name to default to Administrator
rem I would change 'set autoUsr='  to read 'autoUsr=Administrator'
rem Default: (autoSys=) , (autoUsr=) , (autoPwd=)
set autoSys=
set autoUsr=
set autoPwd=

rem (ChangeMe!) - Use Remote System Name in Username.
rem This is for situations where your network account isn't a domain
rem admin, but you know the local admin user/password.
rem Setting UseRSysInUsername=1 will prefix the username
rem with <CurrentRemotePCName>\
rem i.e.  
rem If the remote computer name is ZhoulsPC
rem If the remote username is Zhoul
rem It will change the remote username to ZhoulsPC\Zhoul
rem You can even set the autoUsr feature above, to Administrator
rem and the autoPwd feature to the local admin password, for prompt free task listing/killing.
rem Default: (UseRSysInUsername=0)
set UseRSysInUsername=0

rem (ChangeMe!) *New Feature* - Show Command
rem Set ShowCmd=1 if you would like to show the command(s) used during execution.
rem Set ShowCmd=0 if you wish to suppress this information from visual output.
rem I.E.
rem If this option were enabled and you typed 'Kill 360' , you would
rem get this as an extra output line.
rem Command  : taskkill /pid 360 /f /t
rem *Note* - Does not show the /p <password> portion of the command.
rem Default: (ShowCmd=1)
set ShowCmd=1



rem (ChangeMe!) - Temp Directory/File (Default=Auto-Detect)
rem One piece of this process uses an output file to dump the process list to.
rem By Default: It is set to detect %temp%, then use a file called tasklist.txt
rem *Update* - Changed to 'Tasklist-Current Time-%Random%.txt 
rem I.E.  Tasklist-13-02-01-53-23456.txt
rem This change was made so multiple instances of kill.bat could run without error.
rem If %temp% doesn't exist, it uses the current directory.
rem This file is deleted right after use.
rem Default: (outfile="%temp%\tasklist-%KillCurTime%-%Random%.txt")
If "%temp%" == "" set temp=.\
set outfile="%temp%\tasklist-%KillCurTime%-%Random%.txt"



rem (ChangeMe!) - Remember System/Username/Password (for session).
rem If you would like to use the 'previous' system/user/password, set
rem this to 1.  I.E. if you open a DOS window and kill \\RemotePC, 
rem the next time you type kill , It will remember you are 'using' RemotePC.
rem These settings will override the Auto settings above, and can be reset
rem via command line by using the -reset switch (kill -reset).
rem These settings can be over-ridden/over-written by command line options.
rem *NOTE* These settings are session based, therefore they *will not*
rem carry over between shell instances / two separate DOS windows.
rem Default: (UsePrevious=0)
set UsePrevious=1



rem (ChangeMe!) - Default Filter Prefix/Suffix
rem Here, you choose how kill.bat will handle image names (or shall  we say, non-PID's) 
rem The prefix and suffix are applied during the filter process in tasklist.
rem Example: If both were set to * , then 'kill blah' would result in killing *blah* 
rem To put it another way, It would kill any process with blah in any part of the name.
rem Setting both the prefix and suffix to nothing would result in having to use very
rem specific image names. 
rem Default settings look for things that begin with the letters you type.
rem Example: kill expl    would kill explorer.exe but not iexplore.exe
rem The prefix and suffix are *not* applied when working with a PID. (that would be bad I think...)
rem Default: (DefPrefix=) , (DefSuffix=*)
set DefPrefix=
set DefSuffix=*


rem (ChangeMe!) - Default Filter (No Description)
rem Default: (DefaultFilter=IMAGENAME eq)
set DefaultFilter=IMAGENAME eq


rem (ChangeMe!)
rem Set NoConfirm=1 if you do not want kill.bat to confirm your kill commands before execution.
rem You can also use the /y switch to auto-confirm.
set NoConfirm=0



rem (ChangeMe!)
rem I can't take it NO MORE!
rem set NoMore=1 if you dislike the "more" program, chopping up your output.
rem set Nomore=0 if you are in a terminal window that does not allow scrolling.
rem Kill.bat can still be piped to more, reguardless...  (i.e. kill|more)
rem Default(NoMore=0)
set NoMore=1


rem REMEMBER: Command Line overrides Previous and Auto
rem REMEMBER: Previous overrides Auto (if enabled)
rem REMEMBER: Auto overrides none of the above.
rem You can also use the -reset switch, to reset the "Previous" override.
rem I.E.   Kill -reset
rem ...will set all the previous variables to nothing, letting your default system/user/pass take effect.
rem The -reset switch is completely useless if you do not have UsePrevious set to 1, above.
rem Why? Because the previous variables only get set IF UsePrevious is 'enabled'.
rem -----------------------------------------------------------------------------------------------


:ActivateAuto
rem -----------------------------------------------------------------------------------------------
  If DEFINED autoSys set rsys=%autoSys% 
  If DEFINED autoUsr set rusr=%autoUsr% 
  If DEFINED autoPwd set rpwd=%autoPwd% 
rem -----------------------------------------------------------------------------------------------


:ActivateUsePrev
rem -----------------------------------------------------------------------------------------------

If "%UsePrevious%" == "1" (
  If DEFINED prevSys set rsys=%prevSys%
  If DEFINED prevUsr set rusr=%prevUsr%
  If DEFINED prevPwd set rpwd=%prevPwd%
)
rem -----------------------------------------------------------------------------------------------


:ParseArgs
rem -----------------------------------------------------------------------------------------------

set parseArg=%1
set parseArg=%parseArg:~0,2%

If /I "%parseArg%" == "\\" goto RSys2
If /I "%1" == "-r" goto RSys
If /I "%1" == "-s" goto RSys
If /I "%1" == "/r" goto RSys
If /I "%1" == "/s" goto RSys

If /I "%1" == "-u" goto RUsr
If /I "%1" == "/u" goto RUsr

If /I "%1" == "-p" goto RPwd
If /I "%1" == "/p" goto RPwd

If /I "%1" == "-y" goto NoConf
If /I "%1" == "/y" goto NoConf

If /I "%1" == "-list" goto ListOnly
If /I "%1" == "/list" goto ListOnly

If /I "%1" == "-n" goto ListOnly
If /I "%1" == "/n" goto ListOnly

If /I "%1" == "-l" goto SetLoopKill
If /I "%1" == "/l" goto SetLoopKill


If /I "%1" == "/svc" goto SvcEnum

If "%rsys%" == "" (
set rsys=
set rusr=
set rpwd=
)
if DEFINED rsys set rsysPrefix= /S 
if DEFINED rpwd set rpwdPrefix= /P 
If DEFINED rusr (set rusrPrefix1= /U ) else (goto ParseArgs2)
If NOT DEFINED UseRSysInUsername goto ParseArgs2
If NOT "%UseRSysInUsername%" == "1"  goto ParseArgs2
If NOT DEFINED rsys goto ParseArgs2
echo %rusr%|find "\"|rem
if "%errorlevel%" == "0" goto ParseArgs2
echo %rusr%|find "@"|rem
if "%errorlevel%" == "0" goto ParseArgs2
set rusrPrefix2=%rsys:~2%\


:ParseArgs2

rem Dos box title handling...
set Titletmp=Kill.bat
If "%rSys%" == "" (
	set Titletmp=%Titletmp% -- System: %computername%
) else (
	set Titletmp=%Titletmp% -- System: %rsys%
	prompt [System: %rsys%] - $p$g
)
If "%rUsr%" == "" (
	set Titletmp=%Titletmp% -- User: %Username% [Default]
) else (
	set Titletmp=%Titletmp% -- User: %rusrPrefix2%%rUsr%
)
If "%rPwd%" == "" (
	set Titletmp=%Titletmp% -- Password: [Default]
) else (
	set Titletmp=%Titletmp% -- Password: [User Specified]
)
Title %Titletmp%

If "%1" == "" (goto List) else (goto GoFigure)

:RSys
rem -- Remote System --
SHIFT
:RSys2
set rsys=%1
If "%rsys%" == "" (
        echo You specified the -r or -s option, but failed to specify the remote system there after.
	goto end
)
set rsystmp=%rsys:~0,2%

If NOT "%rsystmp%"  == "\\" set rsys=\\%rsys%

echo Remote System [ %rsys% ] accepted from command line...
SHIFT
goto ParseArgs


:RUsr
rem -- Remote Username --
SHIFT
set rusr=%1 
set rusr=%rusr: =%
If "%rusr%" == "" (
	echo  You specified the -u option, but failed to specify the remote username there after.
	goto end
)
echo Remote Username [%rusrPrefix2%%rusr%] accepted from command line...
SHIFT
goto ParseArgs


:RPwd
rem -- Remote Password --
SHIFT
set rpwd=%1 
If "%rpwd%" == "" (
	echo You specified the -p option, but failed to specify a password there after.
	goto end
)
echo Remote Password accepted from command line...
SHIFT
goto ParseArgs

:SvcEnum
rem -- Use /svc switch --
set UseSvc= /svc 
SHIFT
goto ParseArgs

:NoConf
rem -- No Confirmation --
set NoConfirm=2
SHIFT
goto ParseArgs

:ListOnly
rem -- Auto-Answer No to process kill confirm question (Don't ask, just list) --
set ListOnly=1
SHIFT
goto ParseArgs

:SetLoopKill
rem -- Loop Killing --
set LoopKill=1
set LoopKillCount=20
set CurLoopCount=20
SHIFT
goto ParseArgs


rem -----------------------------------------------------------------------------------------------


:EnvVar2
rem Environment Variables 2
rem -----------------------------------------------------------------------------------------------


If "%1" == "" (goto List) else (goto GoFigure)

rem -----------------------------------------------------------------------------------------------




:GoFigure
rem -----------------------------------------------------------------------------------------------
set CurArg=%1
SHIFT

If "%CurArg%" == "" goto End

echo.

If /I "%CurArg%" == "/pid" (
	set FilterType=PID eq
	set UsePre=
	set UseSuf=
	SHIFT
	set CurArg=%1
	goto Proc
)

If /I "%CurArg%" == "-pid" (
	set FilterType=PID eq
	set UsePre=
	set UseSuf=
	SHIFT
	set CurArg=%1
	goto Proc
)

If /I "%CurArg%" == "/im" (
	set FilterType=IMAGENAME eq
	set UsePre=%DefPrefix%
	set UseSuf=%DefSuffix%
	SHIFT
	set CurArg=%1
	goto Proc
)

If /I "%CurArg%" == "-im" (
	set FilterType=IMAGENAME eq
	set UsePre=%DefPrefix%
	set UseSuf=%DefSuffix%
	SHIFT
	set CurArg=%1
	goto Proc
)


set FilterType=%DefaultFilter%
set UsePre=%DefPrefix%
set UseSuf=%DefSuffix%

If %CurArg% geq 0 (
        If %CurArg% leq 9999 (
		set FilterType=PID eq
		set UsePre=
		set UseSuf=
	)
)

goto Proc


rem -----------------------------------------------------------------------------------------------/



:Proc
rem -----------------------------------------------------------------------------------------------\

echo.
echo /----------------------------------------------------------------------\
If "%rsys%" == "" (
echo System   : %computername% [default]
set rusr=
set rpwd=
) else (
echo System   : %rsys%
)

If "%rusr%" == "" (
echo User     : %userdomain%\%username% [default]
) else (
echo User     : %rusrPrefix2%%rusr%
)

If "%rpwd%" == "" (
echo Password : [default]
) else (
echo Password : [specified]
)

If "%ShowCmd%" == "1" (
	echo Command  : tasklist%UseSvc%%rsysPrefix%%rsys%%rusrPrefix1%%rusrPrefix2%%rusr% /FI "%FilterType% %UsePre%%CurArg%%UseSuf%"
)
echo ------------------------------------------------------------------------
tasklist%UseSvc%%rsysPrefix%%rsys%%rusrPrefix1%%rusrPrefix2%%rusr%%rpwdPrefix%%rpwd% /FI "%FilterType% %UsePre%%CurArg%%UseSuf%" >%outfile%
If NOT "%NoMore%" == "1" (more /p /e /s /T0 %outfile%) else (type %outfile%)
find /c "PID" %outfile%|rem
If "%errorlevel%" == "1" (
	echo.
	goto GoFigure
)
del %outfile%
echo.
echo.
if "%ListOnly%" == "1" (
	goto GoFigure
)
echo Press [Enter] to kill the above task(s), or type 'n' [Enter] to abort.
If "%NoConfirm%" == "1" (
	echo Auto-Confirm - Reason:  Kill.bat setting.
	goto ExecKill
)
If "%NoConfirm%" == "2" (
	echo Auto-Confirm - Reason: Command line option /y.
	goto ExecKill
)
set Continue=
set /p Continue=
set ContinuePart=%Continue:~0,1%
If /I "%ContinuePart%"=="n" (
	echo.
	echo User aborted process kill command.
	goto GoFigure
)
If /I "%ContinuePart%"=="r" (
	goto Proc
)

:ExecKill
echo.
If "%ShowCmd%" == "1" (
	echo Command: taskkill%rsysPrefix%%rsys%%rusrPrefix1%%rusrPrefix2%%rusr% /FI "%FilterType% %UsePre%%CurArg%%UseSuf%" /f /t
)
taskkill%rsysPrefix%%rsys%%rusrPrefix1%%rusrPrefix2%%rusr%%rpwdPrefix%%rpwd% /FI "%FilterType% %UsePre%%CurArg%%UseSuf%" /f /t >%outfile%
If NOT "%NoMore%" == "1" (more /p /e /s /T0 %outfile%) else (type %outfile%)
del %outfile%
echo.
If /I NOT "%LoopKill%" == "1" goto GoFigure
If %CurLoopCount% leq 1 (
	echo Loop kill complete.
	set CurLoopCount=%LoopKillCount%
	goto GoFigure
)
echo Looping kill command %CurLoopCount% more times.
set /a CurLoopCount=%CurLoopCount%-1
goto ExecKill

rem -----------------------------------------------------------------------------------------------/




:List
rem -----------------------------------------------------------------------------------------------\

echo.
echo /----------------------------------------------------------------------\
If "%rsys%" == "" (
	echo System   : %computername% [default]
) else (
	echo System   : %rsys%
)

If "%rusr%" == "" (
	echo User     : %userdomain%\%username% [default]
) else (
	echo User     : %rusrPrefix2%%rusr%
)

If "%rpwd%" == "" (
	echo Password : [default]
) else (
	echo Password : [specified]
)

If "%ShowCmd%" == "1" (
	echo Command  : tasklist%UseSvc%%rsysPrefix%%rsys%%rusrPrefix1%%rusrPrefix2%%rusr%
)

echo ------------------------------------------------------------------------
tasklist%UseSvc%%rsysPrefix%%rsys%%rusrPrefix1%%rusrPrefix2%%rusr%%rpwdPrefix%%rpwd%>%outfile%
If NOT "%NoMore%" == "1" (more /p /e /s /T0 %outfile%) else (type %outfile%)
find /c "PID" %outfile%|rem
del %outfile%
If /I "%LoopKill%" == "1" (
	echo.
	echo Looping in 4 seconds... Press CTRL+C to exit.
	ping 127.0.0.1|rem
	goto List
)

goto End
rem -----------------------------------------------------------------------------------------------


:Help
rem -----------------------------------------------------------------------------------------------
echo.
echo.
echo ================================================================================
echo                              Kill.bat - Designed by Zhoul
echo ================================================================================
echo.
echo Syntax:
echo   "Kill [-s [System]] [-u [Username]] [-p [Password] [[PID] || [Image Name]]"
echo   "Kill -reset" (Only use this option if you have enabled UsePrevious)
echo.
echo.
echo Example: Kill
echo.
echo   This would simply run tasklist.exe and display the results, using More (incase 
echo   task list is longer then window buffer).
echo.
echo.
echo Example: Kill 989
echo.
echo   This would kill the local process with PID 989.
echo.
echo.
echo Example: Kill iexpl
echo.
echo   This would kill any process with an ImageName starting with iexpl
echo   (first column listed in tasklist, i.e. iexplore.exe) 
echo.   
echo   Such as: iexplore , iexplorer, iexplblahblahblah, iexplore.exe
echo.
echo   This would NOT affect a process named prqiexplore.exe, as the string search
echo   will match "Starts with or Equals" and not "Contains or Equals"
echo   If you wanted to kill prqiexplore.exe and iexplore.exe, you could . . .  
echo   kill *iexpl*
echo.
echo ================================================================================
pause
echo ================================================================================
echo.
echo Example: Kill 989 iexpl 1000 badthing
echo.
echo   This would kill the local process with PID 989, any ImageName that starts with
echo   iexpl, PID 1000, any ImageName that starts with badthing.  Yep, you can take 
echo   out multiple processess in the same kill line.
echo.
echo.
echo Example: Kill -s RemotePC
echo.
echo   This would execute a tasklist on the RemotePC, using your current credentials.
echo.
echo Example: Kill \\RemotePC
echo   Same as previous.
echo.
echo.
echo Example: Kill -s RemotePC -u RemotePC\Administrator -p RemotePCPassword
echo      Or: Kill \\RemotePC -u RemotePC\Administrator -p RemotePCPassword
echo.
echo   If the locally logged in user is not an Administrator of RemotePC, you will
echo   have to specify a user and password.
echo   Remember: If you just specify a Username and not a server before it, it will
echo   assume you mean a user on the local PC.
echo   User can be:  [user]      or     [domain]\[user]     or   [user]@[domain]
echo   I.E.           Zhoul              ZhoulsPC\Zhoul           Zhoul@ZhoulsPC
echo.
echo.
echo Example: Kill -s RemotePC -u RemotePC\Administrator -p RemotePCPassword 500
echo.
echo   Kills PID 500 on RemotePC, using specified credentials.
echo.
echo.
echo Example: Kill -s RemotePC iexpl 500 calc
echo.
echo   Kills ImageName starting with iexpl, PID 500, ImageName starting with calc, on
echo   the RemotePC using your current credentials.
echo.
echo ================================================================================
goto End
rem -----------------------------------------------------------------------------------------------



:Reset
rem -----------------------------------------------------------------------------------------------
echo.
echo Resetting previously used System/User/Pass variables to defaults.
set prevSys=
set prevUsr=
set prevPwd=
set rsys=
set rusr=
set rusrPrefix=
set rpwd=
set autoSys=
set autoUsr=
set autoPwd=
set NoMore=
prompt
Title Kill.bat - Reset Previous System/User/Pass Complete
echo.
goto END
rem -----------------------------------------------------------------------------------------------



:End
rem -----------------------------------------------------------------------------------------------
If NOT "%UsePrevious%" == "1" goto ABSEnd
set prevSys=%rsys%
set prevUsr=%rusr%
set prevPwd=%rpwd%

:ABSEnd
set rsys=
set rusr=
set rpwd=
set autoSys=
set autoUsr=
set autoPwd=
set NoMore=
set UseSvc=
set ContinuePart=
set ShowCmd=
set DefPrefix=
set DefSuffix=
set DefaultFilter=
set FilterType=
set OutFile=
set Titletmp=
set UsePre=
set UseSuf=
set NoConfirm=
set ListOnly=
set ParseArg=
set UsePrevious=
set ArgPart=
set LoopKill=
set rsystmp=
set UseRSysInUsername=
set rusrPrefix1=
set rusrPrefix2=
set rpwdPrefix=
set rsysPrefix=
set LoopKillCount=
set LoopCurCount=
set KillCurTime=
rem -----------------------------------------------------------------------------------------------
