如何通过脚本到变量的服务名称获取进程ID

时间:2014-10-12 23:47:57

标签: powershell windows-7 process tasklist

我有一个名为WinDefend的服务,它在流程svchost.exe上运行 还有其他许多svchost.exe进程,我需要找到一种获取其ID的方法 当我跑tasklist /svc时,我可以看到: enter image description here

我不知道怎么才能得到它 我找到了这个命令但是当我尝试select "PID"时,它给了我空列。 enter image description here

我需要将流程的PID变为变量。

7 个答案:

答案 0 :(得分:19)

tasklist只是返回文本,而不是具有您可以访问的属性的实际对象。您可以使用WMI来获取此信息:

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

$process = Get-Process -Id $id

答案 1 :(得分:7)

$p=Tasklist /svc /fi "SERVICES eq windefend" /fo csv | convertfrom-csv
$p.PID

答案 2 :(得分:2)

这很烦人,如果你想要当前进程的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。

答案 3 :(得分:1)

我已经用过了,效果很好。 YMMV

$ProcessName = "SomeProcessName"

$pidnumber = Get-Process -Name $ProcessName | Select -expand ID

答案 4 :(得分:0)

获取进程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]

注意:如果你运行一个运行多个自身(ex slack)你的实例的服务,这将获取与你的$serviceName匹配的第一个服务只会得到第一个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更改为WinDefend而非svchost.exe

答案 5 :(得分:0)

# 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

谢谢

答案 6 :(得分:0)

Get-Process -Id ((Get-WmiObject -Class Win32_Service -Filter "Name -eq 'WinDefend'").ProcessId)