Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Завершение процессов, не указанных в списке (http://forum.oszone.net/showthread.php?t=208639)

Anonymоus 09-06-2011 22:49 1691741

Завершение процессов, не указанных в списке
 
Доброго времени суток, уважаемые. Не так давно мне пришлось решить задачу, требующую завершения всех процессов, кроме указанных в "белом списке". Написал вот такой скрипт, он работает, но есть одна неувязочка - в белый список приходится вносить и процесс cmd.exe, чтобы скрипт не прерывал свою же работу. Хотелось же, чтобы скрипт завершал работу всех остальных запущенных процессов cmd.exe (если такие будут обнаружены) кроме своего собственного. Не могу понять, как подступится к проблеме, может кто поможет? И еще, кажется что в скрипте слишком много "костылей", буду рад любым советам по упрощению\оптимизации.

Код:

@Echo Off
SetLocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
Call :CheckOS
If %ErrorLevel%==1 Exit /B
:: Файл со списком разрешённых процессов
Set #WhitelistFile=%~sdp0whitelist.txt


:: Чтение файла со списком разрешённых процессов
:ReadList
Set /A i=0
For /F "tokens=*" %%l in (%#WhitelistFile%) Do (
        Set /A i+=1
        Set _Whitelist!i!=%%l
)
Set Whitelist_strings=!i!

:: Получение списка процессов (кроме System и System Idle)
:GetProcList
Set ProcList_Strings=0
For /F "tokens=1,2* skip=4 delims=," %%P In ('tasklist /FO CSV') Do (
        Call :Add Proclist %%~P
)

Call :Purge whitelist
Call :Purge proclist
Call :Compare
EndLocal
Exit /B

:: Вывод содержимого списка
:: (не используется, для отладки)
:Dump
Set $ListName=%*
Set /A #StrCount=!%$ListName%_strings!
Echo.
Echo ==[%$ListName%]=======:
For /L %%S In (1,1,%#StrCount%) Do (
        Echo [%%S] !_%$ListName%%%S!
)
Echo.
Exit /B 0

:: Сравнение списков, завершение не разрешенных процессов
:Compare
For /L %%S In (1,1,%Proclist_strings%) Do (
        Set $TmpStringData=!_Proclist%%S!
        Set isUnknown=True
        For /L %%S In (1,1,%Whitelist_strings%) Do (
                Set $WhitelistString=!_Whitelist%%S!
                If !$TmpStringData!==!$WhitelistString! Set isUnknown=False
        )
        If !isUnknown!==True taskkill /F /IM "!$TmpStringData!"
)
Exit /B 0

:: Добавка строки
:Add
Set $ListName=
Set $ListString=
For /F "tokens=1,* delims= " %%n In ("%*") Do (
        Set $ListName=%%n
        Set $ListString=%%~o
)
Set /A $StrCount=!%$ListName%_strings!
Set /A $StrCount+=1
Set _%$ListName%%$StrCount%=%$ListString%
Set %$ListName%_strings=%$StrCount%
Exit /B 0

:: Очистка от одинаковых строк
:Purge
Set $ListName=%*
Set /A #StrCount=!%$ListName%_strings!
:PurgeLoop
Set /A $TmpStringNum=0
For /L %%S In (1,1,%#StrCount%) Do (
        Set $TmpStringNum=%%S
        Set $TmpStringData=!_%$ListName%%%S!
        For /L %%D In (1,1,%#StrCount%) Do (
                If Not %%D==!$TmpStringNum! (
                        If "!_%$ListName%%%D!"=="!$TmpStringData!" Call :Delete %$ListName% %%D&&GoTo PurgeLoop
                        )
        )
)
Exit /B 0

:: Удаление строки, сдвиг номеров следующих за ней
:Delete
Set $ListName=
Set $ListStringNum=
For /F "tokens=1,* delims= " %%n In ("%*") Do (
        Set $ListName=%%n
        Set $ListStringNum=%%o
)
Set /A #StrCount=!%$ListName%_strings!
Set /A i=0
For /L %%S In (1,1,%#StrCount%) Do (
        If Not %%S==%$ListStringNum% Set /A i+=1
        If Not %%S==%$ListStringNum% Set _%$ListName%!i!=!_%$ListName%%%S!
)
Set _%$ListName%%#StrCount%=
Set %$ListName%_strings=%i%
Exit /B 0

:: Проверка на версию ОС (На Win7 и Vista скрипт не проверялся,
:: поэтому и запускаться он там не будет)
:CheckOS
For /F "tokens=1,2* delims=[" %%A In ('ver') Do (
        Set $TmpString=%%B
        For /F "tokens=1,2* delims= " %%A In ("!$TmpString!") Do (
                Set $TmpString=%%B
                For /F "tokens=1,2* delims=]" %%A In ("!$TmpString!") Do (
                        Set $TmpString=%%A
                        For /F "tokens=1,2,3 delims=." %%A In ("!$TmpString!") Do (
                        Set VerMajor=%%A
                        Set VerMinor=%%B
                        Set VerBuild=%%C
                        )
                )
        )
)
Set bCompatibleOS=false
Echo 5.0 5.1|findstr /R "\<!VerMajor!.!VerMinor!\>">nul&&Set bCompatibleOS=true
If %bCompatibleOS%==false (
ChCp 866>nul
Echo.
Echo Ваша операционная система не поддерживается
Echo Для выхода нажмите любую кнопку...
Echo.
Pause>nul
Exit /B 1
)
Exit /B 0

UPD 28.03.12:
Добавлен усовершенствованный вариант этого скрипта, работающий без WMIC для тех, кому по какой-то причине не подходит вариант от amel27
http://forum.oszone.net/post-1888484-3.html

amel27 10-06-2011 06:40 1691838

Цитата:

Цитата Anonymоus
завершения всех процессов, кроме указанных в "белом списке" »

мне представляется как-то так:
Код:

@echo off
SetLocal EnableDelayedExpansion

Set WhiteListFile=%~sdp0whitelist.txt

for /f "tokens=2 delims==" %%a in (
'"WMIC PROCESS Where (Name="cmd.exe" AND CommandLine LIKE "%%%RANDOM%%RANDOM%%%") Get ParentProcessId /Value"'
) do call set $PID=%%a

for /f "skip=2 tokens=1,2 delims=," %%p in ('tasklist /NH /FO CSV') do if %%~q neq %$PID% (set "$p=%%~p"
  findstr/xic:"!$p:.=\.!" "%WhiteListFile%">Nul||taskkill /F /PID %%~q
)


Anonymоus 10-06-2011 07:14 1691846

Большое спасибо, всё работает.

McLotos 05-08-2011 09:50 1726250

Возникли некоторые вопросы:
1. Где указан адрес текстового файла
Цитата:

Цитата amel27
Set WhiteListFile=%~sdp0whitelist.txt »

т.е. они должны быть в одном каталоге с батником?
2. sdp0whitelist.txt что такое sdp0?
3. В каком виде должны быть записаны названия процессов в этот whitelist?
можно их записать просто через Enter или к примеру через запятую? Покажите плз образец

Iska 05-08-2011 10:33 1726276

Цитата:

Цитата McLotos
т.е. они должны быть в одном каталоге с батником? »

Да.
Цитата:

Цитата McLotos
sdp0whitelist.txt что такое sdp0? »

«sdp0» — ничего. «%~sdp0»:
Код:

call /?
читать дальше »
Код:

    Допускается применение следующих синтаксических конструкций:


        %~d1        - из переменной %1 выделяется только имя диска
        %~p1        - из переменной %1 выделяется только путь к файлу

        %~s1        - полученный путь содержит только короткие имена

    Эти модификаторы могут быть объединены…


— короткое имя от (диск + путь) к пакетному файлу (%0). См., например:
Код:

echo %~sdp0


Время: 13:09.

Время: 13:09.
© OSzone.net 2001-