TP Powershell – String, Regex et petits poneys…

Petit TP PowerShell facile pour une fois, sur la gestion des chaînes de caractères (ou String).
Admettons, pour commencer que l’on est fait un bout de script qui récupère les comptes machines de nos serveurs avec leurs dates de création.

Premier exercice cash ! Écrivez cette commande PowerShell avec Get-ADComputer.

Pour les autres, la solution ci-dessous très bien cachée.

PS C:\> $tab = Get-ADComputer -SearchBase 'OU=Serveurs,DC=equestria,DC=com' -SearchScope Subtree -Filter * -Properties whencreated

Bon, et si on cherche à tester les serveurs donc le nom commence par ‘Pony-‘ pour avoir nos serveurs du projet poney ? Pour commencer doucement on va le faire avec une boucle FOR.

#Ici on crée un tableau vide
$srv_pony = @()

#Pour chaque élément du tableau de tous les serveurs
ForEach($srv in $tab){
    #Si le nom commence par pony
    if($srv.name -match '^pony\-*'){
        #On l’ajoute dans le tableau
        $srv_pony += $srv
    }
}

On récupère alors les serveurs dans l’Active Directory dont le nom de machine commence par pony-. Ceux qui ne connaissent pas ont sûrement remarqué que mon « -match » est un peu étrange. En fait j’utilise la syntaxe des expressions régulières. Les expressions régulières sont avant tout un modèle théorique (utilisé en compilation par exemple) pour gérer des chaînes de caractères, ce modèle est implémenté dans la plupart des langages de programmations. On s’en sert en général pour faire du « search & replace » dans du texte.

Sans rentrer dans les détails techniques Google est votre ami pour ça, il faut lire comme suit :

La variable,

$srv.name

Est conforme avec,

-match

L’expression régulière suivante :

Commence Par

'^

La chaine Pony

Pony

Suivi d’un « – »

\-
*(Backslash permet d’éviter que le tiret soit interprété comme un caractère spécial, comme le `^` juste avant)*

Et qui finit par n’importe  quoi.

*'

Bon, la comme ça, ça parait compliqué pour dire « commence par Pony tiret ». Mais dans la vraie vie, les expressions régulières c’est bon, y’a pas grand-chose d’aussi puissant et à peu près commun à tous les langages de programmation !
=> Donc mangez-en…


 

Petit encart sur les Expressions Régulières (dit RegEx) utilisés ci-dessus.

On peut faire des recherches des patterns très avancés par exemple : trouve-moi toutes les adresses IP V4 ou V6 dans un document texte :

Regex IPV4 :

La structure de l’adresse IP version 4 est très simple. Elle est constituée de 4 nombres allant de 0 à 255 séparés par un point : 1.2.3.4, soit :

(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

Exemple :

PS C:\> '127.0.0.1' –match '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
True
PS C:\> '42.12.A.666' –match '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
False

Regex IPV6 :

La structure des adresses IPv6 est plus complexe. En effet, contrairement à l’IPv4, les mêmes adresses IPv6 peuvent s’écrire différemment. Par exemple, l’adresse `0:0:0:0:0:0:0:1` est la même que l’adresse `::1`. Cette complexité se traduit par une REGEX très, très, longue et compliquée, car elle comprend les différents types d’adresse IPv6 possibles.

La voici :

((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))

Et on fait moins les malins là, hein ?


 

Et maintenant, pour les besoins d’une application, si on a besoin de remplacer tous les Pony- de ces serveurs par des Sangliers_ et d’en faire une liste ?

PS C:\> $srv_pony.Name -replace ('^Pony\-*','Sangliers_')
Sangliers_Applejack
Sangliers_Pinkie-pie
Sangliers_Celestia
Sangliers_Rainbow-Dash
Sangliers_Rarity
Sangliers_Spike
Sangliers_Twilight-Sparkle
Sangliers_fluttershy
Sangliers_Cadance
Sangliers_Shining

Pour finir rapidement, PowerShell implémente les Regex via le .NET, mais on peut également utiliser le Framework .NET directement depuis PowerShell pour ça :

PS C:\> [Regex]::Replace('Peny','e','o')
Pony

Voilà, j’espère vous avoir appris ou rappelé 2-3 truc.

@++

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.