Как получить идентификатор процесса по имени службы со скриптом в переменную
у меня есть служба с именем WinDefend
и он работает на process svchost.exe
Там других много svchost.exe
процессы и мне нужно найти способ, чтобы получить его ID.
когда я бегу tasklist /svc
Я вижу:
Я не уверен, как я могу получить его.
Я нашел эту команду, но когда я попробовал select "PID"
Он дал мне пустой столбец.
мне нужно получить PID процесса для переменной.
5 ответов
tasklist
просто возвращает текст, а не фактические объекты, которые имеют свойства, к которым вы можете получить доступ. Для получения этой информации можно использовать WMI:
$id = Get-WmiObject -Class Win32_Service -Filter "Name LIKE 'WinDefend'" |
Select-Object -ExpandProperty ProcessId
$process = Get-Process -Id $id
раздражает, как это, это требует, чтобы вы установили уникальный заголовок для своего сценария, если вы хотите pid для текущего процесса. Затем найдите это уникальное название в списке процессов. К счастью, команда Title позволяет вам делать именно это. Смотрите также MagicAndi по ответ...
вот мое решение для пакетного файла:
@ECHO OFF
:SetVars
SET _Thread=%1
title=ExecBatch_%_Thread%
Set /A "_iPID=0"
:Main
CALL :getPID _iPID %_Thread%
...
EXIT /b
::----------------
::---- GetPID ----
::----------------
:getPID
setlocal
set _getPIDcmd=tasklist /v /fo csv
for /f "tokens=2 delims=," %%i in ('%_getPIDcmd% ^| findstr /i "ExecBatch_%2"') do (
echo %%~i
set _pid=%%~i
)
endlocal & Set %~1=%_pid%
exit /b
кстати, у меня было "удовольствие" делать это снова и снова на протяжении многих лет, через API, или пакет, или ps. Выберите свой poison-на платформе Windows это все равно.
Я нашел еще лучший способ через powershell: $pid возвращает идентификатор процесса текущего процесса.
альтернативный способ получить PID процесса:
$serviceName = 'svchost.exe'
$pidArgumentPlacement = 1
# Call for the verbose version of tasklist and filter it for the line with your service's name.
$serviceAsCSVString = tasklist /v /fo csv | findstr /i $serviceName
# Remove the quotes from the CSV string
$serviceCSVStringWithoutQuotes = $serviceAsCSVString -replace '["]'
# Turn the string into an array by cutting at the comma
$serviceAsArray = $serviceCSVStringWithoutQuotes -split ","
# Get the pid from the array
$servicePID = $serviceAsArray[$pidArgumentPlacement]
или вы можете подвести его до:
$servicePID = $($($(tasklist /v /fo csv | findstr /i $serviceName) -replace '["]') -split ",")[$pidArgumentPlacement]
Примечание: это захватит первый сервис, который соответствует вашему $serviceName
, если вы запускаете службу, которая запускает несколько экземпляров себя (e.X. slack) вы получите только первый pid. tasklist /v /fi "IMAGENAME eq slack.exe" /fo csv
вернет массив с каждой строкой CSV, являющейся записью массива. Вы также можете отфильтровать это с помощью findstr
чтобы избежать получения столбца имена.
изменить:
Как WinDefend является subservice программы (в данном случае svchost.exe
) вам может потребоваться поменять флаг verbose на tasklist
to /svc
вот так:
$serviceAsCSVString = tasklist /svc /fo csv | findstr /i $serviceName
альтернативный поиск имени службы через фильтр:
$serviceAsCSVString = tasklist /svc /fi "SERVICES eq $serviceName" /fo csv | findstr /i $serviceName
и с учетом того, что фильтр возвращает строку имен столбцов, а также вы искали:
$serviceCSVStringWithoutQuotes = $serviceAsCSVString[1] -replace '["]'
предполагая, что вы изменились $serviceName
to WinDefend
вместо svchost.exe
.
# Enter servicename. (instead of 'netman')
$service = Get-CimInstance -class win32_service | Where-Object name -eq 'netman' | select name, processid
$process = Get-Process | Where-Object ID -EQ $service.processid
Clear-Host
Write-Host '********* ServiceName, PID and ProcessName ******'
Write-Host 'ServiceName:' $service.name
Write-Host 'ID:' $process.Id
Write-Host 'ProcessName:' $process.Name
спасибо,