mercredi 6 mars 2013

Powershell : Astuces en vrac

J'ai commencé à regarder sérieusement du côté de Powershell assez récemment. Je dirais que le langage est assez facilement appréhendable par sa ressemblance avec un shell Linux, mais la seule subtilité est le "tout" objet qu'il vaut mieux respecter si on veut conserver sa force.

C'est un précieux conseil que j'ai trouvé dans la convention de codage de Powersploit (ne me demander comment je suis tombé là-dessus...).

Contrairement à Linux l'idée n'est pas d'écrire sur la sortie standard mais d'y pousser un objet qui pourra être manipulé par la suite. Vous aurez un exemple sur le site de Microsoft ici : http://technet.microsoft.com/en-us/library/ff730946.aspx

La conservation d'un objet et non d'un bloc de texte va permettre de faire des requêtes façon SQL. Je vais présenter comment je raffine une recherche de non-conformité sur des comptes administrateur locaux.

Hypothèse 1 : J'ai une liste de CSV contenant tous les dump des groupes locaux les machines de mon parc.
Hypothèse 2 : Je recherche des comptes utilisateur (UserAccount) et non des groupes.
Hypothèse 3 : Les colonnes de mon CV sont Compte, Categorie, Domaine et Machine

Get-ChildItem .\temp\ | where {$_.Extension -eq ".csv"} |
    Import-Csv | Where-Object {$_.group -eq "Administrateurs"} | 
    Where-Object {$_.Compte -ne "Administrateur"} | 
    Where-Object {$_.Categorie -eq "UserAccount"} | 
    sort Machine, Compte | Export-Csv -notype ".\admin\AdminNonConformes.csv"

J'obtiens la liste des comptes utilisateurs (locaux ou de domaine) disposant des droits administrateur et le tout ranger par nom de machine.

Petit décryptage :
Get-ChildItem liste les enfants d'un objet, ici pour un répertoire il s'agit de son contenu. Il est même possible de faire une recherche récursive pour chercher dans les sous-dossiers. Remarque, il n'est pas possible de limiter la profondeur de récursivité mais des scripts existent.

Le pipe comme sous Linux passe le résultat à la commande suivante.

Import-Csv permet d'importer d'un fichier texte en le convertissant sous forme d'objet requêtable. Si les types de colonne ne sont pas définis chaque champ est pris comme du texte. Ici nous importons donc plusieurs fichiers CSV et un seul ensemble cohérent est créé et va être traité par la suite.

Where va réaliser un test sur chaque objet un par un. L'objet en cours est nommé $_. Il faut faire attention dans les sous-requêtes car l'objet courant peut changer et il faut alors créer un tampon avec la valeur intéressante. Par exemple :

$liste_postes | ForEach-Object {
    $compte = $_.compte
    $match = $liste_admin | Where-Object {$_.compte -eq "$compte"} | Select-Object *
}

Le premier $_ correspond à un ordinateur de $liste_poste, puis $_ correspond à un administrateur de $liste_admin. Cela me permet de comparer les comptes administrateur avec une base de dérogation.

Export-Csv, comme son nom l'indique, va exporter tout notre bazar dans un fichier CSV. A noter quelques arguments intéressants :

  • -notype : évite la ligne de typage des champs (texte, nombre, ...). La sortie est plus "propre"
  • -Encoding Unicode : pour celui-là j'ai eu du mal. C'est lui qui permettra d'enregistrer correctement des lettres accentuées dans des CSV
A noter que Powershell encadre tous les champs de doubles quotas, ce qui n'est utile que lorsque le texte peut contenir des virgules. Il est possible de nettoyer le CSV avec la commande suivante :
Get-Content fichier.csv | 
    % {$_ -replace '"', ""} |  
    Out-File "fichier.csv"

J'espère que ce n'est pas trop indigeste pour ce premier article sur Powershell.

Aucun commentaire:

Enregistrer un commentaire