WinPE et Powershell

I. Présentation

 

Rien de spectaculaire dans cet article si ce n’est de vous sensibiliser aux avantages de Powershell dans un environnement un peu plus contraint que votre bureau Windows habituel. J’ai nommé le désormais célèbre “WinPE”

L’idée de ce petit atelier est de permettre d’évaluer les capacités de cet interpréteur dans un environnement plus limité qu’un Windows standard.

Qui dit Powershell, dit Framework DotNET. Vous le savez surement, mais je rappelle que ce framework n’était initialement pas supporté dans tous les environnements (p.ex. Windows 2008 CoreR2) et n’a été implémenté par Microsoft qu’à partir de WinPE 4 (soit Windows 8.1/2012R2)

Autre rappel, au cas où, les environnements WinPE x64 ne supportent pas de sous-système 32 bits (alias “Windows On Windows”) – Autrement dit, pensez à bien implémenter des vrais binaires 64 bits de votre outils favoris (Notepad++, Explorer ++, 7-Zip, etc…)

II. Fabriquer un WinPE incluant  Powershell

 

Pour bénéficier de la fonctionnalité Powershell dans un environnement WinPE, depuis Windows 8, rien de plus simple. Il suffit de récupérer le kit de déploiement Windows ADK (par exemple https://go.microsoft.com/fwlink/p/?linkid=859206) et le MDT pour faciliter la fabrication (par exemple https://www.microsoft.com/en-us/download/details.aspx?id=54259 ).

Une fois ces 2 éléments installés, lancez l’atelier de déploiement MDT “Deployment Workbench” puis créez un nouveau “New Deployment Share”. Peu importe les valeurs choisies pour notre exemple.

A. Petites précisions

 

Avant de commencer, précisons 2 choses qui risquent de vous agacer et que nous allons contourner.

  • Par défaut, sans opération de personnalisation, l’ADK fournira un noyau WinPE en anglais, avec le clavier en Anglais (pour les messages et les menus, ça passe encore, mais taper des commandes Powershell en QWERTY va vite vous lasser)
  • Les scripts Powershell sont bloqués par la stratégie d’exécution par défaut. Autrement dit, pour les exécuter, il faudra systématiquement préfixer l’invocation du script par “powershell.exe -executionPolicy bypass -file Script.ps1” (pénible aussi, non)

Il existe plusieurs moyens pour arriver à nos fins (cf https://www.it-connect.fr/presentation-de-winpe/ ), mais je vous propose de choisir arbitrairement celle-ci (technique LiteTouch) :

Ouvrez votre bloc-notes favori puis recopiez  le contenu ci-après

<?xml version="1.0" encoding="utf-8"?>

<unattend xmlns="urn:schemas-microsoft-com:unattend">

    <settings pass="windowsPE">

        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">

            <Display>

                <ColorDepth>32</ColorDepth>

                <HorizontalResolution>1024</HorizontalResolution>

                <RefreshRate>60</RefreshRate>

                <VerticalResolution>768</VerticalResolution>

            </Display>

            <RunSynchronous>

                    <RunSynchronousCommand wcm:action="add">

                    <Order>1</Order>

                    <Description>Init. clavier FR</Description>

                    <Path>wpeutil SetKeyboardLayout 040C:0000040C</Path>     

                </RunSynchronousCommand>

                  <RunSynchronousCommand wcm:action="add">

                    <Order>2</Order>

                    <Description>Console Powershell</Description>

                      <Path>powershell.exe -executionPolicy bypass -noexit</Path>

                </RunSynchronousCommand>

            </RunSynchronous>

        </component>

    </settings>

</unattend>

 

Enregistrez le sous le nom “unattend.xml” dans un sous-dossier tel que “\Boot\ExtraDir

 

B. Fabrication

 

Ouvrez ensuite les “Propriétés” de ce nouveau DeploymentShare. Pour cet exemple, on désélectionnera [x86] sous l’onglet “General“, puis on choisira [Platform x64] sous l’onglet “Windows PE

Sous l’onglet “General“, (celui de “Windows PE” cette fois ci),

Cliquez sur le bouton “Browse” correspondant à “Extra directory to add:“, puis sélectionnez le sous-dossier créé précédemment.

Cochez les cases “Generate a generic Windows PE WIM File” et  “Generate a generic bootable ISO image“.

Ajout d’un dossier supplémentaire dans un noyau WinPE

Sous l’onglet “Features“, cochez à minima, les 2 cases essentielles à cette démonstration, c’est-à-dire  “.NET Framework” et   “Windows Powershell” – les autres choix restent à votre discrétion :

  • [X] – DISM Cmdlets
  • [X] – .NET Framework
  • [X] – Windows Powershell
  • [X] – Secure Boot Cmdlets
  • [X] – Storage Management Cmdlets

Sélection des composants additionnels pour Powershell

Cliquez sur “OK“.

Sélectionnez ensuite le partage de déploiement puis utilisez le menu “Action … Update Deployment Share” ou le menu contextuel.

Cliquez 2 fois sur “Next“, patientez quelques minutes (selon la puissance de votre PC)

puis cliquez sur “Finish” un fois la génération terminée.

Les fichiers résultants sont présents dans le sous-dossier “Boot” de votre partage de déploiement

Si vous disposez d’un environnement de virtualisation, il suffit d’associer l’image .ISO à une machine virtuelle et de démarrer dessus.

Pour un essai à partir d’une clé USB, il suffit de préparer un média à partir d’une invite de commande ene mode Administrateur puis d’utiliser Diskpart comme suit :

C:>Diskpart

Diskpart> list disk

Repérer le numéro de disque correspondant à la clé USB (par exemple 2)

Diskpart> select disk 2

Diskpart> clean

Diskpart> create part primary

Diskpart> format fs=fat32 quick label="WinPE"

Diskpart> active

Diskpart> assign letter=K

Diskpart> exit

 

Ouvrez ou montez le fichier “Generic_x64.iso” dans l’explorateur Windows puis recopiez l’intégralité du contenu vers la clé USB.

Une fois lancé, ça devrait vous donner un truc du genre :

Ne fermez pas l’invite de commande traditionnelle qui se cache derrière cette console, sous peine de redémarrer l’ordinateur.

III. Explorons ce nouvel outil

 

Si vous avez, comme pour cet exemple, utilisé une distribution récente de Windows, tel que Windows 10 – 1709, vous pourrez vérifier la version de Powershell est 5.1

$PSVersionTable.PSVersion

 

A. Le noyau dur

 

Les commandes de base sont essentiellement apportées par le composant enfichable “Snapin” nommé “Microsoft.Powershell.Core”

Get-PSSnapin

Si on exclut les modules $PSModuleAutoLoadingPreference = ‘none’, on obtient 317 commandes

Get-command * | Group CommandType

Pour être plus précis, 45 fonctions, 272 cmdlets auxquels on peut ajouter 158 alias

 

On y retrouve toutes les commandes et alias utiles aux techniciens tels queGet-WmiObject ou gwmi mais je vous laisse les (re)découvrir par vous même 🙂

 

B.  Les modules

 

Au total, on dénombre 647 commandes avec le chargement automatique des modules ($PSModuleAutoLoadingPreference =’Auto’)

 

Le module “Storage” (option de fabrication) est particulièrement intéressant car il permet de nous affranchir de la célèbre commande “Diskpart.exe” et d’imaginer des scénarios plus complexes en matière des gestion des disques et partitions.

Import-module Storage

(Get-Command - Module Storage).count

Soit 152 commandes (plus exactement fonctions et alias) à votre disposition pour traiter le sujet…

Pour lister les modules, vous pouvez  utiliser la commande :

dir ($env:PSModulePath).Split(';')

A mon avis, il manque quelques modules, tels que la gestion des certificats (PKI), qui pourraient faire défaut dans le cadre d’une gestion de réseau sécurisé 802.1x. A noter qu’il est possible d’utiliser l’outil intégré par défaut “certutil.exe” pour les opérations de base mais en revanche, l’outil pfximport.exe est absent.

Vous pouvez également recourir aux classes DotNET et vous inspirer de fonctions  comme dans cet exemple : http://www.sherweb.com/blog/powershell-ing-on-windows-server-how-to-import-certificates-using-powershell/

function Import-509Certificate {

   param(

     [String]$certPath,

     [String]$certRootStore,

     [String]$certStore

     )

    $pfx = new-object System.Security.Cryptography.X509Certificates.X509Certificate2

    $pfx.import($certPath)

    $store = new-object System.Security.Cryptography.X509Certificates.X509Store($certStore,$certRootStore)

    $store.open(“MaxAllowed”)

    $store.add($pfx)

    $store.close()

}

 

Bien que l’opération soit plus délicate, et probablement non supportée par Microsoft, il reste toujours possible d’ajouter des modules dans le noyau WinPE, comme celui d’Active Directory selon la procédure indiquée ici https://daviddawsonsblog.wordpress.com/2017/03/03/powershell-active-directory-module-in-winpe-10/

 

C. Et côté GUI ?

 

Du coté des interfaces graphiques (GUI), pas de sortie “type Grid” telle que Out-Gridview, ni d’ISE mais la bonne surprise c’est que Windows Forms et WPF sont pleinement fonctionnels 😀

  • Exemple avec Winforms

  • Exemple avec WPF

IV. Conclusion

 

Voilà, pour ce petit tour d’horizon. Maintenant si vous souhaitez exécuter vos scripts Powershell (graphiques ou non) en toute tranquillité, il faudra exécuter la ligne de commande suivante.

Powershell.exe -executionPolicy bypass -NoLogo -NonInteractive -NoProfile -File x:\Scripts\MonScript.ps1

 

Pour un lancement automatique, ajoutez éventuellement ces commandes aux fichiers unattend.xml, startnet.cmd ou winpeshl.ini. cf mon article : https://www.it-connect.fr/presentation-de-winpe/

 

Si vous souhaitez modifier (durablement) la stratégie d’exécution de Powershell, il vous faudra

  • soit modifier le registre de WinPE (Montage du noyau) par la clé suivante :

Clé :  HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

Type: REG_SZ

Nom: ExecutionPolicy

Valeur : RemoteSigned ou Unrestricted

  • soit exécuter une commande préalable dans les fichiers unattend.xml, startnet.cmd ou winpeshl.ini
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" -Name ExecutionPolicy -PropertyType String -Value Unrestricted -Force

 

Reg.exe Add HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell /v ExecutionPolicy /t REG_SZ /d Unrestricted /f

 

Voilà c’est tout pour cette fois

Bien à vous

Christophe

Laisser un commentaire

Votre adresse de messagerie 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.