Powershell pour les débutants (1ère partie)

I. Présentation du sujet

J'écris ce billet en guise d'introduction à ce que l'on pourrait comparer sommairement à une sorte de série "pour les nuls". Loin de moi l’idée d’introduire une quelconque connotation péjorative dans cet article , mais au fil de mes expériences et des informations que j’ai pu glaner sur le net et autres ouvrages sur le sujet, j’ai pensé qu’un rappel des fondamentaux serait peut être utile à votre envol dans ce monde hostile qu’est le “scripting” ou le shell sous Windows.

En fait, j’imagine volontiers le désarroi d’un technicien ou administrateur sous Windows, qui n’a jamais ou très peu sollicité la ligne de commande, à qui on va exposer des concepts d’objets, de classes, de types, de collections, d’instances (pour le vocabulaire) sans compter des syntaxes condensées et complexes (pour la grammaire) manipulant des concepts obscurs du système.

• Du batch (en gros l’héritage du DOS) – Ca ressemble/ait à ça…Non ?

FOR /F "tokens=2,3 delims= " %%A IN ('PING -a %1') DO IF "%%B"=="[%1]" SET PC=%%A

A cette “époque” on manipulait uniquement des chaines et des fichiers…

• Du WMI (via la console depuis XP, Ca ressemble/ait à ça :

WMIC useraccount where "name like '%500'" get name

Cette fois, on manipule des objets et franchement avec cette console Microsoft vous simplifiait bien la tâche. Pas convaincu ? Essayez de lancer “wbemtest” pour voir !…

• Du VBScript (ou WSH) – Ca ressemble (toujours) à ça :

Set oNetwork = CreateObject("WScript.Network")
Set oDrives = oNetwork.EnumNetworkDrives
bExist = False
For i = 1 to oDrives.Count step 2
if oDrives.Item(i)=sUNC then
WScript.Echo "le chemin " & sUNC & _
vbCrLf & "est deja associe au lecteur " & oDrives.Item(i-1)
bExist = true
end if
Next …

Une petite connaissance de ce langage simple et structuré tel que VBSscript, est un atout indéniable pour appréhender Powershell plus sereinement. A ce propos, Microsoft fournit un guide de correspondance et d’équivalence des instructions vbscript vers Powershell : en ligne ici ou la version Word “vbscript_to_powershell.doc

La première chose à admettre c’est que les tutoriels et autres formations que vous pourriez avoir sur Powershell, ne vous affranchiront pas d’une certaine maitrise (ou l’inverse ) du système Windows. Je parle ici du “noyau” et non des interfaces graphiques, outils ou autres consoles d’administration. En mode shell ou script, l’écriture du code consiste à utiliser des éléments et préciser des détails dont vous ne connaissiez peut être pas l’existence car masqués par l’interface. Autrement dit, le premier obstacle, trouver la technologie la plus adaptée à votre besoin, puis identifier les contraintes et/ou les valeurs pour que cela fonctionne.

II. Premier contact – La console (ou $Host)

En premier lieu, il vous faut ouvrir une console Powershell.exe (à l’instar de l’invite de commande “cmd.exe”) – De préférence, en tant qu’administrateur (n’oubliez pas le contrôle de compte utilisateur UAC)

consolepowershell1

Quelques trucs à savoir (pour plus de confort) :

Complétion : Contrairement à l’invite de commande traditionnelle, les commandes Powershell et leurs commutateurs (options précédés par un tiret), ainsi que les membres des instances (que l’on verra plus tard) bénéficient de la “complétion”. C’est à dire que vous pouvez utiliser les “Tabulations” (touches [Tab] ou [Maj] + [Tab]) pour compléter vos lignes de code.

Historique : La touche [F7] permet de rappeler l’historique des commandes tapées précédemment dans votre session. Utilisez les touches de curseur [Haut] ou [Bas] pour vous déplacer dans la fenêtre.

F7

Appuyez sur [Entrée] pour rappeler et exécuter la commande sélectionnée, ou sur [Flèche Droite] pour rappeler la commande sélectionnée sans l’exécuter. Utilisez ensuite les flèches [Gauche] ou [Droite] pour modifier la ligne (Mode “insertion” par défaut).

Note : Depuis Powershell v3, il est possible d’utiliser la complétion au sein d’une ligne existante sans perdre la fin de ligne.

Copier-Coller : Vous pouvez utiliser la souris dans la console ! afin de copier/coller du texte. Pour cela, vérifiez que les propriétés de la fenêtre PowerShell, sont bien configurées : Sous l’onglet “Options”, cochez la case “Édition rapide” (C’est normalement le cas par défaut).

1 – “Clic gauche maintenu” et glissement pour la sélection du texte qui doit apparaitre en surbrillance.
2 – “Clic droit” n’importe où = “copier” (La sélection passe dans le presse-papier)
3 – “Clic gauche” sur le point d’insertion désiré
4 – “Clic droit” = “Coller

Vous voilà armé au minimum pour la suite.

III. La structure des commandes

A. Les applets de commandes “cmdlet”

Dans le monde Powershell, vous remarquerez que les applets de commandes (Les fameuses “cmdlet” que nous verrons plus tard) sont composées d’une paire (ou tandem pour mieux pédaler ) de la forme “verbe”-“nom” destiné à en faciliter la mémorisation.

cmdlet

Le résultat renvoie une “collection d’instances” (Concept sur lequel je reviendrais plus tard) – Dans l’immédiat, considérez que c’est une sorte de tableau avec des entêtes de colonnes, où chaque ligne représente un élément.

Collection

B. Les variables Powershell

J’ajoute quelques mots sur la notion des “variables Powershell” qui mériteraient certainement un développement plus complet, mais je pense que pour débuter, un usage basique de ces variables volatiles peut être un allié de poids. En effet, plutôt que d’écrire une commande complexe et vous arracher les cheveux pour des histoires syntaxiques, les variables vous permettent de décomposer chaque bloc ou élément de code, afin d’avancer à votre rythme.

• Une variable Powershell est un emplacement de stockage provisoire en mémoire destiné à recueillir une valeur, un objet ou une collection d’objets.
• Les variables sont généralement nommées, et leurs noms sont toujours précédés d’un symbole “$“
• Les variables sont automatiquement “typées” lors de l’affectation de valeur (si elles ne sont pas déclarées au préalable.)
• Il existe plusieurs commandes pour manipuler les variables, mais le plus simple reste la déclaration par instanciation via le signe d’égalité soit :

$Process = Get-Process

• La variable “Process” déclarée dans cet exemple, contient la liste des processus en cours, obtenus par la commande “Get-Process” Vous pouvez afficher son contenu en mentionnant simplement en stipulant son nom “$Process” puis “Entrée

C. Les variables d’environnement

J’admets que c’est un peu hors sujet, mais j’ajouterais juste quelques mots en raison de la fréquence des questions sur ce point.

Les variables d’environnement sont accessibles de plusieurs manières :

• Via le lecteur PS (j’utilise “dir”, mais il faudrait plutôt utiliser "Get-ChildItem" ou "gci" …)

dir env:U*

• Via une variable PS

$env:USERNAME

• Via l’interpréteur traditionnel (c’est pas top, mais bon…)

cmd /c set U

Par exemple, pour afficher votre nom de login (en vert) dans une console Powershell :

write-host "Bonjour $env:USERNAME" –fore 'green'

D. Le pipeline

J’ai hésité à évoquer ce concept dans cet article d’initiation, mais son usage (et maitrise) est tellement important que je vais essayer de résumer rapidement ce concept.

Cette notion de pipeline, symbolisée par le caractère “|” ([AltGr] + [6]) permet de “chainer” plusieurs commandes entre elles.

Autrement dit, la sortie d'une commande est liée à l'entrée de la suivante. On peut considérer cet ensemble comme un tout, éventuellement destiné à une variable ou une fonction…

Un petit schéma pourrait être utile ?

pipelinebis

Dans cette illustration, quelque peu abrupte j’en conviens , l’applet de commande “Get-Service” envoie son résultat (sortie) vers l’entrée de la commande “ForEach-Object” (aliassée par “%”). Cette seconde commande traite chacun des éléments de l’objet en cours ( Symbolisé par “$_” ) afin de traiter une seule propriété, en l’occurrence “Name”).

Amusez-vous avec ce petit exemple :

gsv | ogv

Bien pratique pour retrouver le nom d’un service sur une machine.

Note : L'applet de commande "ogv" nécessite le framework .NET 3.51 ou + (non activé par défaut sur Win2008R2)

IV. Les commandes de “Découverte”

Pour bien débuter en Powershell, je vais vous parler des commandes qu’il vous faudra impérativement maîtriser au plus vite. Les voici dans le tableau de synthèse suivant :

Cmdlet Description Alias
Get-Command Informations de base sur les commandes gcm
Get-Help Aide de base (utiliser -full ou -example) help, man
Get-Member Informations sur les méthodes et propriétés des objets gm
Get-PSDrive Informations sur les “lecteurs” PowerShell gdr
Get-Module Liste les “modules” actuellement chargés gmo
Get-PSSnapin Liste les “snapins” actuellement chargés gsnp

Vous comprendrez par la suite l’importance primordiale de ces quelques commandes parmi les nombreuses autres commandes intégrées, dites “cmdlets” (129 en PSv1, 236 en PSv2, …).

Maitrisées, ces applets de commandes* devraient vous permettre de débroussailler la plupart de vos questions (légitimes) de néophytes.

Pour les plus impatients, essayez ces quelques commandes :

Pour afficher la version de Powershell :

$Host.version.major

Pour compter ces fameuses “cmdlet” ou applets de commande Powershell :

(Get-Command –CommandType cmdlet).count

Au début, concentrez votre attention sur les applets en commande, c’est-à-dire les “cmdlet”.

En effet, bien que pratiques au quotidien, les alias, les fonctions, les scripts, les modules ou même les “applications”, sont très utiles mais sont de véritables pièges pour les non-initiés.

A mon avis, les débutants ne doivent pas abuser des “alias”, car je pense qu’ils les desservent plus les qu’ils ne les aident. (ie : dir /s –> Get-ChildItem –Recurse )

Petite précision importante : Powershell n’est pas sensible à la casse (Majuscules/minuscules), ni aux espaces, ou tabulations superflues.En fait, vous verrez que Powershell est par défaut très tolérant, peut-être même trop parfois….

A. “Get-Help” – L’anti-sèche ou l’ami de tous les instants

Powershell est “auto-documenté” : N’hésitez-pas à solliciter l’aide intégrée via : GET-HELP

C’est sans doute la première commande à connaitre

Pour obtenir de l’information sur une commande, ou un sujet quelconque : “GET-HELP” ou “HELP” ou “MAN” ou encore “HELP HELP

En ajoutant éventuellement les commutateurs : “-Example” ou “-Full” ou “-Detailed” ou “-online” (Notez que les exemples fournis sont pleinement fonctionnels)

En fait, la documentation de l’aide est contenue dans les fichiers “about_*

Ces fichiers sont situés dans le dossier : "C:\Windows\System32\WindowsPowerShell\v1.0\fr-FR\" Ou bien en code Powershell

gci "$PSHOME\$PSCulture"

Note : Ne vous attardez pas sur le “v1.0″ du chemin qui reste invariable quelle que soit la version de Powershell. A l’instar de “system32″ qui contient des binaires 64bits sur un système 64 bits : Les binaires 32 bits étant dans SysWOW64 !

Dans la pratique, la commande “Help” effectue une recherche intégrale dans les fichiers “About_” (à l’instar d’un Grep Unix – “Select-String” en PowerShell) – L’aide affiche des propositions si le nom n’est pas correspond pas à un terme reconnu. Essayez par exemple les commandes suivantes en oubliant volontairement le “s” à la fin….

HELP Alia
HELP Operator

Remarque : Powershell v3 n’intègre plus qu’une aide locale partielle – Vous pouvez utiliser l’aide en ligne si la machine dispose d’un accès Internet et/ou “Update-Help” (Également disponible dans l’éditeur graphique Powershell ISE) – Il faut être administrateur pour réaliser cette action.

Note : Une version .CHM de l’aide (de base) sur PowerShell est disponible ici.

B. “Get-Command” – Une commande incontournable !

Usez et abusez de cette commande pour tout savoir sur les commandes disponibles, l’origine ou le type d’une commande particulière, les commandes propres à un module…L’alias de “get-command” est “gcm”. Une petite explication s’impose :

Si vous souhaitez connaitre la liste des commandes disponibles, essayez d’entrer les commandes suivantes :

(gcm).count
(gcm * ).count
(gcm -CommandType cmdlet).count

Le nombre renvoyé est différent parce que Powershell est en mesure d’exploiter différentes catégories de commandes :

Catégorie Description
Alias Pointeur ou nom alternatif affecté à une applet de commande, une fonction ou une application
Function Bloc d’instruction nommé ou suite de commandes existant en mémoire uniquement le temps d’une session PS ou d’un script (analysée une seule fois) – Le contenu d’une fonction peut être affiché, comme par exemple “gc function:\mkdir”
Cmdlet Commandes prédéfinies / compilées (Généralement elles offrent un accès convivial et simplifié aux classes du Framework .Net)
Application Fichier exécutable se trouvant dans le PATH , par exemple:gcm ipconfiggcm notepadgcm where

 

Je n’ai pas encore abordé ce sujet, mais sachez d'ores et déjà que Powershell dispose d’un noyau constitué de commandes (alias, function, cmdlet) de base qui peuvent être complétées à la demande par le chargement de “modules” complémentaires.

Les modules sont apparus avec la version 2 de Powershell et tendent à se généraliser (ils portent généralement l’extension *.psm1, ou *.psd1, parfois *.dll lorsqu’ils sont compilés). Les modules sont généralement spécialisés pour la gestion des fonctionnalités et rôles propres à une machine. (Par exemple, le module “ServerManager” n’est disponible que sur les versions Windows Server 2008R2 et ultérieures).

Pour connaitre les modules disponibles sur votre machine :

get-module –ListAvailable

pour charger un module dans le contexte de la session ou d’un script :

import-module NomDuModule

Indiquez le chemin complet, si celui-ci n’est pas enregistré ni proposé dans la liste précédente.

Note : Le chemin de recherche des modules est stipulé dans la variable d’environnement “$env:PSModulePath

Vous pouvez “décharger” un module de la mémoire via la commande : remove-module (Rassurez-vous, cela ne détruit pas le module).

Et enfin, pour connaitre les commandes “apportées” par un module chargé en mémoire :

gcm –module NomDuModule

Pour conclure sur cette fameuse applet de commande “Get-Command” ou “gcm”, entrez l’instruction suivante pour énumérer toutes les commandes et les classer par verbes en ordre décroissant.

gcm –CommandType cmdlet | group verb | sort count –Descending

Amusez-vous à regarder et comprendre les inégalités entre “start|stop”, “New|Remove”, “Export|Import”. C’est parfois logique, parfois un peu moins … (Vous n’avez pas déjà oubliez l’aide ?!…)

C. “Get-Member” – L’explorateur d’objets (la clé du succès)

Bon maintenant, il va falloir passer aux choses sérieuses. Avant de parler de cette commande “Get-Member”, je me dois de vous présenter le plus simplement possible, le concept complexe des objets :

Un petit peu de vocabulaire s’impose:

Terme Explication
Classe C'est un peu comme le “Plan de construction” – aussi appelé “Type” de données
Instance “Objet existant (élément) – construit selon une classe”
Collection Désigne un “Ensemble d’instances” (généralement d’un même type ou associé)”
Variable C'est un contenu nommé, ou le stockage d’une collection dans une zone mémoire
Membres Ce sont les “Caractéristiques” (Propriétés) et les “Capacités” (Méthodes) d’un objet.

Bien, regardons cette notion de membre d’un peu plus près via cette petite illustration :

Objet

Une classe de type “Boite”, va nous permettre de construire une ou plusieurs boites similaires (instance). Nous pourrons ensuite consulter (voir modifier) les caractéristiques (Propriétés) telles que la taille, la couleur, etc. De la même manière, nous pouvons agir sur une boite et ses capacités (Méthodes) telles que l’ouvrir, la fermer, etc…

Note : Sur le plan syntaxique, les membres (propriétés ou méthodes) sont liés à l'objet (l’instance) par un point “Instance.Membre” et par un double "::" pour les membres statiques du Framework .NET “[Type.NET]::Membre

Un membre statique est une notion particulière que l'on pourrait définir comme membre ayant la particularité d'être sollicité directement via la classe sans nécessiter d'instance. Comme par exemple :

[datetime]::now

Bien, maintenant que le décor est planté, essayons de revenir à un exemple plus concret et pratique. Sous Powershell, tout est objet. Une simple chaine de caractère est donc un objet de type [string] doté de propriétés et de méthodes.

Vous imaginez peut être quelques possibilités telle que la longueur de la chaine (“.length”), mais probablement moins l’étendue de toutes ses possibilités. En premier lieu, interrogez le type du contenu “Chaine” via l’instruction suivante :

("Chaine").gettype()

Normalement, vous obtenez “String” dans le résultat. Maintenant, regardez d’un peu plus près les possibilités en tapant la commande suivante :

"Chaine" | get-member

ou plus simplement

“Chaine” | gm

Parmi toutes les informations renvoyées, vous devriez apercevoir le type “TypeName : System.String”, ainsi qu’une liste conséquente de méthodes et de propriétés. Essayez de les utiliser comme dans les exemples suivants :

(“Chaine”).length –> 6
(“Chaine”).ToUpper() –> CHAINE
(“Chaine”).Replace(“C”,”Déc”) –> Déchaine

Note : Pour invoquer une méthode (sans paramètres), vous devrez ajouter les parenthèses à la fin “.Method()”.

Ultime précision, et bien qu'il s'agisse d'un concept avancé qui ne devrait pas apparaitre ici, sachez qu'il est possible d'obtenir la liste des membres statiques d'un type .NET via la commande suivante :

[string] | get-member -static

Voilà, je pense que j’ai fait le tour des fondamentaux. J’ajouterais peut être un complément dans les mois à venir. Maintenant, il ne vous reste plus qu’à digérer tout cela et surtout à pratiquer sans modération.

Pour lire la deuxième partie de ce cours : PowerShell pour les débutants (Partie 2)

La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Bon courage.

Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Partager sur Google+ Envoyer par mail

Christophe Mandin

Consultant/Formateur indépendant en quête de solutions et de moyens alliant efficacement la théorie et la pratique. Fort d’une expérience de plusieurs dizaines années dans l’informatique, j’ai pu apprécier de nombreuses problématiques, développer des qualités rédactionnelles et un esprit de synthèse, tout en me forgeant de solides fondamentaux théoriques, indispensables à toute analyse et mise en œuvre fonctionnelle. Malgré toutes ces années, je ne me lasse pas du plaisir de transmettre mes connaissances en misant sur 3 critères que sont les fondamentaux, la simplicité et le pragmatisme. Bien à vous. Retrouvez-moi sur LinkedIn : Christophe Mandin

Nombre de posts de cet auteur : 32.Voir tous les posts

28 thoughts on “Powershell pour les débutants (1ère partie)

  • Bonjour,
    en ‘D. Le pipeline’ la représentation graphique du pipeline doit être horizontale, car si on transpose celle existante à cet exemple :
    Cmdlet1 | Cmdlet2 | Cmdlet3
    cela n’a plus de sens. Cette représentation laisse supposer qu’il y a plusieurs tuyaux.

    Le schéma indique Fonction A et Fonction B, par contre le texte parle de cmdlet, il manque soit un concept regroupant les deux ( fonction et cmdlet) soit une notion en trop.

    Enfin la notion de ‘robinet’ devrait être présente en entrée et en sortie de chaque cmdlet. Pas de robinet, pas d’eau !

    Ceci dit, la représentation graphique d’un pipeline n’est pas aisé. Avec qq corrections celui-ci peut devenir une référence.

    Cdt.
    Manuel

    Répondre
  • Pour
     »
    Sur le plan syntaxique, les membres (propriétés ou méthodes) sont liés à leur parent (l’instance) par un point “Instance.Membre” et par un double “::” pour les objets du Framework .NET “[Type.NET]::Membre”

     »
    L’usage de la notion de parent est ici erroné, une propriété ou méthode est une caractéristique d’une classe et appartient en propre à une instance d’objet, ce n’est pas une filiation. et la seconde syntaxe référence une méthode de classe (méthode statique donc).
    Elle laisse entendre qu’il existe des objets dotNet et d’autres objets ( lesquels ? )

    Répondre
  • Bonjour,
    Cette 1ere remarque est avisée et je reconnais que le terme fonction porté sur mon schéma est ambigüe. (cmdlet) aurait été plus approprié. En revanche, concernant les « tuyaux », j’avais volontairement représenté les canaux E/S (0 et 1) dits normaux sur la même ligne, afin de différentier les autres flux d’erreur, avertissement, verbose, debug (qui font aussi partie du pipeline) – mais je pensais en parler ds un autre article. Concernant l’eau qui rentre ou sort du robinet, c’est aussi le dilemme de la poule et de l’oeuf) mais c’est une introduction, donc perfectible 😉
    Pour la 2eme remarque, j’aurais probablement du dire lié à « l’objet » ? , mais je parlais d’une notion syntaxique. Désolé d’avoir choqué certains développeurs par cette affirmation erronée 🙂
    En tout cas merci pour ces précisions, constructives
    Errare humanum est, perseverare diabolicum
    Cdt
    Christophe

    Répondre
  • Bonjour,
    >>afin de différentier les autres flux d’erreur, avertissement, verbose, debug (qui font aussi partie du pipeline)
    Le principe du pipeline est émettre/recevoir, les données des autres flux n’y transitent pas. Un cmdlet ne reçoit pas de donnée issue du flux debug.
    Si le pipeline et les autres flux cités sont liés, c’est plus de ‘la mécanique d’implémentation’.
    A mon avis ta démarche de les placer dans ton schéma t’éloigne du principe que tu veux expliquer.

    Et après réflexions, la présence de la vanne laisse supposer que c’est le pipeline qui décide de filtrer les objets (ouvrir ou fermer) alors que cette décision appartient au cmdlet émetteur.
    Le symbole entre les deux cmdlets porte effectivement la notion de raccord/connexion, mais celui-ci est juste un tuyau, voir un passe-plat.

    >>Désolé d’avoir choqué certains développeurs par cette affirmation erronée 🙂
    Cela ne me choque pas, c’est un domaine qui nécessite de la précision, même et surtout pour un public d’admin.
    La difficulté dans cet exercice est savoir où l’on s’arrête.

    Enfin je trouve ta correction sur les notions de membre ambiguë :
    >>les membres (propriétés ou méthodes) sont liés au nom de l’objet (l’instance)
    Ce simple exemple la met à mal :
    $A=1|select nom
    $B=1|select nom
    $a.Nom=’un’
    $b.Nom=’un’
    $a;$b

    « sont liés à l’objet  » ?

    Répondre
  • Un autre point :
    >>Les variables sont automatiquement “typées” lors de l’affectation de valeur (si elles ne sont pas déclarées au préalable.)
    Non.

    Mais chaque ‘valeur’ affectée à une variable a un type :
    (10).GetType().FullName
    #System.Int32

    ‘Chaine’.GetType().FullName
    #System.String

    Et justement en Powershell une variable n’est pas typée :
    $A=’Chaine’
    $A.GetType().FullName
    #System.String

    $A=10
    $A.GetType().FullName
    #System.Int32

    La variable $A peut contenir n’importe quel type de valeur.

    Une variable est “typées” explicitement, c’est à dire dès qu’on précise un type :
    [Int] $A=10
    $A.GetType().FullName
    #System.Int32

    $A=’Chaine’
    #Impossible de convertir la valeur «Chaine» en type «System.Int32».

    Ainsi on contraint la variable $A à ne recevoir que des valeurs d’un certain type.

    >>si elles ne sont pas déclarées au préalable.
    $A=$null

    $A=’Chaine’
    $A.GetType().FullName
    #System.String

    $A=10
    $A.GetType().FullName
    #System.Int32

    La déclaration préalable d’une variable ne change rien à son typage. Même en mode Strict (Set-StrictMode).

    Donc, sous Powershell le typage, c’est comme les antibiotiques c’est pas automatique.

    >> via le signe d’égalité soit
    Non, = est le symbole d’affectation, -EQ est l’opérateur d’égalité.
    😉

    Répondre
  • Waouh, ça c’est ce que j’appelle de la précision chirurgicale 🙂 … Mais si ça peut contribuer à une meilleure compréhension des lecteurs…

    Dans cet article d’initiation, il est vrai que je fais certains raccourcis, notamment sur la gestion des flux et redirections (prévue dans un autre billet) pour introduire la notion de gestion des erreurs et aller légèrement plus loin que l’entrée et la sortie cmdlet1 |cmdlet2 | cmdlet3 …. Mais il est vrai que dans toute explication, il faut s’adapter au niveau du public, d’où le titre « débutants »…

    Concernant ton exemple $A=1|select nom, je ne suis pas sur que l’usage de select nom pour dériver l’objet $A (qui serait implicitement instancié en type int32 ) en un « PSCustomObject » soit très pédagogique mais bon, pourquoi pas. Cela étant, lorsque tu considères les instances $A ou $B, ( de type Selected.System.Int32 , on est d’accord ?), et que tu affectes la valeur chaine ‘un’ au nouveau membre ‘nom’, et tu utilises bien le point « $A.nom= » pour affecter ou afficher une valeur. Sur le plan syntaxique, la propriété « nom » est donc bien liée au nom de l’objet « $A », non ?
    Pour le 2eme point, je suis d’accord pour la précision entre la valeur typée et la variable (l’objet conteneur) mais là encore, c’est une 1ere couche, et trop de détail risque de tuer le message…. (d’où l’intérêt de des commentaires, en seconde lecture :-)…)

    Enfin, dans la phrase « par instanciation via le signe d’égalité », je voulais exprimer le fait de déclarer la variable en lui affectant une valeur par la même occasion. Il est évident que qu’il ne faut pas confondre les opérateurs d’affectation avec celui d’égalité, mais j’en parle justement dans un autre volet à venir ;-)…

    En tous cas, merci pour ces précisions, je suis persuadé que les lecteurs apprécieront 🙂
    Cdt

    Répondre
  • >>Mais il est vrai que dans toute explication, il faut s’adapter au niveau du public, d’où le titre « débutants »…
    Oui, mais je pense qu’à vouloir trop simplifier, on rend le discours simpliste.
    J’ai donné quelques formations sur Powershel à un public de débutants, je peux t’assurer qu’ils comprennent parfaitement ces nuances si on se donne la peine et le temps de les expliquer.
    Un atelier interactif d’une heure, une heure et demi sur la notion d’objet suffit.
    Je ne suis pas là pour les rassurer, mais leur donner de solides bases afin qu’ils puissent progresser seul par la suite. Ce n’était certes pas facile pour eux…
    Ensuite chacun sa démarche, je te l’accorde.

    >>Concernant ton exemple $A=1|select nom, je ne suis pas sur que l’usage … soit très pédagogique
    Non, car ce n’était pas son objectif. C’est au rédacteur que je m’adressais.

    >>on est d’accord ?
    Oui. Pour faire simple 🙂

    Ce que je voulais te dire, c’est que si tu remplaces.
    >>les membres (propriétés ou méthodes) sont liés au nom de l’objet (l’instance)

    par

    >>les membres (propriétés ou méthodes) sont liés à l’objet (l’instance)
    Cela ‘passe’ bien mieux à mon avis.

    Je ne sais pas ce qu’est « un nom d’objet », tu parles de son identité, c’est à dire une notion de clé, d’unicité ?
    Je ne pense pas.

    Ta formulation te semble évidente à comprendre, mais à la lire, comme je ne connais pas l’objet, je peux me poser cette question :
    « Si je change le nom d’un objet, la liaison existe-t-elle toujours ? »

    >>trop de détail risque de tuer le message….
    Non, tu ne le tues pas tu l’enrichis.
    Risquer ou pas, c’est un choix.

    >>je voulais exprimer
    J’ai bien compris, c’était juste une remarque.
    On peut être débutant et prêter attention à ce qu’on lit.

    Répondre
  • A corriger:
    get-module –ListAvailaible
    ->
    get-module -ListAvailable

    Répondre
  • Bonjour,

    Très humblement (parce que je suis venu ici en noob parfait et pour apprendre), les premiers exemples ne fonctionnent pas chez moi…

    $(env:USERNAME)
    à corriger en
    $env:USERNAME

    write-host « Bonjour $(env:USERNAME) » -fore ‘green’
    à corriger en
    write-host « Bonjour $env:USERNAME » -fore ‘green’

    gci $PSHOME+ »\ »+$PSCulture
    à corriger en
    gci ($PSHOME+ »\ »+$PSCulture)

    C’est peut-être lié à une version de PowerShell mais c’est un peu perturbant.

    Cordialement,

    Répondre
    • Bonjour WD, et tout d’abord merci pour cette remarque très pertinente (j’ai honte) J’avais effectivement relevé ces erreurs, mais j’avoue avoir oublié de les corriger dans cet article.

      En fait, la syntaxe pour une variable dynamiquement calculée est $(Expression) et pour env:USERNAME il s’agit d’un lecteur PS ( dir Env:\USERNAME) . La correction proposée est correcte.

      Pour la seconde, La correction proposée est correcte mais celle-ci également
      gci « $PSHOME\$PSCulture »

      Cette syntaxe est propre et valide dans toutes les versions de Powershell. La v3 apporte quelques « facilités » d’écriture mais pas pour ce cas de figure (mea culpa).
      – env: c’est donc le lecteur des variables d’environnement et $env:variable c’est la variable elle-même
      – () Les parenthèses servent à encadrer une expression. Par exemple, $username = $( $env:USERNAME.ToLower() ) est une écriture bizarre/inutile mais valide, car entre les parenthèses la variable est d’abord évaluée.
      – «  » les guillemets permettent d’évaluer les variables au sein d’une chaîne et évitent ainsi de procéder à des concaténations. Dans le cas contraire, il faut « échapper » le signe dollar via le backtick [AltGr] + [7] ou mettre la chaîne entre simples quottes.

      Je viens de corriger / désolé pour ce désagrément cher noob 😀

      Répondre
  • Ecrire une fonction get-bigFile($val) qui cherche tous les fichiers qui ont dépassés la taille $val et qui écrit leurs nom dans un fichier journal c:\Mes_script\Bigfile.log

    Répondre
    • Bonjour dahraoui,
      Il y a plein de solutions, y compris « one-line », mais voici un exemple de fonction (perfectible certes, mais c’est un exemple) :

      function Get-FileBySize {
      param ( $path = $Pwd,
      $size = 100MB,
      $extension = "*.*")

      $ErrorActionPreference = 'SilentlyContinue'
      $largeSizefiles = get-ChildItem -path $path -recurse -include $Extension |
      Where-Object { $_.GetType().Name -eq "FileInfo" } |
      where-Object {$_.Length -ge $size} |
      sort-Object -property length -Descending |
      Select-Object @{Name="Fichier";Expression={$_.Name}}, @{Name="Taille";Expression={$_.Length}},@{Name="Chemin";Expression={$_.directory}}

      return $largeSizefiles
      }
      Get-FileBySize -path D:\ -size 1MB -extension *.msi

      (Enlever « function { … } » si besoin uniquement d’un script.)
      Pour ne garder que le nom et envoyer le résultat dans un fichier, il suffit d’ajouter en fin de ligne « … | select Fichier | out-file c:\Mes_script\Bigfile.log »
      Bon courage

      Répondre
  • Il y a des cours sur MVA de PowerShell qui sont excellents également…
    Ce site est un excellent complément…

    Répondre
  • Merci Anthony, je prends cela comme un compliment. Surtout qu’en tant que formateur/consultant indépendant je ne peux manifestement pas mettre le meilleur sous peine de me tirer une balle dans le pied 🙂

    Répondre
  • Bonjour,
    Tour d’abord un grand merci pour vos efforts énorme pour nous fournir des cours aussi détaillés et aussi clairs, ça me permet de comprendre simplement et rapidement le powershell,
    Je voulais savoir aussi quelle était la différence entre le powershell 2,3,4 et si on apprend la version 2 est il possible d’utilisé les commandes sur la version 4 par exemple ,

    Merci d’avance pour vos réponse,

    Répondre
    • Bonjour,
      Comparer les versions de Powershell revient à comparer les versions de Windows :-D, c’est impossible en quelques mots…
      A mon avis, le Powershell v2 (intégré à Windows 7/2008r2) est la 1ere version « aboutie » avec laquelle on couvre un grand nombre de sujets (et les bases du scripting) puis on se heurte à des cas plus complexes, (genre accès aux classes .NET 🙁 ) souvent traités par de nouveaux paramètres et cmdlets dans les versions suivantes. Il suffit alors de mettre à jour (selon l’OS) le framework DotNET puis le WMF pour passer à la vitesse supérieure mais les principes restent les mêmes. (La plupart des syntaxes de commandes PSv2 fonctionnent sur les versions ultérieures, mais pas l’inverse). Pour améliorer la compatibilité, on peut activer le « moteur Powershell v2 » et aussi stipuler la version souhaitée lors de l’invocation de l’interpréteur (cf Powershell.exe /?). Dans le doute, on peut aussi ajouter la directive « #Requires -Version » dans un script afin d’imposer une version et arreter le script le cas échéant ou ajouter du code pour évaluer la version Powershell comme par exemple ici .
      Write "Powershell version $($PSVersionTable.PSVersion.Major)"
      Bonne continuation

      Répondre
    • ?? Le batch ou le Bash ??
      Sous Windows Powershell est le remplaçant du batch par excellence (et la v2 était même supportée sur Windows XP) – De nos jours, il est de plus en plus rare d’exploiter des batches même si Microsoft assure encore une certaine compatibilité des .bat ou .cmd. Ce langage historique (MsDOS) ne répond plus aux besoins et s’accommode très mal des technos associées aux systèmes actuels.
      On ne trouve plus grand monde qui enseigne cette « langue morte » qu’est le batch, mais, on trouve encore beaucoup de sites (en anglais) sur le sujet : tutorialspoint.com ou robvanderwoude.com
      Bonne continuation

      Répondre
  • Merci pour cet article. Je débute et ça m’aide beaucoup.

    Répondre
  • Bonjour,

    Merci pour cet article.
    Comme Pustoc’h Fabrice, je débute en PowerShell et suis bien content de trouver votre cours.
    Je cours voir la « 2ièm partie ». 🙂

    Bien à vous,

    Répondre
  • Salut,
    Je cherche à récupéré des info sur des PC avec un envoi par mail. Mais je ne sais pas comment inclure plusieurs demande pour une même variable. Si vous avez une solution, merci d’avance de me la communiquer.

    Voici mon script :
    $InfoPc =
    (
    Write-Host "Version de PowerShell : Get-Host | findstr Version"
    Write-Host "Nom du PC :"$Env:ComputerName
    Write-Host "iPV4 local : "
    ipconfig | findstr /i "ipv4"
    )
    Send-MailMessage -From "[email protected]" -To "[email protected]" -Subject "INFO PC" -SmtpServer "smtp.orange.fr" -Body $InfoPc -Credential [email protected]

    Répondre
    • Bonjour Olivier,

      Aie, du « findstr » et « ipconfig », c’est pas très « powershell » mais bon pourquoi pas 🙂 Ensuite, le write-host c’est juste pour un affichage à la console (à éviter, et préférer le « write », ou « write-output ») et ce n’est pas la technique pour peupler un contenu de variable.
      La version de Powershell s’obtient plutôt via « $PSVersionTable.PSVersion.ToString() ». Pour le reste, même si perso j’aurais pris d’autres méthodes 😉 , il suffit de concaténer les différents résultats en ajoutant un [AltGr]+[7]+[`n] pour les retours lignes et en jouant avec les « $ » ,guillemets et autres backticks… Ce qui pourrait donner un code du genre :

      $InfoPC = (
      "Version de PowerShell : $($PSVersionTable.PSVersion.ToString()) `n" +
      "Nom du PC : $Env:ComputerName `n" +
      "$(ipconfig | findstr /i `"ipv4`") `n"
      )

      Le reste du code devrait fonctionner
      Bonne continuation

      Répondre
      • Salut.
        Un grand merci pour m’avoir aidé. C’est super éfficace. Je débute en autodidacte sur PowerShell. Donc mon code n’est pas formidable et je vous invite à ne pas hésité à réecrire ce code comme vous le sentez. Cela me permetra d’apprendre. Mais sinon, une question : vers quoi devrais-je me dirigé en terme de formation ou livre pour m’amélioré en PowerShell. Merci d’avance.

        Répondre
        • Bonjour,
          La pratique au quotidien, même perfectible et hasardeuse est probablement la meilleure façon d’apprendre. Les livres, les cours ou les tutos, ne sont que des « marche-pieds », pour vous mettre le pied à l’étrier, car chacun à ces propres besoin ou objectifs.
          N’oubliez pas l’aide intégrée, à défaut de réponse elle donne souvent des pistes de bases. Pour les besoins un peu « touchy », je conseille souvent le site « stackoverflow.com » animé par une communauté très riche (là encore, à défaut de solution, on y trouve souvent une inspiration)
          Et plutôt que fournir un script « corrigé », voici quelques pistes (PS v5) 🙂
          help ipconfig (renvoie « Get-NetIPConfiguration »)
          help findstr (renvoie « Select-String »)
          Je pense que le reste est dans mes 4 tutos et surtout dans la pratique 😀

          Bon courage
          La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. [Albert Einstein]

          Répondre
  • Mes plus reconnaissantes salutations, Monsieur Mandin !
    Béotien désireux de m’initier à PowerShell, je considère votre cours comme du pain béni.
    Je le lis et le relis avec une intimité croissante à chaque fois.
    Je m’entraîne encore et encore à partir des exemples que vous proposez.
    Bref, en offrant ainsi le fruit de votre expérience, soyez certain que vous avez enrichi intellectuellement plus d’une comme plus d’un.
    C’est au nom de cette majorité silencieuse que je voudrais ici m’exprimer en vous remerciant du fond du cœur.
    Un savoir qui ne se transmet pas est un savoir qui meurt.
    Or vous savez manifestement maintenir l’envie en vie, votre envie de partager le savoir, notre envie de le recevoir.
    Ce qu’on lit nous lie, tout simplement.
    Altius, citius, fortius,

    Jérôme

    Répondre

Répondre à Anthony LEDUC Annuler la réponse

Votre adresse e-mail 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.