Get-ADComputer exporter adresseMAC en csv

Bonjour,

Je cherche un moyen d'exporter en csv toutes les adresses MAC des ordinateurs de l'Active Directory.

J'ai une piste de commande avec powershell mais cela ne m'exporte pas les adresses MAC. J'obtiens seulement les noms de machines et à la place de l'adresse MAC il y a noté "Microsoft.ActiveDirectory.Management.ADPropertyValueCollection

Name	networkAddress
B12-01	Microsoft.ActiveDirectory.Management.ADPropertyValueCollection
A16-04  Microsoft.ActiveDirectory.Management.ADPropertyValueCollection
B12-03	Microsoft.ActiveDirectory.Management.ADPropertyValueCollection

pourtant quand je lance la commande dans powershell j'obtiens bien les adresses MAC entre crochet {}

B12-03     {EC-B1-D7-46-05-22}
SDP-05     {9C-7B-EF-BB-EA-89}
B12-02     {EC-B1-D7-41-9C-B6}
B12-01     {EC-B1-D7-41-1D-C2}
B18-02     {EC-B1-D7-41-9C-BC}
B18-01     {EC-B1-D7-46-05-51}

voici mon script

Get-ADComputer -Filter * -Properties Name,networkAddress | Select-Object Name,networkAddress | Export-CSV -Path "c:\macadress.csv" -delimiter ";" -NoTypeInformation -Force

Comment faire en sorte d'avoir mon fichier csv avec dans la colonne A les noms de machine et dans la colonne B les Adresse MAC ?
Windows / Firefox 127.0

6 réponses

  1. Bonjour,

    Je n'ai pas d'Active Directory et donc pas moyen de tester.

    Puisque tu nous dis que c'est l'export qui débloque et pas la commande PowerShell elle-même, pas moyen de tricher dans un Batch en transitant par un fichier texte de ce style?
     

    @echo off
    CHCP 65001>NUL
    
    powershell.exe -command "& { Get-ADComputer -Filter * -Properties Name,networkAddress  | Select-Object Name,networkAddress | Format-Table -HideTableHeaders }">>%~dp0_test.txt
    
    FOR /F "tokens=1,2 skip=1 delims=" %%J in ('type "%~dp0_test.txt"') DO SET name=%%J & SET mac=%%K & CALL :PROCESS
    GOTO END
    
    :PROCESS
    SET name=%name:~0,-1%
    SET mac=%mac:~0,-1%
    ECHO %name%;%mac%>test.csv
    exit /b
    
    :END



     

    1. merci pour l’astuce. En effet j'avance un peu mais ce batch ne me permet pas d'obtenir un csv complet il ne récupère que la dernière ligne du fichier .txt alors que le fichier txt créé est bien complet avec les 250 machines+macaddress.

      J'ai testé autre chose et toutes mes adresse mac peuvent etre récupérées avec la simple commande sans besoin de passer par le fichier .txt :

      powershell.exe -command "& { Get-ADComputer -Filter * -Properties Name,networkAddress | Select-Object Name,networkAddress | Format-Table -HideTableHeaders}">>%~dp0_test2.csv

      Le probleme c'est que tout est dans la même colonne dans mon .csv. Le nom du PC et l'adresse mac entre crochet. L'idée serait d'avoir le nom en colonne A et l'adresse MAC en colonne B sans les crochets

      Comment séparer les données obtenus dans le csv dans des colonnes différentes ?

      1. Je suis très nul en PowerShell, il faudrait rediriger la sortie de chaque paramètre vers une variable puis concaténer chacun séparée du point-virgule pour redirection vers le fichier csv.

        Dans l'approche Batch précédente, que dit le fichier texte temporaire, une seule ligne ou toutes?

        Dans la deuxième hypothèse, ce sont mes paramètres FOR au pifomètre qui ne sont pas corrects, tokens et consorts si de fait il n'y en avait qu'un (pas réellement d'espace entre le nom et le mac).

        Une telle hypothèse est facile à contourner si le nom a toujours le même nombre de caractères (6): si c'est ma variable name qui contient tout y compris le mac, j'écris:
         

        SET name1=%name:~0,6%
        
        et de manière comparable j'extrais le mac par quelque chose du genre
        (tester la position):
        
        SET mac=%name:~7,19%
        
        si j'ai bien compté et y compris les crochets
        
        Je vais ensuite supprimer le crochet ouvrant:
        
        set "mac=%mac:~1%"
        
        puis fermant:
        
        set mac=%mac:~0,-1%
        
        Si le fichier texte ne contient lui-même que la dernière ligne,
        curieux, c'est qu'il faut soit incrémenter la commande PowerShell
        par FOREACH ou équivalent, je n'y compris rien, soit l'intégrer dans
        une boucle FOR appelant comme dans l'exemple précédent par CALL
        le traitement itératif de chaque valeur des variables.
        
    2. pardon c'est ok en fait juste 2 modif à faire sur le batch en espace après delims= et >> à la place de > pour ajouter toutes les lignes à la suite

      @echo off
      CHCP 65001>NUL
      
      powershell.exe -command "& { Get-ADComputer -Filter * -Properties Name,networkAddress | Select-Object Name,networkAddress | Format-Table -HideTableHeaders }">>%~dp0_test.txt
      
      FOR /F "tokens=1,2 skip=1 delims= " %%J in ('type "%~dp0_test.txt"') DO SET name=%%J & SET mac=%%K & CALL :PROCESS
      GOTO END
      
      :PROCESS
      SET name=%name:~0,-1%
      SET mac=%mac:~0,-1%
      ECHO %name%;%mac%>>test.csv
      exit /b
      
      :END
      ma question c'est du coup plutôt comment supprimer les crochet {} qui entourent l'adresse mac ? 
      1. ok il faut en fait les 17 premiers caractères de %MAC% à compter de la position 1 d'où : SET mac=%mac:~1,17%

        voici le script qui fonctionne avec en colonne B l'adresse MAC sans les {}

        @echo off
        CHCP 65001>NUL
        
        powershell.exe -command "& { Get-ADComputer -Filter * -Properties Name,networkAddress | Select-Object Name,networkAddress | Format-Table -HideTableHeaders }">%~dp0_test.txt
        
        FOR /F "tokens=1,2 skip=1 delims= " %%J in ('type "%~dp0_test.txt"') DO SET name=%%J & SET mac=%%K & CALL :PROCESS
        GOTO END
        
        :PROCESS
        SET name=%name:~0,-1%
        SET mac=%mac:~1,17%
        ECHO %name%;%mac%>>test.csv
        
        exit /b
        
        :END

        Ma dernière idée c'est de pouvoir classer les données selon les noms de machines, en créant un fichier .csv par salle. Par exemple dans le fichier j'ai A01-01,... 06 qui doit intégrer un fichier unique appelé A01, et ainsi de suite selon le début du nom de machines

        est ce qu'il existe une commande pouvant faire cela ? du genre si les 4 premiers caractère du nom de machine sont identique alors regrouper toutes les lignes correspondantes et les extraire dans un fichier csv spécifique.

        1. Tu veux dire si j'ai bien suivi selon les 3 premiers caractères, par exemple B12?

          Quelque chose de ce genre?
           

          :PROCESS
          SET name=%name:~0,-1%
          SET number=%name:~1,3%
          SET mac=%mac:~1,17%
          ECHO %name%;%mac%>>%number%.csv
          exit /b
          
      2. oui merci c'est bien ça c'était tout bête. Le pb c'est que parfois ce sont les 3 premiers parfois les 4 ou les 5 premiers caractères qui détermine la salle donc j'ai récupéré une astuce qui permet de sélectionner tous les caractères avant le tiret - puisque mes salles sont nommées par exemple B310i-xx ou A01-XX

        :PROCESS
        SET name=%name:~0,-1%
        SET mac=%mac:~1,17%
        set salle=%name:-=&:"%"
        mkdir salle
        ECHO %name%;%mac%>>salle\%salle%.csv

        Me reste à trouver comment trier les données selon la colonne 1, par nom de machine, car tout est dans le désordre.

        1. Tu veux dire que tu as bien des fichiers séparés mais que par exemple pour B12 B12-03 sort avant B12-02?

          C'est apparemment l'ordre de sortie de la commande PowerShell, je ne vois pas trop de moyen d'y remédier sauf à modifier cette commande pour qu'elle sorte selon "Name" ascendant ou alphabétique, ce qui devrait revenir au même, je ne sais pas comment.

          Ou évidemment de faire un tri alphabétique sur la colonne concernée de chacun des fichiers concernés une fois générés au format csv ou xlsx.

        2. @brucine

          oui c'est ça.  j'ai trouvé une astuce dans powershell en effet

          powershell.exe -command "& { Get-ADComputer -Filter * -Properties Name,networkAddress | Select-Object Name,networkaddress | Sort-object Name -unique | Format-Table -HideTableHeaders }">%~dp0_test.txt

          il existe le paramètre -descending mais pour l’ordre alphabétique il semble que c'est -unique (et non pas -ascending)

        3. @adgm1

          Sinon peut-être une recette de cuisine a posteriori:

          SORT %salle%.csv

      3. Une idée pour exclure les lignes contenant le mot "prof"? je souhaite avoir dans mon fichier .csv uniquement les nom de machine eleve qui ne contiennent pas ce mot

        Jai tenté cette commande mais elle me revient en erreur

        powershell.exe -command "& { Get-ADComputer -Filter * -Properties Name,networkAddress| Select-Object Name,networkaddress  | Sort-object Name -unique | Select-String -Pattern "prof" -notMatch| Format-Table -HideTableHeaders }">%~dp0_test.txt

        je ne suis pas sur de la manœuvre powershell avec select-string + notMatch

        peut etre un moyen avec une commande batch ?

        1. C'est sûrement possible en PowerShell mais dont je t'ai déjà dit que j'y suis assez nul.

          Dans tous les cas, je suppose que le mot "prof" apparaît dans le nom de la salle, quelque chose sur le mode Bxx-prof, mais la question est de savoir à quel endroit il apparaît dans cette chaîne.

          Je n'ai pas de difficulté à écrire:

          IF NOT "%name%"=="prof" ECHO...

          mais ça ne suffit pas puisque ce n'est pas le nom lui-même qui vaut prof, mais une partie.

          On peut alternativement quelle que soit la position chercher "prof" dans %name% par une syntaxe FINDSTR comme illustré par exemple ici:

          https://stackoverflow.com/questions/5491383/find-out-whether-an-environment-variable-contains-a-substring

        2. @brucine

          merci, jai fait différemment du coup en ajoutant une ligne powershell qui va lire le fichier .txt pour supprimer toutes les lignes contenant "prof" puis en recréant un nouveau fichier .txt. Ca marche même si cest un peu de la bidouille

          powershell.exe -command "& { Get-ADComputer -Filter * -Properties Name,networkAddress | Select-Object Name,networkaddress | Sort-object Name -unique | Format-Table -HideTableHeaders }" >%~dp0_list.txt
          
          powershell.exe -command "& { get-content %~dp0_list.txt | select-string -pattern "prof" -notmatch }" >%~dp0_list2.txt
          del /f %~dp0_list.txt
           
          FOR /F "tokens=1,2 skip=1 delims= " %%J in ('type "%~dp0_list2.txt"') DO SET name=%%J & SET mac=%%K & CALL :PROCESS
          GOTO END
        3. @adgm1

          Oui, tu aurais eu le même résultat directement dans la console avec
          FINDSTR /V C:"prof" ou en redirigeant aussi vers un nouveau fichier texte traité avec FINDSTR, et cela aura été de la bidouille pas vraiment élégante tout pareil, mais PowerShell ou Batch, seul le résultat compte.