2 Question: Dans Powershell, quel est le meilleur moyen de joindre deux tables en une seule?

question créée à Thu, Jul 29, 2010 12:00 AM

Je suis assez nouveau chez Powershell et je me demande si quelqu'un connaît une meilleure façon de résoudre le problème d'exemple suivant.

J'ai un tableau de mappages d'adresse IP à nom d'hôte. Ceci représente une liste des baux DHCP actifs:

 
PS H:\> $leases

IP                    Name
--                    ----
192.168.1.1           Apple
192.168.1.2           Pear
192.168.1.3           Banana
192.168.1.99          FishyPC

J'ai un autre tableau de mappages d'adresse MAC à adresse IP. Ceci représente une liste de réservations IP:

 
PS H:\> $reservations

IP                    MAC
--                    ---
192.168.1.1           001D606839C2
192.168.1.2           00E018782BE1
192.168.1.3           0022192AF09C
192.168.1.4           0013D4352A0D

Par souci de commodité, j’ai pu créer un troisième tableau de mappages d’une adresse MAC à une adresse IP et un nom d’hôte à l’aide du code suivant. L'idée est que $reservations devrait recevoir un troisième champ, "Nom", qui est rempli chaque fois qu'il existe un champ "IP" correspondant:

 
$reservations = $reservations | foreach {
    $res = $_
    $match = $leases | where {$_.IP -eq $res.IP} | select -unique
    if ($match -ne $NULL) {
        "" | select @{n="IP";e={$res.IP}}, @{n="MAC";e={$res.MAC}}, @{n="Name";e={$match.Name}}
    }
}

La sortie souhaitée ressemble à ceci:

 
PS H:\> $ideal

IP                    MAC                 Name
--                    ---                 ----
192.168.1.1           001D606839C2        Apple
192.168.1.2           00E018782BE1        Pear
192.168.1.3           0022192AF09C        Banana
192.168.1.4           0013D4352A0D

Existe-t-il un meilleur moyen de le faire?

    
15
  1. Il est presque incroyable que cela ne soit toujours pas inclus dans PowerShell
    2011-07-20 15: 36: 12Z
  2. @ Michael Comment avez-vous pu obtenir un tableau d'adresse IP à nom d'hôte pour tous les baux en cours? J'utilise le module DHCP mais je ne peux pas le comprendre. J'essaie également de combiner certaines tables.
    2011-09-22 16: 37: 00Z
  3. @ Ruisu J'utilisais la commande dhcp de netsh pour obtenir une liste, puis analysais le résultat avec des expressions régulières. Il existe également la API de gestion de serveur DHCP , mais il n’est disponible que pour le code natif. Je ne connais aucun module powershell ou bibliothèque .net pour faire ce genre de chose. J'ai fini par écrire des wrappers P /Invoke dans l'API de gestion de serveur DHCP.
    2011-09-23 18: 07: 41Z
2 réponses                              2                         

Lee Holmes a rédigé un bloguer sur une fonction Join-Object qui fait ce que vous voulez. Dommage qu'il ne soit pas encore intégré à PowerShell.

    
9
2016-07-19 20: 06: 55Z
  1. Merci. C'est exactement ce que j'avais besoin de savoir.
    2009-12-04 22: 13: 59Z
  2. 2016-07-19 20: 08: 40Z

Après 1,5 ans, la cmdlet que j'ai collée dans la réponse d'origine a subi tellement de mises à jour qu'elle est devenue complètement obsolète. C'est pourquoi j'ai remplacé le code et le Lisez-moi avec un lien vers la dernière version.

Objet-jointure

L'objet Join peut être téléchargé à partir de la galerie PowerShell à l'aide de la commande suivante:

 
Install-Script -Name Join

Le package Join comprend la commande Join-Object (alias Join) et les commandes de proxy suivantes:

  •  InnerJoin-Object, alias InnerJoin (Join-Object -JoinType Inner)
    Renvoie uniquement les objets joints
  •  LeftJoin-Object, alias LeftJoin (Join-Object -JoinType Left)
    Renvoie les objets joints et le reste des objets de gauche
  •  RightJoin-Object, alias RightJoin (Join-Object -JoinType Right)
    Renvoie les objets joints et le reste des objets appropriés
  •  FullJoin-Object, alias FullJoin(Join-Object -JoinType Full)
    Renvoie les objets joints et le reste des objets gauche et droit
  •  CrossJoin-Object, alias CrossJoin (Join-Object -JoinType Cross)
    Joint chaque objet de gauche à chaque objet de droite
  •  Update-Object, alias Update (Join-Object -JoinType Left -Merge = {RightOrLeft.$_})
    Met à jour l'objet de gauche avec les propriétés de l'objet de droite
  •  Merge-Object, alias Merge (Join-Object -JoinType Full -Merge = RightOrLeft.$_})
    Met à jour l'objet de gauche avec les propriétés de l'objet de droite et les insère right si les valeurs de la propriété associée ne sont pas égales.

Fichier Lisez-moi

Le fichier complet (ainsi que le code source) est disponible sur GitHub: https://github.com/iRon7 /Join-Object

Installation

Après le téléchargement (Install-Script -Name Join), le script peut simplement être appelé par sourçage des points :

 
. .\Join.ps1

Vous pouvez également envisager de convertir le script en module PowerShell en le renommant en un fichier de module PowerShell ( .psm1 ) et en le déplaçant vers l'un des dossiers de module définis dans $env:PSModulePath. Pour plus de détails, voir: Comment écrire un module de script PowerShell .
Remarque: la commande Import-Module est requise pour charger les commandes proxy.

Répondre

Pour répondre à l'exemple réel dans la question:

 
$reservations | LeftJoin $leases -On IP

IP          MAC          Name
--          ---          ----
192.168.1.1 001D606839C2 Apple
192.168.1.2 00E018782BE1 Pear
192.168.1.3 0022192AF09C Banana
192.168.1.4 0013D4352A0D

Exemples

Vous trouverez d'autres exemples dans les questions sur Stackoverflow à l'adresse suivante:

Et dans le Test de jointure d'objet script .

    
14
2019-05-03 06: 58: 09Z
  1. Après 7,8 ans, cette question a reçu une autre réponse.
    2017-08-03 12: 40: 59Z
  2. Mise à jour de révision: a fusionné les paramètres -Expressions [HashTable] et -DefaultExpression [ScriptBlock] en un seul -Merge [HashTable|ScriptBlock] prenant en charge un HashTable pour des expressions de fusion spécifiques ou un ScriptBlock pour une expression de fusion commune.
    2017-08-08 14: 32: 10Z
  3. Bogue résolu: le tableau gauche contient une seule colonne
    .
    2017-10-24 18: 32: 21Z
  4. Excellente fonction, mais prudent si vous l'utilisez depuis un module Powershell. En raison du fonctionnement de la portée, les variables $Left et $Right ne seront pas disponibles dans le bloc de script -Merge (les variables des modules sont privées du module, le bloc de script ne peut donc pas les voir). Ce n’est pas un problème si le sourçage ou l’inclusion directe de la fonction dans le script l’appelle.
    2018-02-22 12: 40: 20Z
  5. @ Omni, j'ai effectué quelques tests en plaçant la cmdlet dans un module, mais je n'ai pas pu confirmer votre problème. Néanmoins, lors de la révision de la cmdlet, j'ai trouvé un bogue assez gros qui est décrit à Résultats inattendus lors de la réutilisation d'objets personnalisés dans le pipeline . J'ai créé une version branchée qui a été collée dans cette réponse. Je suppose que c'est en fait le problème que vous avez rencontré (je l'apprécierai si vous pouviez confirmer si tel est le cas ou non).
    2018-03-11 18: 18: 40Z
source placée ici