
I. Présentation
Avec Windows PowerShell, vous avez découvert comment créer des interfaces graphiques avec PowerShell WPF et Windows Forms grâce à nos articles précédents (que nous vous recommandons de lire pour une meilleure compréhension de cet article).
Aujourd’hui, nous allons apprendre à créer des applications WPF avec PowerShell 7.5 (appelé aussi PowerShell Core) et les versions supérieures. Avec la récente mise à jour de PowerShell en version 7.5, les composants .NET en version 9 ont apporté beaucoup de changement aux applications WPF… C’est ce que nous allons découvrir dans ce tutoriel.
II. Les prérequis
PowerShell 7.5 est la version multiplateforme de Windows PowerShell. Son installation est possible sur l’ensemble des plateformes MacOs, Linux et Windows, bien sûr. En complément, vous devez aussi installer .NET Desktop Runtime en version 9 sur votre machine.
A. Installer PowerShell Core avec WinGet
Je pense que vous connaissez le gestionnaire paquets de Windows ? Sinon, je vous invite à le découvrir dans cet article. Il permet d’installer des applications en ligne de commande.
Pour rechercher PowerShell, utiliser la ligne de commande suivante :
PS > winget search Microsoft.PowerShell
Nous remarquons que nous avons la version 7.5 et même la version en preview 7.6.0.4 de PowerShell Core disponibles dans les dépôts.
Pour installer PowerShell, utiliser la ligne de commande suivante :
PS > winget install Microsoft.PowerShell
B. Installer .NET Desktop Runtime 9 avec WinGet
Maintenant, passons à l’installation du .NET Desktop Runtime en version 9, toujours avec WinGet.
PS > winget install Microsoft.DotNet.DesktopRuntime.9
Nous disposons désormais de tous les prérequis pour entrer dans le vif du sujet : créer des applications WPF avec un thème moderne, sans recourir à des bibliothèques tierces comme MahApps ou WPF UI, en utilisant cette fois le thème Fluent.
Source : Learn.microsoft.com
Pour découvrir les contrôles ainsi que les styles utilisés dans Fluent, Microsoft a créé une application Galerie WPF disponible dans le Store de Windows.
III. L’application WPF avec PowerShell 7.5
A. La partie XAML
Nous allons utiliser à nouveau la même application que nous avions créée précédemment avec Mahapps ou MaterialDesign, mais cette fois en PowerShell 7.5 avec le thème Fluent de Windows 11.
Quels changements pour prendre en compte le nouveau thème Fluent ? Pas grand-chose en fait, regardons de plus près le XAML.
L’ajout de la propriété ThemeMode au contrôle Window, il accepte trois paramètres :
Light : thème blanc
Dark : thème noir
System : récupère le thème actif du système.
L’ajout de la propriété Style au contrôle Button avec la valeur DynamicResource AccentButtonStyle, ce qui va lui permettre de récupérer la couleur de la valeur de l’accent au sein du système d’exploitation.
Pour une documentation plus complète sur les styles ainsi que les accents, je vous recommande le site Learn Microsoft pour avoir l’ensemble des paramètres.
B. La partie PowerShell
Et le code PowerShell ! Pour faire simple, j’ai décidé d’utiliser un seul fichier. J’ai décidé d’ajouter une vérification de la version de PowerShell. Ainsi, si la version n’est pas du PowerShell 7.5, alors le script s’arrête avec un message d’erreur.
Cette vérification est effectuée via le code suivant :
if ($PSVersionTable.PSVersion.Major -lt 7 -or ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -lt 5)) {
Write-Host “This script requires PowerShell 7.5 or later. Please upgrade your PowerShell version.” -ForegroundColor Red
exit
}
Pour ce qui est du corps du script PowerShell, voici son contenu en intégralité :
# Check if the script is running on PowerShell 7 or later
if ($PSVersionTable.PSVersion.Major -lt 7 -or ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -lt 5)) {
Write-Host “This script requires PowerShell 7.5 or later. Please upgrade your PowerShell version.” -ForegroundColor Red
exit
}
# Define the xaml code for the window
[xml]$xaml = @’
‘@
# Charger l’assembly WPF
Add-Type -AssemblyName PresentationFramework
# Charger la fenêtre et les éléments nommés en tant que variables dans une table de hachage
$UI = [System.Collections.Hashtable]::Synchronized(@{})
$UI.Window = [System.Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $xaml))
$xaml.SelectNodes(“//*[@*[contains(translate(name(.),’n’,’N’),’Name’)]]”) |
ForEach-Object -Process {
$UI.$($_.Name) = $UI.Window.FindName($_.Name)
}
# Amener la fenêtre au premier plan
$UI.Window.Add_Loaded({
$This.Activate()
})
function Get-ADUserLastLogon {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)][ValidateScript({ Get-ADUser $_ })]$Identity = $null
)
# Récupérer la liste de tous les DC du domaine AD
$DCList = Get-ADDomainController -Filter * | Sort-Object Name | Select-Object Name
# Initialiser le LastLogon sur $null comme point de départ
$TargetUserLastLogon = $null
# Date par défaut
$DefaultDate = [Datetime]’01/01/1601 01:00:00′
Foreach ($DC in $DCList) {
$DCName = $DC.Name
Try {
# Récupérer la valeur de l’attribut lastLogon à partir d’un DC (chaque DC tour à tour)
$LastLogonDC = Get-ADUser -Identity $Identity -Properties lastLogon -Server $DCName
# Convertir la valeur au format date/heure
$LastLogon = [Datetime]::FromFileTime($LastLogonDC.lastLogon)
# Si la valeur obtenue est plus récente que celle contenue dans $TargetUserLastLogon
# la variable est actualisée : ceci assure d’avoir le lastLogon le plus récent à la fin du traitement
If ($LastLogon -gt $TargetUserLastLogon) {
$TargetUserLastLogon = $LastLogon
}
# Nettoyer la variable
Clear-Variable LastLogon
}
Catch {
Write-Host $_.Exception.Message -ForegroundColor Red
}
}
if ($TargetUserLastLogon -eq $DefaultDate) {
return “Jamais”
}
else {
return $TargetUserLastLogon.ToString(” dd/MM/yyyy à HH:mm:ss “)
}
}
$UI.Label.Content = “Active Directory – LastLogon – $((Get-ADDomain).DNSRoot)”
# Remplir la ComboBox avec les données des utilisateurs
Get-ADUser -Filter { Enabled -eq $true } | Select-Object samAccountName | Foreach {
$ComboBoxItem = New-Object System.Windows.Controls.ComboBoxItem
$ComboBoxItem.Content = $_.SamAccountName
$ComboBoxItem.HorizontalContentAlignment = ‘Stretch’
[void]$UI.MonComboBox.Items.Add($ComboBoxItem)
}
$UI.MonBouton.Add_Click(
{
# Assurez-vous que l’élément sélectionné n’est pas nul et récupérez son contenu
if ($UI.MonComboBox.SelectedItem -ne $null) {
$SelectedUser = $UI.MonComboBox.SelectedItem.Content
if ($SelectedUser -ne $null) {
$LastLogonOfUser = Get-ADUserLastLogon -Identity $SelectedUser
$UI.Label2.Content = “Dernière connexion de $SelectedUser : $LastLogonOfUser”
} else {
$UI.Label2.Content = “Aucun utilisateur sélectionné.”
}
} else {
$UI.Label2.Content = “Aucun utilisateur sélectionné.”
}
}
)
# Ajouter un événement de clic au bouton Switch
$UI.Switch.Add_Click({
if ($UI.Window.ThemeMode -eq “Dark”) {
$UI.Window.ThemeMode = “Light”
$UI.Switch.Content = “Switch to Dark”
} else {
$UI.Window.ThemeMode = “Dark”
$UI.Switch.Content = “Switch to Light”
}
})
# Définir le texte initial pour le bouton Switch en fonction du thème actuel
if ($UI.Window.ThemeMode -eq “Dark”) {
$UI.Switch.Content = “Switch to Light”
} else {
$UI.Switch.Content = “Switch to Dark”
}
# Afficher la fenêtre
[void]$UI.Window.ShowDialog()
Quels sont les changements lors de l’utilisation de PowerShell 7.X ?
Nous avons chargé l’ensemble de la fenêtre ainsi que les contrôles dans une Hashtable dans notre variable $UI.
$UI.Window = [System.Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $xaml))
$xaml.SelectNodes(“//*[@*[contains(translate(name(.),’n’,’N’),’Name’)]]”) |
ForEach-Object -Process {
$UI.$($_.Name) = $UI.Window.FindName($_.Name)
}
# Amener la fenêtre au premier plan
$UI.Window.Add_Loaded({
$This.Activate()
})
Découvrez ci-dessous un aperçu de notre application !
C. Changement de thème
Pour changer de thème, il suffit de changer la propriété ThemeMode de l’objet Window. Pour cela, ce code PowerShell nous permet de changer à la volée le thème de l’application.
$UI.SwitchThemeButton.Add_Click({
if ($UI.Window.ThemeMode -eq “Dark”) {
$UI.Window.ThemeMode = “Light”
} else {
$UI.Window.ThemeMode = “Dark”
}
})
Découvrez ceci avec l’animation suivante :
IV. Conclusion
En suivant ce tutoriel, vous devriez être en mesure de migrer vos applications de Windows PowerShell WPF à PowerShell Core ! La seule limite qui existe maintenant reste votre imagination.
Si vous avez des questions, pensez à commenter cet article.
Passionné par l’automatisation, la virtualisation et le déploiement des postes de travail, Jérôme BEZET-TORRES est Consultant Formateur sur les technologies Système et Réseau et professeur d’informatique dans l’Académie de Lyon en BTS SIO option Infrastructure, Systèmes et Réseaux. Il intervient également sur le cycle Ingénieur dans la formation ICS (Ingénieur en Informatique et Cybersécurité). Reconnu MCT (Microsoft Certified Trainer) depuis 10 ans, MVP (Most Valuable Professional) dans la catégorie Cloud and Datacenter Management (depuis 3 ans) et VMware vExpert depuis 4 ans, il fait partie de la communauté française PowerShell (French PowerShell User Group) et est organisateur de la communauté Workplace Ninja France. Il est également auteur pour les Editions ENI.