Question controler l'intégrité d'un volume, chkdsk distant

Plus d'informations
il y a 16 ans 6 mois #5282 par Burgun
Bonjour,

Je cherche à créer un script qui check une partition d'un serveur distant pour savoir si des erreur sont détectées.
Faire l'équivalent d'un chkdsk c: .

Voici mon script actuel :

[code:1]
#Récupere les info sur les partitions
$Disks=Get-WmiObject -ComputerName PRD-DOM-BAT01 Win32_LogicalDisk

#Filtre le résultat pour conserver uniquement les info sur la partition C
$C=$Disks | Where-Object {$_.DeviceID -match \"C:\"}

#Parametre de la fonction chkdsk
$FixErreurs = $false # Fixe les erreurs détectées
$Index = $true # Oblige un scanne approfondi des index
$SkipCycle = $false # skip folder cycle checking.
$ForceDem = $false # Force le démondatage du volume pour les corrections
$RestaureSector = $false # Restore les secteurs défectueux
$RunBoot = $false # programme un scanne au redémarrage

#Récuperation du bit d'impureté
$C.VolumeDirty

#Lancement de la méthode CHKDSK
$RES=$C.chkdsk($FixErreurs ,$Index,$SkipCycle ,$ForceDem ,$RestaureSector,$RunBoot )

#Retourne le résultat de la méthode
$res.ReturnValue
[/code:1]

Mon soucis vient du faite que la valeur qui m'est retournée m'indique juste que la commande est bien passée, mais ne me renseigne pas sur l'état du disque.

La ligne $C.VolumeDirty me récupère le bit d'intégrité mais celui-çi peut être placé à false alors que des erreurs existent.

Sur certains serveurs, $C.VolumeDirty est à false mais pourtant quand que je lance un chkdsk c:, j'ai
\"Windows found problems with the file system.\"

Donc comment récupérer ce \"Windows found problems with the file system.\" via un script powershell.

Quelqu'un à une idée ?

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 6 mois #5283 par Laurent Dardenne
Salut,
bvivi57 écrit:

Mon soucis vient du faite que la valeur qui m'est retournée m'indique juste que la commande est bien passée, mais ne me renseigne pas sur l'état du disque.

La valeur de retour d'une fonction a peu à voir avec l'état d'une propriété. Dans ce cas interroge à nouveau la propriété.
Même si dans ce cas il est logique que les 2 informations soient cohérents. Si ce n'est pas le cas soit il y a un bug de logique soit il y a autre chose à faire (reboot ?).
Tu supposes également qu'une opération chkdsk corrige les erreurs en une passe, je n'en suis pas certains.
bvivi57 écrit:

Quelqu'un à une idée ?

En consultant la doc de cette classe WMI, il est dit, à propos de VolumeDirty:

If True, the disk requires ChkDsk to be run at the next restart. This property is only applicable to those instances of logical disk that represent a physical disk in the machine. It is not applicable to mapped logical drives.

Est-ce le cas ?
Il est aussi possible que le driver du provider WMI soit buggué sur ce point là, c'est une piste à ne pas négliger.

La classe Win32_Volume .DirtyBitSet a-t-elle le même comportement ?

Sinon changer ton fusil d'épaule et passer via pesexec+ Fsutil.exe , par exemple.
Ou encore de poster dans le forum US WMI...

[edit]
Concernant la classe Win32_LogicalDisk il est préférable de filtrer les types de disques avant d'interroger la propriété VolumeDirty :
[code:1]
Const LOCAL_HARD_DISK = 3

strComputer = \".\"
Set objWMIService = GetObject(\"winmgmts:\" _
& \"{impersonationLevel=impersonate}!\\\" & strComputer & \"\root\cimv2\"«»)

Set colDisks = objWMIService.ExecQuery _
(\"Select * from Win32_LogicalDisk Where DriveType = LOCAL_HARD_DISK \"«»)

For Each objDisk in colDisks
Wscript.Echo \"Device ID: \"& vbTab & objDisk.DeviceID
Wscript.Echo \"Drive Type: \"& vbTab & objDisk.VolumeDirty
Next
[/code:1]
Source Portable Script Center .<br><br>Message édité par: Laurent Dardenne, à: 14/09/09 19:32

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 6 mois #5284 par Burgun
Merci pour ton aide.

chkdsk ne corrige effectivement pas forcement les erreurs en une passe. Surtout si il s'agit d'un disque système qui nécessitera forcément un reboot pour être corrigé.

L'idée n'est pas de corriger, mais de détecter. Mon objectif final est de pouvoir planifier un script à intervalles régulier (1x par semaine) qui lance un chkdsk sur une liste de serveur et qui remonte par mail un warning si l'un des chkdsk remonte qu'une partition contient des erreurs.

J'ai déja essayer fsutils, mais malheureusement j'ai le même problème. Son utilisation me retourne un disque OK alors qu'un chkdsk m'indique \&quot;Windows found problems with the file system\&quot; et me conseille de lancer à nouveau un chkdsk avec l'option /f pour lancer les réparations.
Le bit que contrôle fsutil et qui je suppose est le même que celui récupérer par VolumeDirty, n'est pas forcement une bonne indication de l'état du disque. Il ne semble être modifié par l'OS que si un certains nombre d'erreurs sont présentes (du moins c'est ce que l'on m'a expliqué)

Les disques sur lesquels j'effectue mes test sont bien des disque locaux aux serveurs avec des partitions de type primaire.

Apparemment la méthode chkdsk de la classe Win32_VolumeDisk n'est pas employée pour vérifier mais pour lancer un chkdsk sans remonter le résultat de l'opération. Elle permet par exemple de planifier un chkdsk lors du prochain reboot pour plusieurs serveurs.

Merci à toi pour le code de filtrage des disques.

Je ne sais pas trop comment m'y prendre ?????
Utiliser psexec pour lancer un chkdsk, récuperer le résultat dans une variable, parcourir cette variable à la recherche de la suite de caractères \&quot;Windows found problems with the file system\&quot; et déclencher un mail en cas de détection.....Mes compétences en powershell sont très limités.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 6 mois #5285 par Laurent Dardenne
bvivi57 écrit:

L'idée n'est pas de corriger, mais de détecter.

Je comprends mieux ton objectif.
bvivi57 écrit:

Le bit que contrôle fsutil et qui je suppose est le même que celui récupérer par VolumeDirty, n'est pas forcement une bonne indication de l'état du disque. Il ne semble être modifié par l'OS que si un certains nombre d'erreurs sont présentes (du moins c'est ce que l'on m'a expliqué)

Bah dés que cela touche à la MFT on tombe dans une zone de brouillard.
bvivi57 écrit:

Je ne sais pas trop comment m'y prendre ?

Je confirme :/
bvivi57 écrit:

Utiliser psexec pour lancer un chkdsk, récuperer le résultat dans une variable, ...

C'est une solution proche du bricolage, car on se lie à un compte rendu formaté, et rien ni personne ne peut confirmer que cela restera comme c'est à l'heure actuelle.
Mais si tu réussis à récupérer le texte de sortie de chkdsk c'est déjà bien, ensuite c'est une question d'analyse et je peux essayer de t'aider là dessus.
bvivi57 écrit:

Mes compétences en powershell sont très limités.

A mon avis, pour le moment ce n'est pas un pb de langage.
Déjà tu t'adresses aux services de WMI est ceux-ci sont défaillant.

Je ne connais pas ce pb, mais j'irais bien regardé du coté des forum de programmation Win32, celui de sysinternals par exemple. C'est souvent trop pointu mais on peut trouver qq infos.
Peut être lancer une sonde là-bas ;-)

Si sur Google code on recherche \&quot;dirty volume ntfs\&quot;, 'ça matche' et sur C# il y en à déjà moins.
A priori cela semble donc possible d'avoir l'info par code, après reste à savoir si c'est simple et comment.
Mais bon ce n'est peut être la piste à suivre.

J'ai regardé rapidement sur Sysinternals et rien ne me semble répondre au besoin. Et pourtant c'est une tâche d'administration basique !

Sinon une autre piste, poster dans www.vistax64.com/powershell/
Ce forum est fréquenté par de nombreuses personnes 'd'horizon technique différent', comme ici, mais multiplié par 50.
Tu peux y trouver d'autres pistes...

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 6 mois #5297 par Burgun
Merci beaucoup pour votre aide.

Finalement, je suis parti sur ma solution \&quot;bricolage\&quot; du moins pour le moment:

Voici le principe :

[code:1]
$Commande=\&quot;$Binaire\psexec.exe \\serveur chkdsk c:\&quot;
$Res=Invoke-Expression $Commande
$Erreur=$Res | Select-String \&quot;Windows found problems\&quot;
$Erreur
if($Erreur -ne \&quot; \&quot;«») {
write-host \&quot;Erreurs disque détectées\&quot;
exit
}
[/code:1]

Cela fonctionne, mais pas mon if. C'est tout bête mais je ne sais pas comment faire pour simplement dire:
Si Erreur prend une valeur, alors déclenche une action.
En effet la ligne \&quot;$Res | Select-String \&quot;Windows found problems\&quot; retourne le contenu de la ligne si celle ci contient \&quot;Windows found problems\&quot;. Si la chaine n'est pas trouvé, ma variable $Erreur reste vide. Du moins, je le pensais car je rentre constamment dans mon if, peu importe la valeur de $Erreur.
C'est vraiment un problème de débutant, mais je ne comprend pas pqr mon if ne fonctionne pas.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 16 ans 6 mois #5298 par Laurent Dardenne
bvivi57 écrit:

je ne comprend pas pqr mon if ne fonctionne pas.

Sous PS on manipule des objets qui peuvent être $null ou pas.

Si $Erreur contient une string dans ce cas là on peut tester sur [string]:Empty (une chaîne vide).
mais si l'objet contenu dans $Erreur est $null, ton test ne fonctionnera pas.

Pour info, Select-String renvoi un objet de type Microsoft.PowerShell.Commands.MatchInfo, même si cela ne pose pas de pb dans ton test car PowerShell cast le résultat en une String.

Je testerais comme ceci :
[code:1]
$Result=chkdsk /i #local
$Erreur=$Result | Select-String \&quot;Windows found problems\&quot;
if (($Erreur -ne $Null) -and ($Erreur -ne [String]::Empty)) {
write-host \&quot;Erreurs disque détectées\&quot;
Exit #Si vraiment tu veux quitter la session, sinon utiliser Break
}
[/code:1]
Pour résumer, puisque ces 2 cas peuvent se présenter, tu dois tester si l'objet n'est pas $null ET si la chaîne n'est pas vide.
Le truc à savoir est que PowerShell optimise le test -and, si la première condition est fausse la seconde n'est pas testée.

Quelques tests :
[code:1]
$Erreur=$null
$Erreur -eq $null #True
$Erreur -ne \&quot;\&quot; #True
$Erreur -ne [string]::Empty #True
$Erreur -ne \&quot; \&quot; #True

$Erreur=[string]::Empty
$Erreur -eq $null #False
$Erreur -ne \&quot;\&quot; #False
$Erreur -ne [String]::Empty #False
$Erreur -ne \&quot; \&quot; #True
[/code:1]
Ces tests sont tjr vrai lorsque l'objet est $Null.

Si on inverse la logique de test :
[code:1]
$Erreur=$null
$Erreur -ne $null #False
$Erreur -eq \&quot;\&quot; #False
$Erreur -eq [string]::Empty #False
$Erreur -eq \&quot; \&quot; #False

$Erreur=[string]::Empty
$Erreur -ne $null #True
$Erreur -eq \&quot;\&quot; #True
$Erreur -eq [String]::Empty #True
$Erreur -eq \&quot; \&quot; #False
[/code:1]

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.050 secondes
Propulsé par Kunena