Question
[Résolu] Comparer deux éléments
- Pas-letemps
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 3
- Remerciements reçus 0
il y a 15 ans 4 mois #8461
par Pas-letemps
[Résolu] Comparer deux éléments a été créé par Pas-letemps
Bonjour,
Je dois effectuer dans le cadre de mon stage, un script qui doit relever l'adresse IP et le nom de la machine dans un fichier .CSV et le comparer avec le fichier original d'adresse mais je bloque à la comparaison...
Le fichier .csv de relevé se présente de cette manière :
\"nom_machine\";\"55.158.4.12\"
et le fichier d'IP original contenant toutes les autres adresses se présente comme ci-dessous :
55.160.4.009;Nom_du_service;\"Nom_Prénom\";\"Netbios\";;;
Je viens de m'initier à Powershell depuis très peu et c'est mon 1er script...
Merci d'avance pour votre aide
(PS: désolé pour la taille de l'image)<br><br>Message édité par: Vivi, à: 11/01/11 13:22
Je dois effectuer dans le cadre de mon stage, un script qui doit relever l'adresse IP et le nom de la machine dans un fichier .CSV et le comparer avec le fichier original d'adresse mais je bloque à la comparaison...
Le fichier .csv de relevé se présente de cette manière :
\"nom_machine\";\"55.158.4.12\"
et le fichier d'IP original contenant toutes les autres adresses se présente comme ci-dessous :
55.160.4.009;Nom_du_service;\"Nom_Prénom\";\"Netbios\";;;
Je viens de m'initier à Powershell depuis très peu et c'est mon 1er script...
Merci d'avance pour votre aide
(PS: désolé pour la taille de l'image)<br><br>Message édité par: Vivi, à: 11/01/11 13:22
Pièces jointes :
Connexion ou Créer un compte pour participer à la conversation.
- Jacques Barathon
- Hors Ligne
- Administrateur
-
Réduire
Plus d'informations
- Messages : 576
- Remerciements reçus 0
il y a 15 ans 4 mois #8464
par Jacques Barathon
Réponse de Jacques Barathon sur le sujet Re:Comparer deux éléments
Bonjour,
Pour un premier script, tu ne t'es pas forcément attaqué au sujet le plus simple. Comparer les éléments de deux tableaux, ça peut se faire de plusieurs façons mais le tout est d'avoir :
a) une vision claire de ce qu'on veut,
b) et une assez bonne maîtrise de la syntaxe de PowerShell.
Concernant le premier point, tu as peut-être une vision claire mais ça ne transparaît ni dans ton script ni dans ton message. Qu'est-ce que tu veux obtenir exactement à la fin de ton script :
- La liste des PC relevés qui figurent bien avec la bonne adresse dans le fichier original ?
- La liste des adresses IP utilisées par des noms Netbios différents de ceux spécifiés dans le fichier original ?
- La liste des adresses IP relevées qui ne figurent pas dans le fichier original ?
- Ou encore autre chose ?
Concernant le deuxième point, j'ai relevé plusieurs fautes de syntaxe ou des contre-sens dans l'usage de certaines commandes. Je reprends juste les principales :
[code:1]
$AdresseIPoriginal = import-csv c:\...\AdresseIP.csv | foreach {$_.psobject.properties} | select value
[/code:1]
La commande ci-dessus contient plusieurs erreurs :
1. Séparateur de champs
Import-csv utilise la virgule comme séparateur de champs par défaut. Or, tes deux CSV, y compris AdresseIP.csv, utilisent le point-virgule.
Tu dois le préciser, soit explicitement avec le paramètre -delimiter, comme implicitement avec le paramètre -useCulture (import-csv utilise alors le séparateur de champs indiqué dans les paramètres régionaux de ton système).
2. En-têtes
Import-csv utilise les champs de la première ligne du fichier comme en-têtes pour les champs suivants. Ca permet d'accéder aux différents champs de chaque ligne via leur nom, comme des propriétés d'objets. Or, tes CSV n'ont pas l'air d'avoir des en-têtes.
Tu dois alors préciser les noms d'en-têtes via le paramètre -header.
3. Propriété Value
Après import-csv tu sélectionnes la propriété Value de chaque objet comme si les objets retournés étaient des tableaux associatifs. Ce n'est pas le cas, cette fin de ligne risque donc de ne rien retourner du tout.
Je coderais donc plutôt la ligne comme ceci :
[code:1]
$AdresseIPoriginal = import-csv c:\...\AdresseIP.csv -useCulture -header \"AdresseIP\", \"NomService\", \"NomPrenom\", \"NomNetbios\"
[/code:1]
Chaque élément de $AdresseIPoriginal pourra alors être adressé, testé et comparé via les noms de propriété donnés en en-tête (les résultats ci-dessous ne font que reprendre la ligne que tu as donnée en exemple :
[code:1]
PS> $AdressIPoriginal[0].AdresseIP
55.160.4.009
PS> $AdressIPoriginal[0].NomNetbios
Netbios
[/code:1]
Tu peux appliquer la même méthode d'importation du CSV en remplacement de la ligne suivante :
[code:1]
$FicIP = get-content c:\...\Export_IPNetbios.csv
[/code:1]
Avec les principes décrits ci-dessus, ça donnera :
[code:1]
$FicIP = import-csv c:\...\Export_IPNetbios.csv -useCulture -header \"NomNetbios\", \"AdresseIP\"
[/code:1]
Chaque ligne du fichier est alors un objet qui a deux propriétés, NomNetbios et AdresseIP.
Enfin, la ligne où tu fais ton compare-object contient plusieurs erreurs :
1. Le paramètre \"differenceObject\" devrait être précédé du signe \"-\".
2. Tu compares deux objets dont la structure est différente :
$AdresseIPOriginal (si tant est que l'importation se fasse correctement) est une collection d'objets qui ont au moins quatre propriétés (l'adresse IP, le nom de service, les nom et prénom de l'utilisateur, et le nom Netbios de la machine), alors que $TabAll est une collection d'objets avec seulement deux propriétés (le nom Netbios et l'adresse IP).
En admettant que les deux tableaux aient été importés avec import-csv comme décrit ci-dessus, tu peux les comparer avec compare-object en précisant sur quelles propriétés la comparaison doit porter :
[code:1]
$AdresseIPoriginal = import-csv c:\...\AdresseIP.csv -useCulture -header \"AdresseIP\", \"NomService\", \"NomPrenom\", \"NomNetbios\"
$FicIP = import-csv c:\...\Export_IPNetbios.csv -useCulture -header \"NomNetbios\", \"AdresseIP\"
compare-object $AdresseIPoriginal $FicIP -property NomNetbios, AdresseIP -includeEqual
[/code:1]
Je te laisse déjà digérer tout ça.
PS. Si tu dois poster une nouvelle version de ton script, évite de coller une image, c'est lourd et surtout pas réutilisable pour des tests... Fais plutôt un copier-coller de ton code entre les balises de code (tu peux les insérer en cliquant sur le bouton \"code\" dans l'éditeur du forum, ou directement les saisir : 'code' entre crochets en début de code, et '/code' entre crochets en fin de code).
Pour un premier script, tu ne t'es pas forcément attaqué au sujet le plus simple. Comparer les éléments de deux tableaux, ça peut se faire de plusieurs façons mais le tout est d'avoir :
a) une vision claire de ce qu'on veut,
b) et une assez bonne maîtrise de la syntaxe de PowerShell.
Concernant le premier point, tu as peut-être une vision claire mais ça ne transparaît ni dans ton script ni dans ton message. Qu'est-ce que tu veux obtenir exactement à la fin de ton script :
- La liste des PC relevés qui figurent bien avec la bonne adresse dans le fichier original ?
- La liste des adresses IP utilisées par des noms Netbios différents de ceux spécifiés dans le fichier original ?
- La liste des adresses IP relevées qui ne figurent pas dans le fichier original ?
- Ou encore autre chose ?
Concernant le deuxième point, j'ai relevé plusieurs fautes de syntaxe ou des contre-sens dans l'usage de certaines commandes. Je reprends juste les principales :
[code:1]
$AdresseIPoriginal = import-csv c:\...\AdresseIP.csv | foreach {$_.psobject.properties} | select value
[/code:1]
La commande ci-dessus contient plusieurs erreurs :
1. Séparateur de champs
Import-csv utilise la virgule comme séparateur de champs par défaut. Or, tes deux CSV, y compris AdresseIP.csv, utilisent le point-virgule.
Tu dois le préciser, soit explicitement avec le paramètre -delimiter, comme implicitement avec le paramètre -useCulture (import-csv utilise alors le séparateur de champs indiqué dans les paramètres régionaux de ton système).
2. En-têtes
Import-csv utilise les champs de la première ligne du fichier comme en-têtes pour les champs suivants. Ca permet d'accéder aux différents champs de chaque ligne via leur nom, comme des propriétés d'objets. Or, tes CSV n'ont pas l'air d'avoir des en-têtes.
Tu dois alors préciser les noms d'en-têtes via le paramètre -header.
3. Propriété Value
Après import-csv tu sélectionnes la propriété Value de chaque objet comme si les objets retournés étaient des tableaux associatifs. Ce n'est pas le cas, cette fin de ligne risque donc de ne rien retourner du tout.
Je coderais donc plutôt la ligne comme ceci :
[code:1]
$AdresseIPoriginal = import-csv c:\...\AdresseIP.csv -useCulture -header \"AdresseIP\", \"NomService\", \"NomPrenom\", \"NomNetbios\"
[/code:1]
Chaque élément de $AdresseIPoriginal pourra alors être adressé, testé et comparé via les noms de propriété donnés en en-tête (les résultats ci-dessous ne font que reprendre la ligne que tu as donnée en exemple :
[code:1]
PS> $AdressIPoriginal[0].AdresseIP
55.160.4.009
PS> $AdressIPoriginal[0].NomNetbios
Netbios
[/code:1]
Tu peux appliquer la même méthode d'importation du CSV en remplacement de la ligne suivante :
[code:1]
$FicIP = get-content c:\...\Export_IPNetbios.csv
[/code:1]
Avec les principes décrits ci-dessus, ça donnera :
[code:1]
$FicIP = import-csv c:\...\Export_IPNetbios.csv -useCulture -header \"NomNetbios\", \"AdresseIP\"
[/code:1]
Chaque ligne du fichier est alors un objet qui a deux propriétés, NomNetbios et AdresseIP.
Enfin, la ligne où tu fais ton compare-object contient plusieurs erreurs :
1. Le paramètre \"differenceObject\" devrait être précédé du signe \"-\".
2. Tu compares deux objets dont la structure est différente :
$AdresseIPOriginal (si tant est que l'importation se fasse correctement) est une collection d'objets qui ont au moins quatre propriétés (l'adresse IP, le nom de service, les nom et prénom de l'utilisateur, et le nom Netbios de la machine), alors que $TabAll est une collection d'objets avec seulement deux propriétés (le nom Netbios et l'adresse IP).
En admettant que les deux tableaux aient été importés avec import-csv comme décrit ci-dessus, tu peux les comparer avec compare-object en précisant sur quelles propriétés la comparaison doit porter :
[code:1]
$AdresseIPoriginal = import-csv c:\...\AdresseIP.csv -useCulture -header \"AdresseIP\", \"NomService\", \"NomPrenom\", \"NomNetbios\"
$FicIP = import-csv c:\...\Export_IPNetbios.csv -useCulture -header \"NomNetbios\", \"AdresseIP\"
compare-object $AdresseIPoriginal $FicIP -property NomNetbios, AdresseIP -includeEqual
[/code:1]
Je te laisse déjà digérer tout ça.
PS. Si tu dois poster une nouvelle version de ton script, évite de coller une image, c'est lourd et surtout pas réutilisable pour des tests... Fais plutôt un copier-coller de ton code entre les balises de code (tu peux les insérer en cliquant sur le bouton \"code\" dans l'éditeur du forum, ou directement les saisir : 'code' entre crochets en début de code, et '/code' entre crochets en fin de code).
Connexion ou Créer un compte pour participer à la conversation.
- Jacques Barathon
- Hors Ligne
- Administrateur
-
Réduire
Plus d'informations
- Messages : 576
- Remerciements reçus 0
il y a 15 ans 4 mois #8466
par Jacques Barathon
Réponse de Jacques Barathon sur le sujet Re:Comparer deux éléments
Une remarque supplémentaire au passage :
J'ai l'impression (je me trompe peut-être ?) que tu as écrit ton script d'un bloc, sans en tester les éléments de manière interactive avant de les mettre ensemble.
Si je me trompe, tant mieux.
Sinon, j'en profite pour rappeler qu'un des très grands avantages de PowerShell sur les autres langages de scripts classiques dont VBScript, c'est cette possibilité de pouvoir travailler rapidement en ligne de commande, y compris avec des éléments de syntaxe évolués comme if, for, do/while, foreach, where, etc., ce qui permet de voir immédiatement si telle(s) commande(s) marche(nt) comme prévu.
Ce n'est qu'une fois qu'on a pu valider chaque bloc de commandes qu'on aura intérêt à les intégrer dans un script pour les enchaîner ou encore tester le passage de paramètres.<br><br>Message édité par: janel, à: 29/12/10 17:01
J'ai l'impression (je me trompe peut-être ?) que tu as écrit ton script d'un bloc, sans en tester les éléments de manière interactive avant de les mettre ensemble.
Si je me trompe, tant mieux.
Sinon, j'en profite pour rappeler qu'un des très grands avantages de PowerShell sur les autres langages de scripts classiques dont VBScript, c'est cette possibilité de pouvoir travailler rapidement en ligne de commande, y compris avec des éléments de syntaxe évolués comme if, for, do/while, foreach, where, etc., ce qui permet de voir immédiatement si telle(s) commande(s) marche(nt) comme prévu.
Ce n'est qu'une fois qu'on a pu valider chaque bloc de commandes qu'on aura intérêt à les intégrer dans un script pour les enchaîner ou encore tester le passage de paramètres.<br><br>Message édité par: janel, à: 29/12/10 17:01
Connexion ou Créer un compte pour participer à la conversation.
- Pas-letemps
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 3
- Remerciements reçus 0
il y a 15 ans 4 mois #8511
par Pas-letemps
Réponse de Pas-letemps sur le sujet Re:Comparer deux éléments
Déjà merci d'avoir pris le temps de répondre, j'y travaille dessus depuis, ça m'a bien éclairé mais je bloque encore faute de méthode..
La façon dont j'ai expliqué mon problème est floue, désolé. Je voudrais en fait vérifier sur une liste des PC relevés si leur adresse figure bien avec la bonne adresse dans le fichier original comme tu as dit en 1er.
Alors j'en suis venu au fait de savoir s'il serait plus simple (et possible ?) d'exporter ma liste d'IP et nom de machine avec des en-têtes en faisant un \" Export-Csv \" et puis la comparer avec le fichier original d'IP
oubien
juste de relever l'IP et le nom de machine puis les mettre dans un tableau pour ainsi les comparer ?<br><br>Message édité par: Vivi, à: 6/01/11 16:46
La façon dont j'ai expliqué mon problème est floue, désolé. Je voudrais en fait vérifier sur une liste des PC relevés si leur adresse figure bien avec la bonne adresse dans le fichier original comme tu as dit en 1er.
Alors j'en suis venu au fait de savoir s'il serait plus simple (et possible ?) d'exporter ma liste d'IP et nom de machine avec des en-têtes en faisant un \" Export-Csv \" et puis la comparer avec le fichier original d'IP
oubien
juste de relever l'IP et le nom de machine puis les mettre dans un tableau pour ainsi les comparer ?<br><br>Message édité par: Vivi, à: 6/01/11 16:46
Connexion ou Créer un compte pour participer à la conversation.
- Arnaud Petitjean
-
- Hors Ligne
- Modérateur
-
il y a 15 ans 4 mois #8517
par Arnaud Petitjean
MVP PowerShell et créateur de ce magnifique forum
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?
Réponse de Arnaud Petitjean sur le sujet Re:Comparer deux éléments
Bonjour Vivi,
Compare-Object s'applique sur des tableaux, donc inutile de passer par des fichiers CSV si ce n'est pas le format d'origine.
Arnaud
Compare-Object s'applique sur des tableaux, donc inutile de passer par des fichiers CSV si ce n'est pas le format d'origine.
Arnaud
MVP PowerShell et créateur de ce magnifique forum
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?
Connexion ou Créer un compte pour participer à la conversation.
- Pas-letemps
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 3
- Remerciements reçus 0
il y a 15 ans 4 mois #8536
par Pas-letemps
Réponse de Pas-letemps sur le sujet Re:Comparer deux éléments
Merci pr l'aide, voilà mon ptit script 
[code:1]# ============================================ #
# SCRIPT PRELEVEMENT ADRESSE IP ET NOM MACHINE #
# ============================================ #
# On relève l'adresse IP
$ip_old = ((ipconfig | findstr [0-9].\.)[0]).Split()[-1]
# On relève le nom de la machine
$hostname = hostname
Write-Host Affichage du Nom de la machine et de son Adresse IP :
Write-Host $hostname $ip_old
# On exporte l'adresse IP de la machine et son nom dans un fichier .csv
write-output $hostname\";\"$ip_old | out-file i:\Powershell\Projet\IP\AdrIP.csv
# On importe dans une variable l'adresse IP et le nom de machine
$FicIPCurrent = Import-CSV -Delimiter \";\" i:\Powershell\Projet\IP\AdrIP.csv -Header \"0 Hostname\", \"0 Adresse IP\"
# On importe le fichier d'adresses IP
$AdresseIP = Import-CSV -Delimiter \";\" i:\Powershell\Projet\IP\AdresseIP.csv
# On compare les fichiers d'adresses IP | On Affiche que les résultats identiques
$compare = Compare-Object $AdresseIP $FicIPCurrent -Property \"0 Hostname\", \"0 Adresse IP\" -IncludeEqual | Where-Object {$_.\"SideIndicator\" -eq '==' }
Write-Host Comparaison de l\"'\"adresse IP avec le fichier d\"'\"adresse IP total :
$compare
# On exporte le nom de la machine et son adresse après vérification
$FicIPCurrent | Select-Object \"0 Hostname\", \"0 Adresse IP\" | Export-CSV i:\Test.csv -UseCulture -noTypeInformation[/code:1]
Au départ j'avais la version 1 de PowerShell du coup je ne comprenais pas pourquoi certains paramètres ne passaient pas donc je suis passé à la version 2 et puis voilà..<br><br>Message édité par: Vivi, à: 11/01/11 13:27
[code:1]# ============================================ #
# SCRIPT PRELEVEMENT ADRESSE IP ET NOM MACHINE #
# ============================================ #
# On relève l'adresse IP
$ip_old = ((ipconfig | findstr [0-9].\.)[0]).Split()[-1]
# On relève le nom de la machine
$hostname = hostname
Write-Host Affichage du Nom de la machine et de son Adresse IP :
Write-Host $hostname $ip_old
# On exporte l'adresse IP de la machine et son nom dans un fichier .csv
write-output $hostname\";\"$ip_old | out-file i:\Powershell\Projet\IP\AdrIP.csv
# On importe dans une variable l'adresse IP et le nom de machine
$FicIPCurrent = Import-CSV -Delimiter \";\" i:\Powershell\Projet\IP\AdrIP.csv -Header \"0 Hostname\", \"0 Adresse IP\"
# On importe le fichier d'adresses IP
$AdresseIP = Import-CSV -Delimiter \";\" i:\Powershell\Projet\IP\AdresseIP.csv
# On compare les fichiers d'adresses IP | On Affiche que les résultats identiques
$compare = Compare-Object $AdresseIP $FicIPCurrent -Property \"0 Hostname\", \"0 Adresse IP\" -IncludeEqual | Where-Object {$_.\"SideIndicator\" -eq '==' }
Write-Host Comparaison de l\"'\"adresse IP avec le fichier d\"'\"adresse IP total :
$compare
# On exporte le nom de la machine et son adresse après vérification
$FicIPCurrent | Select-Object \"0 Hostname\", \"0 Adresse IP\" | Export-CSV i:\Test.csv -UseCulture -noTypeInformation[/code:1]
Au départ j'avais la version 1 de PowerShell du coup je ne comprenais pas pourquoi certains paramètres ne passaient pas donc je suis passé à la version 2 et puis voilà..<br><br>Message édité par: Vivi, à: 11/01/11 13:27
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.044 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- [Résolu] Comparer deux éléments