OVH Cloud OVH Cloud

commande Powershell services svchost

31 réponses
Avatar
Robby
Bonjour,

Avec Powershell, je peux voir l'etat du services svchost.
gwmi win32_process -computer xxxx -filter "name='svchost.exe'"
Mais comment obtenir le detail, savoir quelles applications qui utilisent le
process svchost ?

Comme par exemple avec Process Explorer qui m'indique clairement que
l'enfant de svchost est Winword, Iexplorer et d'autres programmes.

Merci d'avance,

Robby

10 réponses

1 2 3 4
Avatar
Gilles LAURENT
"Robby" a écrit dans le message de
news:%
| Merci Gilles,
| Mais est-il possible d'avoir une commande du style gwmi
| win32_process -computer xxxxx
| Sans passer pas le script ?

Mais à quoi sert le script alors ? Pour me faire plaisir ??
Donc pour répondre à votre question : NON !

--
Gilles LAURENT
http://glsft.free.fr
Avatar
Jacques Barathon [MS]
"Gilles LAURENT" wrote in message
news:%
"Robby" a écrit dans le message de
news:%
| Merci Gilles,
| Mais est-il possible d'avoir une commande du style gwmi
| win32_process -computer xxxxx
| Sans passer pas le script ?

Mais à quoi sert le script alors ? Pour me faire plaisir ??
Donc pour répondre à votre question : NON !


On peut quand même simplifier un peu l'écriture en passant par un seul
enchaînement de commandes:

PS> gwmi win32_process -computer . -filter "name='svchost.exe'" | foreach
{"Process Id {0} :" -f $_.processid;gwmi win32_process
-filter "ParentProcessID='$($_.processid)'" | ft name,processid,path -a}

Ma solution est un peu moins rapide car l'imbrication des boucles en une
seule ligne n'est pas optimal. Ca ne devrait pas poser de problèmes pour des
besoins ponctuels, ça peut faire une différence certaine si l'idée est
d'exécuter la tâche régulièrement sur de nombreuses machines.

On peut également faire une version assez similaire à celle de Gilles avec
les lignes suivantes:

PS> $svchost = gwmi win32_process -computer . -filter "name='svchost.exe'" |
%{$_.processid}
PS> gwmi win32_process -computer . | ?{$svchost -contains
$_.parentprocessid} | group parentprocessid

Jacques

Avatar
Gilles LAURENT
"Jacques Barathon [MS]" a écrit dans le
message de news:%
| On peut quand même simplifier un peu l'écriture en passant par un seul
| enchaînement de commandes:
|
|| gwmi win32_process -computer . -filter "name='svchost.exe'" | foreach
| {"Process Id {0} :" -f $_.processid;gwmi win32_process
| -filter "ParentProcessID='$($_.processid)'" | ft name,processid,path
| -a}
|
| Ma solution est un peu moins rapide car l'imbrication des boucles en
| une seule ligne n'est pas optimal. Ca ne devrait pas poser de
| problèmes pour des besoins ponctuels, ça peut faire une différence
| certaine si l'idée est d'exécuter la tâche régulièrement sur de
| nombreuses machines.
|
| On peut également faire une version assez similaire à celle de Gilles
| avec les lignes suivantes:
|
|| $svchost = gwmi win32_process -computer . -filter
|| "name='svchost.exe'" | %{$_.processid} gwmi win32_process -computer
|| . | ?{$svchost -contains
| $_.parentprocessid} | group parentprocessid
|
| Jacques

Bonjour Jacques,

Joli ! Néanmoins il y a plusieurs différences avec ma solution :

1- Votre solution ne recherche que les descendants de niveau 1
2- Vous ne vérifiez pas la validité du pid du processus parent ce qui
peut dans certains cas provoquer une détection erronée des descendants
de svchost

Ce deuxième cas est un peu tordu. Sur ma plateforme :
- un processus svchost.exe (pid 1736)
- le Shell explorer.exe (pid parent 1736)

Démarrage du Shell (pid 388) par le processus Userinit.exe (pid 1736)
Fin du processus Userinit.exe et libération du pid 1736
Démarrage d'un processus svchost.exe (pid = 1736) par le SCM

Pour m'en sortir, j'ai donc dû vérifier la validité du pid du processus
parent en comparant les dates de création des processus. Si le processus
parent référencé par la propriété wmi ParentProcessId est plus récent
que le processus enfant alors la propriété wmi ParentProcessId référence
un processus qui n'est plus en cours d'exécution. J'en déduis donc dans
ce cas que le processus explorer.exe n'est pas un descendant de svchost
!

Count Name Group
----- ---- -----
1 1736 {explorer.exe} <- Faux
1 1160 {wmiprvse.exe}
1 1888 {wuauclt.exe}

--
Gilles LAURENT
http://glsft.free.fr
Avatar
Jacques Barathon [MS]
"Gilles LAURENT" wrote in message
news:
<...>
Joli ! Néanmoins il y a plusieurs différences avec ma solution :

1- Votre solution ne recherche que les descendants de niveau 1
2- Vous ne vérifiez pas la validité du pid du processus parent ce qui
peut dans certains cas provoquer une détection erronée des descendants
de svchost


En effet, je ne prétendais pas reproduire intégralement les fonctionnalités
de ton script, il s'agissait d'une réponse simple et rapide. On doit quand
même pouvoir traiter les deux cas de manière un peu plus concise, mais c'est
un point de détail. Le plus important est d'avoir un script qui marche tout
en étant lisible pour qu'on puisse le débugger et le faire évoluer.

Jacques

Avatar
Jacques Barathon [MS]
"Jacques Barathon [MS]" wrote in message
news:
"Gilles LAURENT" wrote in message
news:
<...>
Joli ! Néanmoins il y a plusieurs différences avec ma solution :

1- Votre solution ne recherche que les descendants de niveau 1
2- Vous ne vérifiez pas la validité du pid du processus parent ce qui
peut dans certains cas provoquer une détection erronée des descendants
de svchost


En effet, je ne prétendais pas reproduire intégralement les
fonctionnalités de ton script, il s'agissait d'une réponse simple et
rapide. On doit quand même pouvoir traiter les deux cas de manière un peu
plus concise, mais c'est un point de détail. Le plus important est d'avoir
un script qui marche tout en étant lisible pour qu'on puisse le débugger
et le faire évoluer.


Voici une version qui permet de traiter le problème de la date:

PS> $proc=gwmi win32_process
PS> gwmi win32_process -filter "name='svchost.exe'" |
%{$id=$_.processid;$date=$_.creationdate; $proc | ?{$_.parentprocessid -eq
$id -and $_.creationdate -gt $date}} | group parentprocessid

Count Name Group
----- ---- -----
4 816 {WmiPrvSE.exe, ehmsas.exe, WmiPrvSE.exe,
WmiPrvSE.exe}
1 1032 {audiodg.exe}
1 1076 {dwm.exe}
2 1092 {taskeng.exe, taskeng.exe}

La technique ci-dessus consiste à prendre chaque instance de svchost et à
vérifier quels process ont son ID comme parent et ont une date de création
postérieure.

On peut également prendre le problème dans l'autre sens, comme tu le fais
dans ton script, à savoir prendre chaque process en cours et vérifier si son
parent s'appelle svchost et a une date de création antérieure:

PS> $svc=gwmi win32_process -filter "name='svchost.exe'"
PS> gwmi win32_process | ?{$id=$_.parentprocessid;($svc |
%{$_.processid}) -contains $id -and ($svc | ?{$_.processid -eq
$id}).creationdate -lt $_.creationdate} | group parentprocessid

Count Name Group
----- ---- -----
1 1032 {audiodg.exe}
2 1092 {taskeng.exe, taskeng.exe}
4 816 {WmiPrvSE.exe, ehmsas.exe, WmiPrvSE.exe,
WmiPrvSE.exe}
1 1076 {dwm.exe}

Pour ce qui est de la récursivité, je ne vois pas en quoi ton script la
gère, puisque l'affichage ne se fait que si le nom du parent est
"svchost.exe". Y'a-t-il quelque chose qui m'échappe? C'est fort possible, je
ne suis pas à 100% de mes neurones ces temps-ci pour cause de grippette :-(.

Jacques


Avatar
Gilles LAURENT
"Jacques Barathon [MS]" a écrit dans le
message de news:%
[...]
| Pour ce qui est de la récursivité, je ne vois pas en quoi ton script
| la gère, puisque l'affichage ne se fait que si le nom du parent est
| "svchost.exe". Y'a-t-il quelque chose qui m'échappe? C'est fort
| possible, je ne suis pas à 100% de mes neurones ces temps-ci pour
| cause de grippette :-(.

Vos scripts vérifient maintenant la validité du pid du parent, testés
sur ma plateforme ;-). Mon processus "explorer.exe" n'apparaît plus
comme enfant de svchost.exe. Concernant l'aspect récursif, ci-dessous la
version commentée de mon script (c'est bien parce que vous êtes grippé
... Bon rétablissement Jacques !)

# initialisation d'un hash pour le stockage des informations
# des processus actifs du système (local ou distant)
$odic=@{}

# Etape 1:
# lecture de tous les processus actifs et sauvegarde des
# informations dans le format (nom:pid du parent:date de création)
# dans le hash avec comme clés les pid
gwmi -computer $args win32_process |
% {
$odic["$($_.ProcessId)"]=`
"$($_.name):"+`
"$($_.ParentProcessId):"+`
"$($_.CreationDate)"
}

# Etape 2:
# recherche récursive des processus dont le parent (direct
# ou indirect) est "svchost.exe"
gwmi -computer $args win32_process |
% {
# initialisation des variables utilisées pour la récursivité
# $ppid = pid du parent
# $cpdate = date de création du processus
$ppid=$_.ParentProcessId; $cpdate=$_.CreationDate

# démarrage de la récursivité jusqu'au processus racine
# le processus racine "Idle" à un pid=0
while ($ppid -ne 0) {
# vérification de l'existance du pid du parent
if ($odic["$ppid"] -eq $null) {
#Non-existent Parent Process
break
}

# le pid du parent existe
# extraction des informations stockées dans le hash
# en utilisant la clé du pid du parent
# $name : le nom du processus parent
# $gppid : le pid du grand-père
# $ppdate : la date de création du pid du parent
($name,$gppid,$ppdate)=$odic["$ppid"].split(":")

# vérification de la validité du pid du parent
# le parent doit être né avant l'enfant !
if ($cpdate -lt $ppdate) {
#Invalid Parent Process
break
}

# si le processus en cours de traitement a pour parent
# (direct ou indirect) svchost.exe alors on l'affiche
if ($name -eq "svchost.exe") {
"$name($ppid) $($_.name)"
}

# poursuite du traitement jusqu'au processus racine
# récursivité donc substitution des variables :
# $ppid prend la valeur du pid du grand-père
# $cpdate prend la valeur du parent
$ppid=$gppid; $cpdate=$ppdate
}
}

--
Gilles LAURENT
http://glsft.free.fr
Avatar
Robby
Bonjour et merci;
Voici les commandes que j'ai tapé:

"Jacques Baratho$proc=gwmi win32_process
$gwmi win32_process -computer cop066012 -filter "name='svchost.exe'" |
%{$id=$_.processid
$date=$_.creationdate;
$proc | ?{$_.parentprocessid -eq
$id -and $_.creationdate -gt $date}} | group parentprocessid
Je n'ai pas d'erreur, à chaque fois j'arrive sur >>

Mais je n'arrive à aucun resultat.



n [MS]" a écrit dans le message de news:
%
"Jacques Barathon [MS]" wrote in message
news:
"Gilles LAURENT" wrote in message
news:
<...>
Joli ! Néanmoins il y a plusieurs différences avec ma solution :

1- Votre solution ne recherche que les descendants de niveau 1
2- Vous ne vérifiez pas la validité du pid du processus parent ce qui
peut dans certains cas provoquer une détection erronée des descendants
de svchost


En effet, je ne prétendais pas reproduire intégralement les
fonctionnalités de ton script, il s'agissait d'une réponse simple et
rapide. On doit quand même pouvoir traiter les deux cas de manière un peu
plus concise, mais c'est un point de détail. Le plus important est
d'avoir un script qui marche tout en étant lisible pour qu'on puisse le
débugger et le faire évoluer.


Voici une version qui permet de traiter le problème de la date:

PS> $proc=gwmi win32_process
PS> gwmi win32_process -filter "name='svchost.exe'" |
%{$id=$_.processid;$date=$_.creationdate; $proc | ?{$_.parentprocessid -eq
$id -and $_.creationdate -gt $date}} | group parentprocessid

Count Name Group
----- ---- -----
4 816 {WmiPrvSE.exe, ehmsas.exe, WmiPrvSE.exe,
WmiPrvSE.exe}
1 1032 {audiodg.exe}
1 1076 {dwm.exe}
2 1092 {taskeng.exe, taskeng.exe}

La technique ci-dessus consiste à prendre chaque instance de svchost et à
vérifier quels process ont son ID comme parent et ont une date de création
postérieure.

On peut également prendre le problème dans l'autre sens, comme tu le fais
dans ton script, à savoir prendre chaque process en cours et vérifier si
son parent s'appelle svchost et a une date de création antérieure:

PS> $svc=gwmi win32_process -filter "name='svchost.exe'"
PS> gwmi win32_process | ?{$id=$_.parentprocessid;($svc |
%{$_.processid}) -contains $id -and ($svc | ?{$_.processid -eq
$id}).creationdate -lt $_.creationdate} | group parentprocessid

Count Name Group
----- ---- -----
1 1032 {audiodg.exe}
2 1092 {taskeng.exe, taskeng.exe}
4 816 {WmiPrvSE.exe, ehmsas.exe, WmiPrvSE.exe,
WmiPrvSE.exe}
1 1076 {dwm.exe}

Pour ce qui est de la récursivité, je ne vois pas en quoi ton script la
gère, puisque l'affichage ne se fait que si le nom du parent est
"svchost.exe". Y'a-t-il quelque chose qui m'échappe? C'est fort possible,
je ne suis pas à 100% de mes neurones ces temps-ci pour cause de grippette
:-(.

Jacques




Avatar
Jacques Barathon [MS]
"Robby" wrote in message
news:%
Ok merci pour ta patience, en effet cela fonctionne bien.
Et mainteant commenf faire pour en faire un fichier Script ?


Tout simplement en copiant les commandes dans un fichier avec l'extension
ps1. Enlève les "PS>" et autres ">>", et de préférence regroupe une même
commande sur une seule ligne, ça évitera les interprétations erronées ou
ambigues. Par exemple, enlève le retour-chariot après "-eq".

Si tu veux passer le nom de l'ordinateur en paramètre, ajoute une clause
param() en tête du script:

param ($computer = ".")
$proc = gwmi win32_process -computer $computer
etc...

Par défaut, c'est l'ordinateur local qui sera interrogé (".").

Jacques

Avatar
Robby
Bonjour et merci pour ton aide,
Voila j'ai rajoute les commandes param et mis sur une ligne -eq, voici mon
fichier test.ps1
param ($computer = ".")
$proc = gwmi win32_process -computer $computer
$proc=gwmi win32_process
gwmi win32_process -computer . -filter "name='svchost.exe'" |
%{$id=$_.processid $date=$_.creationdate;
$proc | ?{$_.parentprocessid -eq $id -and $_.creationdate -gt $date}} |
group parentprocessid
donc je lance test.ps1 dans la console mais rien ne se passe il revient au
prompt.
Robby

"Jacques Barathon [MS]" a écrit dans le
message de news:
"Robby" wrote in message
news:%
Ok merci pour ta patience, en effet cela fonctionne bien.
Et mainteant commenf faire pour en faire un fichier Script ?


Tout simplement en copiant les commandes dans un fichier avec l'extension
ps1. Enlève les "PS>" et autres ">>", et de préférence regroupe une même
commande sur une seule ligne, ça évitera les interprétations erronées ou
ambigues. Par exemple, enlève le retour-chariot après "-eq".

Si tu veux passer le nom de l'ordinateur en paramètre, ajoute une clause
param() en tête du script:

param ($computer = ".")
$proc = gwmi win32_process -computer $computer
etc...

Par défaut, c'est l'ordinateur local qui sera interrogé (".").

Jacques




Avatar
Jacques Barathon [MS]
"Robby" wrote in message
news:
Bonjour et merci pour ton aide,
Voila j'ai rajoute les commandes param et mis sur une ligne -eq, voici mon
fichier test.ps1
param ($computer = ".")
$proc = gwmi win32_process -computer $computer
$proc=gwmi win32_process


Le deuxième "$proc = ..." est en trop. Il fausse les résultats si tu
interroges un ordinateur distant car il remplace la variable $proc initiale
par une requête faite exclusivement sur l'ordinateur local.

gwmi win32_process -computer . -filter "name='svchost.exe'" |
%{$id=$_.processid $date=$_.creationdate;


Dans la ligne ci-dessus il manque un point-virgule avant $date pour séparer
les deux commandes "$id=$_.processid" et "$date=$_.creationdate". Ou alors
tu vas à la ligne. Au passage, le point-virgule en fin de ligne est inutile.

$proc | ?{$_.parentprocessid -eq $id -and $_.creationdate -gt $date}} |
group parentprocessid
donc je lance test.ps1 dans la console mais rien ne se passe il revient au
prompt.


Refais un essai avec les corrections ci-dessus et dis-nous ce que ça donne.

Jacques

1 2 3 4