web-dev-qa-db-ja.com

変数へのスクリプトを使用してサービス名でプロセスIDを取得する方法

WinDefendという名前のサービスがあり、プロセスsvchost.exeで実行されます
他にも多くのsvchost.exeプロセスがあり、そのIDを取得する方法を見つける必要があります。
tasklist /svcを実行すると、次のことがわかります。 enter image description here

どうすれば入手できるかわかりません。
このコマンドを見つけましたが、select "PID"を試したときに空の列が表示されました。 enter image description here

プロセスのPIDを変数に取得する必要があります。

16
E235

tasklistは、アクセス可能なプロパティを持つ実際のオブジェクトではなく、単にテキストを返します。代わりに、WMIを使用してこの情報を取得できます。

$id = Get-WmiObject -Class Win32_Service -Filter "Name LIKE 'WinDefend'" | 
      Select-Object -ExpandProperty ProcessId

$process = Get-Process -Id $id
22
Mike Zboray
$p=Tasklist /svc /fi "SERVICES eq windefend" /fo csv | convertfrom-csv
$p.PID
8
walid toumi

面倒なことに、現在のプロセスのpidが必要な場合は、スクリプトに一意のタイトルを設定する必要があります。次に、プロセスのリスト内でその一意のタイトルを検索します。ありがたいことに、Titleコマンドを使用すると、まさにそれを行うことができます。 MagicAndiの response ...も参照してください。

これが私のバッチファイルソリューションです。

@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を介して、何年にもわたって何度も何度もやり直す「喜び」を感じてきました。あなたの毒を選んでください-Windowsプラットフォームではすべて同じです。

私はpowershell経由でさらに良い方法を見つけました:$ pidは現在のプロセスのプロセスIDを返します。

2
Mark Ronollo

私はこれを使用しましたが、うまく機能します。 YMMV

$ProcessName = "SomeProcessName"

$pidnumber = Get-Process -Name $ProcessName | Select -expand ID
1
user1649664
# 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

おかげで、

0
Kambo

プロセス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に一致する最初のサービスを取得します(ex slack)最初のpidのみを取得します。 tasklist /v /fi "IMAGENAME eq slack.exe" /fo csvは、各CSV行が配列エントリである配列を返します。また、findstrでこれをフィルタリングして、列名を取得しないようにすることもできます。

編集:WinDefendはプログラムのサブサービスであるため(この場合はsvchost.exe)、次のようにtasklistの冗長フラグを/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の代わりにsvchost.exeWinDefendに変更したと仮定します。

0
eFox