Table des matières

PowerShell

Introduction

Version

$PSVersionTable

Exécuter des scripts

Par défaut, l'exécution de scripts PowerShell ne sont pas permis1). Pour se faire, il faut exécuter PowerShell en Administrateur et exécuter cette commande:

Set-ExecutionPolicy RemoteSigned

Variables

On peut spécifier une variable tout simplement en lui assignant une valeur:

$var="Ceci est une chaîne."
$nombre = 5
$fichiers = dir C:\

Variables d'environnement

Les variables d'environnement on comme leur propre namespace $env:. Par exemple, pour le PATH, il faut le référencer par $env:PATH.

Write-Host $env:PATH
Write-Host "App Version: $($env:APP_VERSION)"

Pour la liste des variables d'environnement, on peut faire Get-ChildItem Env:.

Aide

Pour de l'aide sur une commande, on peut faire Get-Help [command] :

PM> Get-Help Get-Service

Pour ouvrir l'aide dans un navigateur par défaut, on peut ajouter -Online:

PM> Get-Help Get-Service

Chercher des commandes avec Get-Command :

PM> Get-Command Stop-Azure* -Module Azure

Chaînes

Dans PowerShell, les chaînes peuvent être délimitées par des guillemets simples (', single-quote) ou doubles (", double-quote). Donc, ces deux valeurs sont équivalentes:

Utiliser les deux types de délimiteurs permet d'inclure des caractères de l'autre type, par exemple: J'utilise le PowerShell. ou 'Il a dit "Hello World" dans son script PowerShell.'.

Si un guillemet simple est nécessaire dans une chaîne délimitée par des guillemets simples, on peut les doubler, par exemple : 'J''utilise PowerShell.'.

Here-string

Pour initialiser une chaîne sur plusieurs lignes, on peut utilser le principe de here-string avec des '@ ou "@:

$var='@
J'utilise les here-strings
dans PowerShell
'@

$var2="@
un autre exemple de here-string.
"@

# En bas, ça ne fonctionnera pas
$var3='@
on ne peut pas laisser d'espace devant le dernier delimiteur
    '@

Substitution de chaîne

La différence principale entre utiliser le délimiteur single-quote ou double-quote, c'est la substitution dans les chaînes. Dans les chaînes délimitées par des double-quotes, l'utilisation d'une variable dans la chaîne sera remplacée par sa valeur. Si la variable $nom contient Stéphane, la valeur de la chaîne "Mon nom est $nom." sera Mon nom est Stéphane.

Si on veut utiliser la valeur d'une propriété sur une instance d'objet, on peut utiliser $($var.Property) dans la chaîne:

Write-Output "Found $($scriptFiles.Count) files."

Caractère d'échappement

Normalement dans les langages de programmation, le caractère d'échappement est la barre oblique inversée (\, backslash), mais dans PowerShell on peut s'en servir comme séparateur de répertoires dans les chemins (C:\Program Files\Application), donc on utilise plutôt le backtick : `.

"La valeur de la variable `$var est $var"

Par exemple, pour une commande :

Copy-Item -Recurse C:\Projets\Application` 101\Site` Web\* -ToSession $session -Destination C:\inetpub\Application` 101

RegEx

$anyGO = [regex]::Match($line, 'GO')

Exemple

$content = Get-Content ..\Projet\Properties\AssemblyInfo.cs
$content = Convert-String -InputObject $content

#echo $content

$found = $content -match 'Version'

echo $found

if ($found) {
    $spid = $matches[0]
}

$found = $content -match 'Version\(".*"\)'

#Write-Host $matches

echo $found

$sln | Select-String 'Version\(".*"\)' -AllMatches

#  $x = 'Version("{0}")' -f "1.2.3.4"
# echo $x

Listes

Scripts

Paramètres

Pour un script appelé de cette façon : script.ps1 param1 param2, les valeurs seront dans args qui est un tableau:

$param1=args[0]
$param2=args[1]

Pour les paramètres nommés, par exemple dans script.ps1 -nom Mike, c'est à l'aide de la fonction param():

param($nom)
return "Le nom est $nom."

Logique

Conditions

If

L'instruction logique la plus simple est le if.

param($number)
if ($number -eq 5) {
    Write-Output "Vous avez deviné le chiffre magique."
}
else {
    Write-Output "Vous n'avez pas trouvé."
}

Switch

Au lieu du if, on peut utiliser le switch s'il y a beaucoup de résultats possibles.

switch (expression)
{
    {test} {code block}
    value {code block}
    default {code block}
}
$today=get-date

switch ($today.day)
{
  1 { Write-Host "Jour de paie!" }
  1 { Write-Host "Arroser les plantes." }
  5 { Write-Host "Rappel pour payer les factures." }
  10 { Write-Host "Sortir les ordures." }
  default { Write-Host "Rien à se rappeler aujourd'hui." }
}

Opérateurs

Les opérateurs suivant ne sont pas sensibles à la casse par défaut.

Opérateur Description
-eq Equal
-ne Not equal
-ge Greater than or equal
-gt Greater than
-lt Less than
-le Less than or equal
-like Wildcard comparison
-notlike Wildcard comparison
-match Regular expression comparison
-notmatch Regular expression comparison
-replace Replace operator
-contains Containment operator
-notcontains Containment operator
-shl Shift bits left (PowerShell 3.0)
-shr Shift bits right – preserves sign for signed values.(PowerShell 3.0)
-in Like -contains, but with the operands reversed.(PowerShell 3.0)
-notin Like -notcontains, but with the operands reversed.(PowerShell 3.0)

Pour avoir une comparaison sensible à la casse, il faut préfixer d'un c devant l'opérateur, par exemple -ceq au lieu de -eq.

Source : Comparison Operators

Système de Fichiers

Répertoires

Supprimer un répertoire étant certain qu'il faut le supprimer:

Remove-Item -Recurse -Force repertoire

On peut ajouter -ErrorAction SilentlyContinue si on ne veut pas avoir d'erreur si le fichier/répertoire n'existe pas.

Variables utiles

Web

Exemple pour télécharger des fichiers:

Invoke-WebRequest -Uri "https://awscli.amazonaws.com/AWSCLIV2.msi" -OutFile "AWSCLIV2.msi"

Si une erreur comme ceci survient:

Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.

Exécuter cette commande:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Boucles

Gestion d'erreurs

Trap statement

L'utilisation du trap statement ($_) est rarement utilisé sauf quand la verison de PowerShell disponible n'est que 1.0. Comme c'est rarement utilisé, on documentera pas beaucoup cet aspect de PowerShell, seulement en montrant un exemple.

function test-trap {
    trap {
        "Une erreur est survenue: $_"
    }
    
    $var = 1/0
    Write-Host "Fin de la fonction"
}

On peut utiliser continue ou break dans le bloc du trap sous la ligne "Une erreur est survenue: $_". La mention continue aura pour effet de continuer l'exécution du script, sinon break arrêtera son exécution.

Try/Catch

Dans PowerShell 2.0 ou plus, on peut utiliser les try, catch et finally dans les scripts.

try {
    $var=1/0
    "La fonction s'est terminée correctement"
}
catch [System.Management.Automation.CommandNotFoundException] {
    "Impossible de trouver la commande $_"
}
catch {
    "Quelque chose est arrivé : $_"
}
finally {
    "Ceci s'exécute toujours."
}

ErrorAction

Code de sortie

commande_erreur.exe
exit $LASTEXITCODE

Commandes

Système de fichiers

Param($path)
new-item -ItemType Directory -Name $path
cd $path

Commandes utiles

Exécution

Pour l'arrêt momentané de l'exécution:

Start-Sleep -Seconds 600

Exemples

iwr https://domain.org/script.ps1 -UseBasicParsing | iex

SMO

La déclaration:

[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null

Une instance de l'objet qui représente le serveur SQL:

$srv = New-Object 'Microsoft.SqlServer.Management.SMO.Server' $sqlServerInstance

Si on veut l'authentification en mode SQL:

$srv.ConnectionContext.LoginSecure=$false;
$srv.ConnectionContext.set_Login($env:DB_USERNAME);
$srv.ConnectionContext.set_Password($env:DB_PASSWORD)

La liste des bases de données sur $srv :

$srv.Databases | Select name 

Développement de Cmdlet

Créer un projet .NET Standard (net46) de type Class Library et installer le package nuget Microsoft.PowerShell.5.ReferenceAssemblies.

En développement, un DLL est créé comme tout autre projet .NET. On peut le charger dans un ISE pour l'essayer.

PM> Import-Module –Name 'C:\myRandomDirectory\myModule.dll'

Sources

1)
exception de Windows Server 2012 R2 qui le permet localement