web-dev-qa-db-fra.com

Comment obtenir l'ID de processus par son nom de service avec un script à variable

J'ai un service nommé WinDefend et il s'exécute sur le processus svchost.exe
Il y a beaucoup d'autres processus svchost.exe et je dois trouver un moyen d'obtenir son ID.
quand je lance tasklist /svc je peux voir: enter image description here

Je ne sais pas comment puis-je l'obtenir.
J'ai trouvé cette commande mais quand j'ai essayé le select "PID", il m'a donné une colonne vide .enter image description here

Je dois obtenir le PID du processus à variable.

10
E235

tasklist renvoie uniquement du texte, et non des objets réels dotés de propriétés accessibles Vous pouvez utiliser WMI pour obtenir ces informations à la place:

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

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

Ennuyant, il vous faut définir un titre unique pour votre script si vous voulez le pid pour le processus en cours. Recherchez ensuite ce titre unique dans la liste des processus. Heureusement, la commande Titre vous permet de faire exactement cela. Voir aussi MagicAndi's response ... 

Voici ma solution de fichier batch:

@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

BTW, j'ai eu le «plaisir» de faire cela maintes et maintes fois au fil des ans, via API, batch ou ps. Choisissez votre poison - sur une plate-forme Windows, c'est la même chose.

J'ai trouvé un moyen encore meilleur via powershell: $ pid renvoie l'identifiant du processus en cours.

2
Mark Ronollo

J'ai utilisé cela et cela fonctionne bien. 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

Merci,

0
Kambo

Une autre façon d’obtenir un PID de processus:

$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]

Ou vous pouvez le résumer à:

$servicePID = $($($(tasklist /v /fo csv | findstr /i $serviceName) -replace '["]') -split ",")[$pidArgumentPlacement]

Remarque: Ceci récupérera le premier service qui correspond à votre $serviceName. Si vous exécutez un service qui exécute plusieurs instances de lui-même (par exemple slack), vous obtiendrez uniquement le premier pid. tasklist /v /fi "IMAGENAME eq slack.exe" /fo csv retournera un tableau avec chaque ligne CSV étant une entrée de tableau. Vous pouvez également filtrer ceci avec findstr pour éviter d’obtenir les noms de colonnes.

EDIT: Comme WinDefend est un sous-service d’un programme (dans ce cas, svchost.exe), vous devrez peut-être échanger l’indicateur prolixe pour tasklist en /svc comme suit:

$serviceAsCSVString = tasklist /svc /fo csv | findstr /i $serviceName

vous pouvez également rechercher le nom du service via un filtre:

$serviceAsCSVString = tasklist /svc /fi "SERVICES eq $serviceName" /fo csv | findstr /i $serviceName

Et en tenant compte du fait que le filtre renvoie une ligne de noms de colonnes ainsi que la ligne que vous recherchiez:

$serviceCSVStringWithoutQuotes = $serviceAsCSVString[1] -replace '["]'

En supposant que vous ayez changé $serviceName en WinDefend au lieu de svchost.exe.

0
eFox