Powershell 如何使用脚本变量通过其服务名称获取进程id
我有一个名为Powershell 如何使用脚本变量通过其服务名称获取进程id,powershell,windows-7,process,tasklist,Powershell,Windows 7,Process,Tasklist,我有一个名为windefind的服务,它运行在进程svchost.exe 还有许多其他的svchost.exe进程,我需要找到一种方法来获取它的ID。 当我运行tasklist/svc时,我可以看到: 我不知道怎样才能得到它。 我找到了这个命令,但是当我尝试选择“PID”时,它给了我空列。 我需要将进程的PID设置为变量。tasklist只是返回文本,而不是具有您可以访问的属性的实际对象。您可以使用WMI来获取此信息: $id = Get-WmiObject -Class Win32_Ser
windefind
的服务,它运行在进程svchost.exe
还有许多其他的
svchost.exe进程,我需要找到一种方法来获取它的ID。
当我运行tasklist/svc
时,我可以看到:
我不知道怎样才能得到它。
我找到了这个命令,但是当我尝试选择“PID”
时,它给了我空列。
我需要将进程的PID设置为变量。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一次又一次地这样做。选择你的毒药——在Windows平台上,一切都是一样的
我通过powershell找到了一种更好的方法:$pid返回当前进程的进程id。另一种获取进程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),您将只获得第一个pidtasklist/v/fi“IMAGENAME eq slack.exe”/fo csv
将返回一个数组,其中每个csv行都是一个数组条目。您还可以使用findstr
对其进行筛选,以避免获取列名
编辑:
由于WinDefend是程序的一个子服务(在本例中为svchost.exe
),您可能需要将任务列表的详细标志切换为/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
更改为windefind
,而不是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
谢谢,我用过这个,效果很好。YMMV
$ProcessName = "SomeProcessName"
$pidnumber = Get-Process -Name $ProcessName | Select -expand ID
当我运行$servicename='windefind'$pidArgumentPlacement=1时,调用详细版本的tasklist并将其筛选为包含服务名称的行$serviceAsCSVString=tasklist/v/fo csv | findstr/i$serviceName
该$serviceScsvString
为空。抱歉,我的脚本中有一个输入错误<代码>$serviceName
在第一行拼写错误。再试一次,确保变量名匹配;powershell区分大小写。它不工作,而且powershell不区分大小写。如果您将运行$a=“a”$A
您将看到它将打印相同的值。你在你的机器上检查过这个代码吗?只运行:$serviceName='WinDefend'$pidArgumentPlacement=1 tasklist/v/fo csv | findstr/i$serviceName
它将找不到任何内容。问题在于您没有使用显示服务名称的/svc
开关。因此,它不显示windefind
服务。修复代码:只需将/v
替换为/svc
Btwsvchost.exe
不是一个好例子,因为它不是一项服务。我已更新了答案,我似乎误解了你在寻找什么。虽然这个答案可能会解决这个问题,但如果你解释一下它是如何工作的,它会更有用,但我的情况不同。进程名为svchost.exe
,它在任务管理器中出现了几次。然后,您只需要找到与WinDefend服务相关的一个“仅仅显示所有svchost.exe
的id并不能解决此问题。我试图在服务上执行此操作,我似乎无法将-expand id与get服务一起使用。我认为您误解了这个问题。虽然此代码可能会回答此问题,提供关于此代码为什么和/或如何回答此问题的附加上下文可提高其长期价值。
$ProcessName = "SomeProcessName"
$pidnumber = Get-Process -Name $ProcessName | Select -expand ID
Get-Process -Id ((Get-WmiObject -Class Win32_Service -Filter "Name -eq 'WinDefend'").ProcessId)