Компьютерный форум 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=343147)

kirillius 03-12-2019 14:00 2898884

Удаление служб по маске
 
Здравствуйте.

Просьба помочь в написании скрипта по удалению служб по маске.
Например, есть список служб типа: service_1, service_2 и т.д.
Необходимо удалить все службы с именем service_*

DJ Mogarych 03-12-2019 15:05 2898898

Powershell, должно работать:
Код:

(get-service service_*).name.foreach({sc.exe delete $_})

Elven 03-12-2019 15:11 2898901

опять нет виндовой машины под рукой, но на пошике это делается +- ванлайном
Код:

Get-Service "service_*" | Remove-Service
насчет маски не уверен т.к. пишу по памяти
Однако должен отметить что удаление служб вижу весьма сомнительным действием.

DJ Mogarych 03-12-2019 15:13 2898902

Elven, Remove-Service появился только в Powershell v.6.

А был бы в общеупотребительных версиях, наверное, можно было бы так:
Код:

Remove-Service "service_*"
:)

kirillius 03-12-2019 15:27 2898907

Цитата:

Цитата DJ Mogarych
Powershell, должно работать: »

Не работает.
Код:

Нельзя вызвать метод для выражения со значением NULL.
строка:1 знак:40
+ (get-service AmmyyAdmin_*).name.foreach <<<< ({sc.exe delete $_})
    + CategoryInfo          : InvalidOperation: (foreach:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Цитата:

Цитата Elven
Get-Service "service_*" | Remove-Service »

Тоже не работает
Код:

Нельзя вызвать метод для выражения со значением NULL.
строка:1 знак:40
+ (get-service service_*).name.foreach <<<< ({cmd.exe /c "sc delete $_"})
    + CategoryInfo          : InvalidOperation: (foreach:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Возможно маска неправильная, в имени службы вместо звёздочки может быть от 4 до 6 символов

DJ Mogarych 03-12-2019 15:36 2898911

kirillius,
Цитата:

Цитата DJ Mogarych
Remove-Service появился только в Powershell v.6. »

У вас какая версия powershell?

Команда
Код:

$psversiontable
Можно вот так попробовать, если версия старая:
Код:

(get-service service_*).name |foreach {sc.exe delete $_}
Цитата:

Цитата kirillius
Нельзя вызвать метод для выражения со значением NULL. »

Вы уверены, что у вас существуют службы с именами service_*? Что показывает
Код:

get-service service_*
?

kirillius 03-12-2019 15:42 2898913

Цитата:

Цитата DJ Mogarych
$psversiontable »

Код:

CLRVersion                    2.0.50727.8806
BuildVersion                  6.1.7601.17514
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions          {1.0, 2.0}
SerializationVersion          1.1.0.1
PSRemotingProtocolVersion      2.1


DJ Mogarych 03-12-2019 16:43 2898920

Да, это очень старая версия.

Так работает?
Код:

(get-service service_*).name |foreach {sc.exe delete $_}

Iska 03-12-2019 17:41 2898926

DJ Mogarych, а Wbem — Win32_Service → .Delete() (мне пробовать не на чем — нет «лишних» служб), не?!

Цитата:

Цитата kirillius
Не работает. »

Метод .foreach() появился позже версии 2.0, которая у Вас (можете смело обновиться как минимум до версии 5.1, если у Вас Windows 7/Server 2008 R2 и выше).

kirillius 05-12-2019 16:00 2899175

Цитата:

Цитата DJ Mogarych
Так работает? »

Нет, не получилось
Код:

Описание:
        Удаление записи службы из реестра.
        Если служба запущена либо для нее открыт дескриптор
        другим процессом, эта служба будет помечена
        для удаления.
Использование:
        sc <сервер> delete [имя службы]

Цитата:

Цитата DJ Mogarych
get-service service_* »

Ну "service_*" я привёл для примера. Если подставить то что реально нужно, выводит список служб по маске.
При проверке скрипта я разумеется меняю всё на то как нужно.

megaloman 05-12-2019 16:59 2899190

VBS
Код:

Maska = "^winsolit_.*$"

Set ProcL = GetObject("winmgmts:").ExecQuery("Select * From Win32_Process")

With CreateObject("VBScript.RegExp")
    .Pattern = Maska
    .IgnoreCase = True
    .Global = True
    For Each iProc In ProcL
        If .Test(iProc.Name) Then
            iProc.Terminate
        End If
    Next
End With

MsgBox "Done"

Единственное, написать регулярку
Тестировал на старой игре winsolit
Скопировал несколько раз exe с разными именами и запустил их.

DJ Mogarych 05-12-2019 17:19 2899193

Цитата:

Цитата kirillius
Если служба запущена либо для нее открыт дескриптор
другим процессом, эта служба будет помечена
для удаления. »

Ну давайте будем из вас информацию клещами тащить.
Служба остановлена?
Нет ли там дескрипторов от других процессов?

Код:

(get-service service_*).name |foreach {
stop-service $_
sc.exe delete $_
}


kirillius 06-12-2019 15:27 2899284

Цитата:

Цитата DJ Mogarych
(get-service service_*).name |foreach {
stop-service $_
sc.exe delete $_
} »

Код:

Не удается привязать аргумента к параметру "Name", так как он имеет значение NULL.
Все службы по данной маске остановлены. Также, по одиночке они спокойно удаляются из cmd путём sc delete.
Скрипт выше тоже удалил службу, когда я вместо маски прописал полное её имя.

DJ Mogarych 06-12-2019 18:48 2899299

Какой-то из этих вариантов работает?
Код:

get-service service_*
get-service "service_*"
get-service service*


kirillius 09-12-2019 14:11 2899651

Цитата:

Цитата DJ Mogarych
Какой-то из этих вариантов работает? »

Работают все. Выводится список служб.

DJ Mogarych 09-12-2019 14:39 2899654

Хорошо. А такие варианты?
Код:

(get-service service_*).name
get-service service_* |select -expand name


kirillius 10-12-2019 09:33 2899749

Цитата:

Цитата DJ Mogarych
Хорошо. А такие варианты? »

Тоже отработало.

DJ Mogarych 10-12-2019 10:00 2899754

Интересное кино.

А так работает?
Код:

$services = get-service service_*
foreach ($service in services) {
stop-service $service
sc.exe delete $service.name
}


kirillius 10-12-2019 10:21 2899757

Цитата:

Цитата DJ Mogarych
$services = get-service service_*
foreach ($service in services) {
stop-service $service
sc.exe delete $service.name
} »

Ошибок не пишет (вообще ничего не пишет), но службы не удаляет.

Busla 10-12-2019 11:46 2899766

Цитата:

Цитата DJ Mogarych
Интересное кино.
А так работает? »

Отличная демонстрация того, что все эти "хакерские" выверты и прочая магия допустимы в интерактивном режиме. А скрипты надо писать однозначно.


kirillius, попробуйте добавить в цикл вывод найденных сервисов
у Stop-Process укажите явно, что вы передаёте, а не надейтесь на приведение типов
внешние файлы вызывайте либо командлетом Start-Process либо оператором контекста &

примерно так
Код:

$services = get-service service_*
foreach ($service in $services) {
  write-verbose $service.name -Verbose
  stop-service -InputObject $service
  & sc.exe delete $service.name
}

а на самом деле просто потерян $ перед services

и этого бы не случилось, если бы не городили на пустом месте кучу переменных, а писали бы конвейером

p.s. и в общем случае оно не будет работать - сломается на службах с пробелом в имени

Iska 10-12-2019 12:28 2899773

Цитата:

Цитата Busla
а на самом деле просто потерян $ перед services
и этого бы не случилось, если бы не городили на пустом месте кучу переменных, а писали бы конвейером »

Да нет, это просто язык такой. Желание объять всё зараз вот к такому и приводит.

DJ Mogarych 10-12-2019 13:20 2899780

Цитата:

Цитата Busla
скрипты надо писать однозначно »

Для этого надо нормально формулировать задачу.
И неплохо бы иметь любознательность хотя бы чтобы попробовать понять, что делает элементарный скрипт в две строки, я уж не говорю о том, чтобы попробовать самому попробовать их написать.

kirillius 10-12-2019 13:24 2899783

Цитата:

Цитата Busla
$services = get-service service_*
foreach ($service in $services) {
write-verbose $service.name -Verbose
stop-service -InputObject $service
& sc.exe delete $service.name
} »

Получилось, спасибо!
А теперь это можно в некое подбие BAT-файла преобразовать, чтобы запуском в один клик вся эта процедура проделывалась? К сожалению с PowerShell не знаком совершенно...

Busla 10-12-2019 17:15 2899819

kirillius,
Попробуйте так:
Код:

powershell.exe -Command { Stop-service service_* -PassThru | % { & sc.exe delete $_.name }  }
не проверял, т.к. лишних служб у меня нет :-)

kirillius 13-12-2019 10:56 2900196

Цитата:

Цитата Busla
Попробуйте так: »

Не сработало, выдало:

Код:

"%" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.


DJ Mogarych 13-12-2019 10:59 2900198

Busla, теперь ваша очередь демонстрации написания однозначных скриптов.

kirillius 13-12-2019 13:17 2900217

Пока решил задачу так:

Код:

$services = get-service service_*
foreach ($service in $services) {
write-verbose $service.name -Verbose
stop-service -InputObject $service
& sc.exe delete $service.name
}

- Это поместил в файл .ps1, а в BAT прописал:

Код:

powershell "D:\Desktop\DelServices.ps1"

Busla 13-12-2019 15:24 2900244

kirillius, для bat удобнее будет использовать wmi:
Код:

wmic.exe service where "name like 'service_%' and started = true" call stopservice
wmic.exe service where "name like 'service_%'" call delete


kirillius 13-12-2019 15:51 2900250

Цитата:

Цитата Busla
wmic.exe service where "name like 'service_%' and started = true" call stopservice
wmic.exe service where "name like 'service_%'" call delete »

А так не работает - No Instance(s) Available.

Iska 13-12-2019 16:54 2900254

Цитата:

Цитата kirillius
А так не работает »

А так:
Цитата:

Цитата Busla
Код:

wmic.exe service where "name like 'service_%%' and started = true" call stopservice
wmic.exe service where "name like 'service_%%'" call delete

»

?

kirillius 14-12-2019 00:31 2900287

Цитата:

Цитата Iska
А так: »

Так работает! Благодарю!


Время: 13:30.

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