Claude Couderc Consulting

PowerShell pour créer un fichier

Dans cet article, vous découvrirez une commande PowerShell pour créer un fichier. Cet article est l’occasion de passer en revue les principales particularités des formats de fichier et les commandes associées.

En effet, les “vrais” fichiers recèlent des pièges liés aux données elles-mêmes: présence de virgule ou de point-virgule dans les données au format CSV, etc.

Commande PowerShell pour créer un fichier : Out-File

En particulier, pour obtenir la liste des services Windows qui s’exécutent sur votre ordinateur dans un fichier texte, vous allez utiliser la commande Out-File.

Aussi, ouvrez une invite de commande PowerShell en tant qu’Administrateur et tapez :

Get-WmiObject win32_service | Out-File services.txt

Ensuite, ouvrez le fichier services.txt avec Notepad++. Vous lisez :

ExitCode : 0
Name : AdobeARMservice
ProcessId : 1780
StartMode : Auto
State : Running
Status : OK

ExitCode : 0
Name : AdobeFlashPlayerUpdateSvc
ProcessId : 0
StartMode : Manual
State : Stopped
Status : OK

Dans ce cas, vous ne récupérez qu’une partie des informations d’un service, la disposition est sous forme de fiche et le fichier est encodé en UCS-2 Little Endian.

Commande PowerShell pour créer un fichier Encodage UTF-8

Ensuite, pour avoir un encodage UTF-8, tapez :

Get-WmiObject win32_service | Out-File .services.txt -Encoding "UTF8"

Par ailleurs, Get-WmiObject win32_service produit un résultat sous forme de liste. Aussi, pour avoir une disposition tabulaire, vous essayez :

Get-WmiObject win32_service | Format-Table | Out-File .services.txt -Encoding "UTF8"

Notamment, le résultat donne :

ExitCode Name ProcessId StartMode State Status
——– —- ——— ——— —– ——
AdobeARMservice 1780 Auto Running OK
AdobeFlashPlayer… 0 Manual Stopped OK

Le “Name” est partiel. La mise en forme est peu pratique pour un traitement automatisé.

Commande PowerShell pour créer un fichier avec Get-Service

Ensuite, le résultat ne vous convenant toujours pas, vous changez de commande pour obtenir la liste des services.

Cette fois-ci, au lieu d’utiliser Get-WmiObject win32_service, vous essayez la commande Get-Service qui par défaut produit un résultat sous forme de tableau :

Get-Service | Out-File .services.txt -Encoding "UTF8"

Le résultat est encore différent :

Status Name DisplayName
—— —- ———–
Running AdobeARMservice Adobe Acrobat Update Service
Stopped AdobeFlashPlaye… Adobe Flash Player Update Service

En fait, la colonne Name (ainsi que DisplayName) est tronquée.

Commande PowerShell pour créer un fichier : Export-Csv

Maintenant, au lieu d’utiliser Out-File, vous allez utiliser Export-Csv.

Aussi, tapez la commande suivante :

Get-WmiObject win32_service | Export-Csv .services.csv -Encoding "UTF8"

Puis, ouvrez le fichier services.csv avec Notepad++ et vous voyez apparaître beaucoup plus d’informations sous forme quasi-tabulaire:

#TYPE System.Management.ManagementObject#rootcimv2Win32_Service
“PSComputerName”,”__GENUS”,”__CLASS”,”__SUPERCLASS”,”__DYNASTY”,”__RELPATH”,…
“MONORDINA”,”2″,”Win32_Service”,”Win32_BaseService”,”CIM_ManagedSystemElement”,”Win32_Service.Name=””AdobeARMservice”””,…
“MONORDINA”,”2″,”Win32_Service”,”Win32_BaseService”,”CIM_ManagedSystemElement”,”Win32_Service.Name=””AdobeFlashPlayerUpdateSvc”””,…

Ensuite, pour éliminer la première ligne, il suffit de rajouter le paramètre -NoTypeInformation à la ligne de commande:

Get-WmiObject win32_service | Export-Csv .services.csv -Encoding "UTF8" -NoTypeInformation

Enfin, ouvrez le fichier services.csv avec Microsoft Office Excel.

Lors de son ouverture, Excel a détecté la présence du séparateur “;” dans certaines lignes et il a séparé les données concernées dans la seconde colonne (“B”). Par exemple la description du “Service de cache de police Windows” contient un “;”: “[…] Il peut être désactivé ; il en résulte cependant une dégradation des performances des applications.”

Délimiteur spécifique

La présence inopportune du séparateur “;” va rendre plus complexe le traitement des données lors de l’utilisation d’un Split(). Aussi, pour contourner ce problème, vous décidez de changer de délimiteur en choisissant un caractère plus rare comme ¤.

La commande devient:

Get-WmiObject win32_service | Export-Csv .services.csv -Delimiter "¤" -Encoding "UTF8" -NoTypeInformation

Lorsque vous ouvrez le fichier services.csv avec Microsoft Office Excel, celui-ci n’arrive pas à séparer les colonnes automatiquement: l’assistant d’importation de texte se lance.

PowerShell pour créer un fichier
Assistant d’importation de texte d’Excel

Vous pouvez réduire le nombre de colonnes avec l’utilisation de la commande Select-Object. Par exemple, si vous ne voulez que le nom et la description (“Caption”) de chaque service, vous tapez la commande suivante:

Get-WmiObject win32_service | Select-Object Name, Caption | Export-Csv .services.csv -Delimiter “¤” -Encoding “UTF8” -NoTypeInformation

Le fichier résultat est plus sobre:

“Name”¤”Caption”
“AdobeARMservice”¤”Adobe Acrobat Update Service”
“AdobeFlashPlayerUpdateSvc”¤”Adobe Flash Player Update Service”

Commande PowerShell pour créer un fichier : Import-Csv

Pour retraiter le fichier résultat, utilisez la commande PowerShell Import-CSV suivante :

Import-Csv .services.csv -Delimiter "¤"
Commande PowerShell Import-Csv
Commande PowerShell Import-Csv

Pour traiter une seule colonne, vous utilisez la fonction Split() ou la variable automatique $_.

La commande suivante fournit la description de tous les services dont le nom débute avec la lettre “A”:

Import-Csv .services.csv -Delimiter "¤" | ForEach-Object {if($_.Name.StartsWith("A")){write-host $_.Caption}}

Si votre fichier services.csv ne possédait pas d’entête, la commande précédente échouerait. Pour y remédier, il suffit d’indiquer un entête dans la commande Import-Csv avec le paramètre Header:

Import-Csv .services.csv -Header ("Name","Caption") -Delimiter "¤" | ForEach-Object {if($_.Name.StartsWith("A")){write-host $_.Caption}}

Le résultat donne quelque chose comme:
Adobe Acrobat Update Service
Adobe Flash Player Update Service

Supprimer les double guillemets

Lorsque vous utilisez Export-CSV, cette commande ajoute automatiquement des guillemets autour de chaque donnée retournée.

Notamment, pour enlever tous les guillemets des fichiers CSV à l’aide de PowerShell, l’article de Hey, Scripting Guy! donne une solution qui combine l’utilisation des commandes Export-Csv et Out-File. Toutefois, cette solution n’est pas pleinement satisfaisant car elle remplace aussi les guillemets qui seraient à l’intérieur d’une donnée !

(Get-Content .services.csv) -replace '"', "" | Out-File .services.csv -Encoding "UTF8" -Force

Ensuite, faites attention à l’affichage ambiguë des guillemets et des quotes dans WordPress. L’opérateur -replace a comme premier argument ‘”‘, soit: une quote, un guillemet, une quote.

En effet, le second argument est “”, soit: un guillemet, un guillemet.

Par ailleurs, le paramètre -Force permet d’écraser un fichier en lecture seule.

Enfin, une solution moins radicale consiste à utiliser une expression régulière. Celle-ci utiliserait alors la fonction replace pour supprimer uniquement les guillemets en début et en fin de chaîne de chaque donnée: ‘^”(.*)”$’, ‘$1’.

Ainsi, le replacement doit se faire sur chaque donnée, et non pas ligne par ligne.

Tableaux et Arrays PowerShell

Face à la diversité des choix, vous pouvez être tenté de manipuler toutes les données à l’aide de tableaux (“Arrays”) plutôt que de les stocker temporairement dans un fichier.

Si le volume de données manipulées n’est pas disproportionné, ce choix est souvent judicieux car la manipulation en mémoire reste souvent plus rapide que l’écriture sur un disque dur.

Toutefois, pour des raisons de conservations d’historique ou de traçabilité, vous devrez peut-être enregistrer les données manipulées dans un fichier.

Dans ce cas, n’utilisez pas l’opérateur -replace sur les objets. En effet, les commandes suivantes risquent de produire un résultat différent de vos attentes:

# Génére un fichier CSV à partir de la liste des services de l'ordinateur
 Get-WmiObject win32_service | Select-Object Name, Caption | Export-Csv .services.csv -Delimiter "¤" -Encoding "UTF8" -NoTypeInformation

# Alimente le tableau $Array à partir du fichier CSV
 $Array = Import-Csv .services.csv -Delimiter "¤"

# Cherche à remplacer des caractères dans $Array puis génère un fichier TXT pour récupérer le résultat
 $Array -replace "Adobe","ADOBE" | Out-File .services-2.txt

# Cherche à remplacer des caractères dans $Array puis génère un second fichier CSV pour récupérer le résultat
 $Array -replace "Adobe","ADOBE" | Export-Csv .services-2.csv -Delimiter "¤" -NoTypeInformation

Vous obtenez alors le contenu de services-2.txt :

@{Name=ADOBEARMservice; Caption=ADOBE Acrobat Update Service}
@{Name=ADOBEFlashPlayerUpdateSvc; Caption=ADOBE Flash Player Update Service}

Puis, le contenu de services-2.csv :

“Length”
“61”
“76”

En effet, l’opérateur -replace a converti l’objet tableau $Array en une seule chaine de caractères (string).

Notamment, le fichier résultat services-2.txt contient les chaînes de caractères.

Par ailleurs, le fichier résultat services-2.csv contient uniquement la longueur des chaînes de caractères.

En effet, la chaîne “@{Name=ADOBEARMservice; Caption=ADOBE Acrobat Update Service}” fait exactement 61 caractères. Tandis que  la chaîne “@{Name=ADOBEFlashPlayerUpdateSvc; Caption=ADOBE Flash Player Update Service}” fait exactement 76 caractères.

Suite à parcourir

Si vraiment Windows PowerShell vous rebute, sachez qu’il existe d’autres possibilités. Vous avez notamment la possibilité de faire des scripts Windows sans effort.

Office365 Addict

Ajouter un commentaire

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