Archives de catégorie : DSC

Powershell DSC: Quelques réflexions

Voici quelques réflexions sur Powershell DSC:

Une approche descriptive

DSC est fondé sur l’approche descriptive pour la définition des configurations à appliquer et l’approche impérative pour la mise en oeuvre de ces configurations. Cela permet aux développeurs de définir des configurations sans avoir à se soucier des détails techniques et opérationnels pour qu’un déploiement applicatif et son infrastructure se fasse dans les règles. DSC, dans un contexte Devops, rapproche deux métiers qui ont par définition des objectifs différents. Les développeurs ont des besoins de déploiements à intervalles plus ou moins rapides, et les admins IT ont besoin de maintenir la maîtrise d’une infrastructure stable. Les développeurs définissent les configurations, et les admin IT, à travers les ressources DSC, les traduisent en commandes spécifiques et automatisées pour que l’infrastructure réponde aux besoins décrits.

La maîtrise de l’état de son infrastructure

DSC permet de savoir si une configuration a été appliquée, et surtout, si elle a été altérée. Dans un environnement cloud (public ou privé) où des myriades de VMs avec des rôles distincts se côtoient, il n’est pas aisé de savoir avec les outils actuels (GPO, SCCM, etc.), si les configurations sont bien appliquées et si des exceptions apparaissent suite à des manipulations ad hoc. Powershell DSC permet très simplement de savoir si une machine est dans un état désiré ou pas.

Une forte complexité due à des configurations en place qui ne sont plus dans les normes, multipliée par un nombre croissant de systèmes résulte dans la perte de maîtrise de son infrastructure. DSC permet de faire le point, savoir où on en est à tout moment, et ainsi faire face une infrastructure évolutive.

L’idempotence, la clé de la réussite des processus répétitifs

Les ressources sont un point fondamental de DSC. Une ressource est un module Powershell dédié à la configuration d’un élément de l’infrastructure (service web, cluster, annuaire, pare-feu, etc. etc.) qui expose 3 fonctions pour atteindre les objectifs suivants:

  • Appliquer une configuration donnée
  • Vérifier si l’application d’une configuration a été effectuée
  • Récupérer l’état de ce qui a été configuré

L’application d’une configuration doit être faite par idempotence, c’est à dire que si le processus est répété, le résultat sera le même sans générer d’erreurs. C’est ce point qui est important, car il permet de répéter à volonté l’opération de mise en production avec la maîtrise du résultat.

Powershell, le capital confiance par la simplicité.

Powershell est une révolution dans la mise en oeuvre des processus IT. Les demandes de mises en production (DMEP) ou mode opératoires avec des pages et des pages de screen-shots de wizards, clique ici, renseigne cela, next, seront balayés. Je ne dis pas que les DMEPs ou les mode ops vont disparaître, non, mais ils vont être extrêmement simplifiés. La complexité de l’opération sera cachée dans le script. Si le script est robuste, l’infrastructure sera stable, et sa mise en oeuvre rapide. Le capital confiance ne sera plus dans l’habilité d’un admin de gérer l’interface graphique d’un outil de configuration, la configuration sera codée dans le script à travers des cmdlets Powershell. Le tout sera réuni dans des ressources DSC. De plus, différents services informatique de l’entreprise peuvent rendre disponibles des modules ou des ressources DSC pour répondre aux besoins d’autres services.

Par exemple, l’équipe Collaboration peut créer des ressources qui, pour certaines fonctions, vont s’appuyer sur des modules venant de l’équipe Windows, et pour d’autres de l’équipe AD/Sécurité. Chacun apportant sa brique, son savoir faire, ses méthodes, et s’assurant que solution finale reste en conformité avec les règle mises en place. Cela permettra aussi à l’équipe Collaboration de garder la maîtrise sur les temps de mise en production et répondre ainsi aux besoins du métier.

La gestion d’un environnement de plus en plus hétérogène

Les environnements IT sont de plus en plus hétérogènes. Non seulement ils peuvent couvrir plusieurs versions d’un même produit, mais on trouve de plus en plus de liens entre des environnements Linux, UNIX, et Windows et autres. Powershell DSC est capable de gérer Linux à travers Open Management Instrumentation (OMI, la version open source de WMI) et l’approche Pull qu’on voit pour la famille de machines Windows. Qui sait, bientôt on pourrait voir des version de DSC sur UNIX ou même OSX à l’image de PASH qui est une version open source de Powershell disponible sur plusieurs plateformes tels que différents Linux, Solaris, OSX, etc.

Le prix du ticket d’entrée

Powershell DSC n’est pas un langage à part, il fait partie de Powershell, et donc il faut apprendre Powershell. Les acquis d’autres langages comme Visual Basic Script ne sont pas perdus, pour apprendre un langage de programmation il faut comprendre et maîtriser la structure d’un programme informatique, quelqu’un qui a des bases en programmation pourra s’adapter à Powershell plus rapidement. Powershell n’est pas simplement le remplaçant des commandes CMD, c’est un vrai langage de programmation, orienté objet, extrêmement moderne.

Quand un collègue me dit qu’il ne sait pas scripter et que dans son plan de formation il a l’administration de la nouvelle version de telle base de donnée, ou de je ne sais quoi, je lui dis immédiatement de repenser à son plan de formation et choisir plutôt un cours sur les bases de la programmation, peu importe le langage, et d’ensuite suivre une formation dédiée à Powershell et à .NET.

Pour conclure je dirais ceci: on est en pleine révolution et il y a un train formidable à prendre, il ne restera pas en gare longtemps.

 

Powershell DSC: Modification d’une ressource DSC existante

Dans cet article nous allons voir comment modifier une ressource DSC afin de l’adapter à nos besoins.

Pour rappel, une ressource DSC est un module qui permet de définir des configurations. Par exemple, la ressource xDisk permet d’initialiser et formater un volume et le rendre disponible avec une lettre donnée:

La ressource définit le numéro du disque à gérer (le disque 2 dans l’exemple), et la lettre avec laquelle on veut le rendre disponible (G).

Toute la gestion pour rendre le volume disponible, l’initialisation et le formatage (la partie impérative donc) est gérée sans qu’on ait à s’en soucier.

En fait si, on va s’en soucier. xDisk a été écrit pour Azure, et je voudrais le modifier car j’ai remarqué que le formatage du volume ne fonctionne pas sur mes serveurs.

Et j’ai aussi remarqué que la version 1.0 que j’ai essayée veut absolument redémarrer mon serveur cible….en boucle.

Alors allons modifier tout ça.

Toutes les ressources disponible dans le Resource Kit de Microsoft sont Open Source. Et Microsoft indique (à peu près une fois par page lue) ceci :

When making changes to these resources, we suggest the following practice:

  1. Update the following names by replacing MSFT with your company/community name and replacing the « x » with « c » (short for « Community ») or another prefix of your choice:
    • Module name (ex: xDisk becomes cDisk)
    • Resource folder (ex: MSFT_xDisk becomes Contoso_xDisk)
    • Resource Name (ex: MSFT_xDisk becomes Contoso_cDisk)
    • Resource Friendly Name (ex: xDisk becomes cDisk)
    • MOF class name (ex: MSFT_xDisk becomes Contoso_cDisk)
    • Filename for the <resource>.schema.mof (ex: MSFT_xDisk.schema.mof becomes Contoso_cDisk.schema.mof)
  2. Update module and metadata information in the module manifest
  3. Update any configuration that use these resources

We reserve resource and module names without prefixes (« x » or « c ») for future use (e.g. « MSFT_Disk » or « MSFT_ADUser »). If the next version of Windows Server ships with a « Disk » resource, we don’t want to break any configurations that use any community modifications. Please keep a prefix such as « c » on all community modifications.

Donc on doit renommer tous les fichiers dans l’arborescence de xDisk. Ainsi on sera conforme.

On renomme tous les fichiers et on remplace xDisk par cDisk, et MSFT par autre chose. Une fois que l’arborescence a été renommée on peut s’attaquer aux modules de metadonnées:

Le premier est cDisk.psd1:

Surtout bien remplacer le GUID qui identifie le module de façon unique.

Pour avoir un nouveau GUID utiliser la classe [guid] ainsi:

Ensuite dans le sous-répertoire DSCResources pour chaque ressource nous devons modifier le fichier MOF, par exemple le fichier BALLADELLI_cDisk.schema.mof. (comme je n’ai pas d’imagination et que Contoso est déjà pris, j’ai utilisé mon nom pour remplacer MSFT).

Et finalement on peut s’attaquer au module qui contient le code, dans mon cas: BALLADELLI_cDisk.psm1

Cette version de cDisk se focalise surtout sur la partie Set-TargetResource et ajoute le formatage à la suite de New-Partition directement avec un pipe (|).

On règle un petit souci car le code original ne pouvait fonctionner que si le volume était RAW. Et finalement enlève la demande de reboot car il y en a pas besoin.

Pour info dans Powershell DSC une demande de reboot s’écrit ainsi:

Un excellent moyen de tester le module est de le copier sur une machine cible de test, et de l’exécuter en local. Ainsi on s’évite toute la partie configuration à télécharger etc. ce qui peut prendre du temps si on doit résoudre des problèmes dans le code.

Une chose à savoir lorsqu’on crée ou on modifie une ressource DSC est que la fonction doit être idempotente. Ceci veut dire que si on exécute la fonction plusieurs fois, on doit toujours avoir le même résultat. Nous devons toujours nous assurer que c’est le cas, et le tester. Car si une ressource exécutée donne un résultat différent à chaque itération, nous allons avoir un vrai problème de conformité à terme.

Une fois le code bien testé, on doit le zipper et recréer un checksum.

On crée un zip qui s’appellera cDisk_1.2.zip (le 1.2 est la version qu’on a modifiée dans cDisk.psd1 dans le répertoire racine de la ressource).

On copie le zip dans $env:ProgramFiles\WindowsPowershell\DscService\Modules

et l’arborescence entière du répertoire cDisk dans $env:ProgramFiles\WindowsPowershell\Modules (comme pour l’installation d’un nouveau module, ainsi powershell ne produira pas d’erreurs lorsqu’on veut utiliser le nouveau module dans nos configurations).

Ensuite on regénére le checksum ainsi:

 

Finalement on est prêts à utiliser notre nouvelle ressource dans nos configurations:

Nous allons tout d’abord importer notre module:

Et nous allons l’utiliser:

Chose importante dans le cas de cette ressource cDisk (ou xDisk):

Nous devons arrêter le service ShellHWDetection, car dés qu’un nouveau matériel devient disponible il essaye (à tort ou à raison) de nous proposer un dialog box avec les tâches à effectuer, notamment pour effectuer un formatage du nouveau volume. Dans notre cas dés que la cmdlet New-Partition est exécutée, le service se réveille, or nous on ne veut pas de dialog box car on gère le formatage dans la commande successive. Du coup on l’arrête avec DSC, et on s’assure qu’il reste éteint.

Une fois que la configuration est exécutée on peut voir notre disque formaté, et disponible à la lettre voulue (G):

newvolumeAinsi que dans explorer:

newdrive

En conclusion je dirais qu’une best-practice est de se focaliser sur la fonction qui fait les modifications Set-TargetResource en local sur une machine de test. Et seulement ensuite d’intégrer le tout dans DSC pour utilisation avec des modules de configuration.

Autre best-practice est de ne pas sous-estimer le GUID et la version de la ressource. Si vous ne les changez pas, DSC ne copiera pas une nouvelle version du module car il pensera que c’est déjà fait. Pour vérifier le module que DSC a copié, vous pouvez vous rendre sur un serveur cible, dans le répertoire

C:\Program Files\WindowsPowerShell\Modules

Là vous pouvez vérifier que c’est bien la dernière version.

octocatToutes les sources sont dans ce repository Github

 

Powershell DSC: trouver le nom d’une fonctionnalité Windows à configurer

Voici une cmdlet bien utile lorsqu’on développe des configurations Powershell DSC.

Imaginons que nous voulons installer la feature Windows Server Backup, afin de planifier des sauvegardes sur nos serveurs Windows.

Dans l’article précédent nous avions configuré le rôle Active Directory Services de la même façon avec le code suivant:

Or comment trouver le nom de la feature Windows Server Backup? Nous pouvons utiliser la cmdlet Get-WindowsFeature, et passer en paramètre des caractères afin de simplifier la requête.

Par exemple si nous voulons voir toutes les fonctionnalités commençant par Windows, ainsi que les fonctionnalités DSC, nous pouvons passer un array, comme ceci:

Le X entre les crochets veut dire que l’option est déjà installée.

On voit aussi le nom de l’option Windows Server Backup, qu’on peut renseigner dans une ressource Powershell DSC:

Et voilà.

Powershell DSC: configuration d’un Contrôleur de Domaine

 

Suite de notre série d’articles sur Powershell DSC, nous allons maintenant capitaliser sur l’infrastructure que nous avons mise en place (voir articles précédents) pour configurer un nouveau contrôleur de domaine Active Directory (DC).

Il nous faut récupérer le module xActiveDirectory.

Sur le serveur pull, nous allons dézipper le module et le placer dans C:\Program Files\WindowsPowerShell\Modules.

Nous allons également placer le zip ici: C:\Program Files\WindowsPowerShell\DscService\Modules.

Enfin nous allons régénérer les checksums des modules à distribuer aux nouvelles machines, et pour cela nous allons exécuter le code suivant:

Voici le résultat:

xADmodule

(le module xNetworking était déjà présent et est le résultat d’un des articles précédents)

Nous allons maintenant modifier notre script de génération et distribution de configurations en 4 parties:

Dans la fonction de configuration (ServerConfig), nous allons importer le module xActiveDirectory:

Ensuite dans la partie Node $AllNodes.NodeName, nous allons faire deux choses:

Ceci installe la feature AD-Domain-Services, c’est comme si on ajoutait le rôle avec Server Manager.

Nous allons utiliser la ressource xADDomainController qui permet de promouvoir un serveur en contrôleur de domaine. C’est comme si on faisait un DCPROMO dans les anciennes versions de Windows Server.

On peut voir dans la ressource les éléments suivants:

  • SafemodeAdministratorPassword, il s’agît du mot de passe utilisé lorsque on veut entrer dans le mode de restauration (safe mode) du contrôleur de domaine.
  • DomainAdministratorCredential, ce sont les credentials d’un compte admin du domaine.
  • DomainName, le nom du domaine. A remarquer j’ai basculé cette info dans le $ConfigData du script, on sépare le quoi, du .
  • DatabasePath, LogPath, SysvolPath, à customiser si besoin.
  • DependsOn, Nous voulons nous assurer que si le rôle AD DS est installé avant faire la promotion du DC.

Finalement, nous allons modifier notre $configData ainsi:

On voit que c’est ici qu’on renseigne le nom du domaine. Ainsi je peux planifier de modifier le script pour ajouter plusieurs domaines, si besoin.

 

Voici le script entier:

Voici l’exécution du script:

Et voici le résultat dans Server Manager, on voit que le DC est bien installé et promu.

xADDCpromoted

 

Par contre je remarque que DNS a été ajouté, je pense que c’est dû au fait que la partition DNS de mon domaine est intégrée dans l’Active Directory. Il faudra tester avec un domaine qui utilise un DNS externe.

Enfin voilà, les prochains DCs seront tous les mêmes, à la virgule près.

En IT c’est facile de créer mais c’est beaucoup plus difficile de détruire. Pour enlever le rôle AD on peut utiliser la cmdlet Uninstall-ADDSDomainController. Il y a toute la méta-data à nettoyer si on l’enlève de façon brutale. On doit en tout cas penser au cycle de vie complet d’un DC afin que le tout reste cohérent. Et on doit en tout cas répéter à nos collègues coté développement applicatif de ne jamais s’appuyer sur un DC donné par son nom (où pire son adresse IP). Ils doivent toujours utiliser le nom de domaine, ce sera pareil pour eux, le DC le plus proche répondra.

Et nous coté IT, on pourra faire et défaire selon besoin.

Nano Server: un pas de géant vers DevOps

Lors de l’event //BUILD/ la semaine dernière à San Francisco, Jeffrey Snover et Andrew Mason de Microsoft ont dévoilé une nouveau type de serveur Windows, le Nano Server. Il a une particularité: Il n’y a aucune interface-homme-machine (GUI).

Oui, il y a les versions Core de Windows Server 2008 et 2012 qui peuvent être installées sans un GUI, mais on peut changer d’avis et remettre l’interface Windows. De plus, on peut se connecter à ces machines via RDP, et effectuer des opérations en local. Rien de ceci n’est possible avec Nano Server, car non seulement il n’y a pas de login, il n’y a pas non plus d’outils d’administration en local.

Nano Server est une version avec l’essentiel de Windows Server, et toute la performance d’un serveur ordinaire. Le superflu a été enlevé pour qu’il consomme le moins de place et de ressources possible. Aucun des rôles qu’on ajoute au serveur tels que IIS, AD, DNS etc, ne peuvent être installés tel qu’on le faisait jusqu’à aujourd’hui. Les rôles doivent être ajoutés à partir de packages comme n’importe quelle autre application.

Toute la gestion se fait à travers les composants à distance suivants:

  • Powershell DSC pour la configuration
  • WMI
  • Core Powershell, qui est une version basée sur le CoreCLR de .NET (oui c’est la version Open Source)
  • Portail Web (en remote) pour gérer certaines fonctionnalités telles que le Registry, le Control Panel, le Device Manager, l’Event Viewer, le Task Manager etc. Ce portail pourra gérer les versions « classiques » de Windows Server également.
  • Powershell Package Manager (OneGet) qui permet l’installation d’applications.

L’idée est de toujours passer par un ou des serveurs d’administration qui auront les scripts et les outils nécessaires pour la gestion du parc informatique, ces serveurs applicatifs auront pour rôle d’être le point central pour l’administration à distance d’un ou plusieurs serveurs, y inclus le serveur PULL de Powershell DSC qui sera lui même la clé de voûte de la configuration des machines  :

RemoteAdmin

Et tout ça veut dire beaucoup de scripts, d’automatisation, voire une approche qui s’apparente plus à du développement qu’à de l’administration IT.

Ce qui est important, est que nous sommes témoins d’un changement important dans la l’approche de mise en production et de gestion de serveurs Windows:

Les administrateurs IT devront se mettre au développement de scripts. Et ceci n’est ni une mauvaise chose, ni une nouveauté.

Il y a toujours eu des scripts, mais ces scripts étaient plutôt créés et utilisés si un outil d’administration ne remplissait pas totalement le cahier des charges. Oui, on utilisait des produits tel que SCCM pour le déploiement d’une multitude de machines, Mais dès qu’un problème faisait surface, on se connectait et on traitait les machines affectées de façon unitaire, en effectuant des opérations qui peuvent en modifier la configuration. Et c’est ainsi que petit à petit, on perd la conformité mise en place au début.

Tout ceci manque terriblement d’automatisation. La nouvelle approche Microsoft mets en place les composants nécessaires pour une automatisation du début à la fin du cycle de vie d’un serveur Windows.

Le point de focus n’est plus la machine, mais le(s) script(s) pour configurer la machine. Si le script est robuste, les serveurs le seront tout autant.

Si une machine présente une défaillance, on l’élimine, et on recommence en appliquant les scripts de déploiement et de configuration. L’unité n’est plus importante, le parc dans son ensemble le devient.

Si avec le temps, la machine déployée n’est plus conforme, on peut s’appuyer sur Powershell DSC pour que les réparations soient automatisées, ou éventuellement s’appuyer sur les rapports de conformités pour avoir un état des lieux.

Le monde applicatif a bougé, il s’appuie sur des méthodes de développement tels que Agile qui demandent des déploiements de plus en plus fréquents.

Coté IT, le but ultime reste la stabilité. C’est là que je pense que Powershell est capable de concilier deux mondes par tradition opposés. Car en s’appuyant sur l’automatisation on s’assure de créer et gérer les serveurs requis par les applications, et surtout on s’assure que ces serveurs restent en ligne avec les pré-requis de sécurité et de disponibilité, tout en améliorant les temps de mise à disposition et en réduisant les ressources requises.

A nous de nous assurer que nos serveurs d’infrastructure et nos méthodes répondent aux nouveaux besoins applicatifs, tels que des applications qui naissent et évoluent directement dans les clouds.

Voici le lien vers la session MSIgnite: Nano Server: The Future of Windows Server Starts Now

 

Powershell DSC: Chiffrer les mots de passe dans les configurations

 

Cet article est la suite de Powershell DSC: Installation d’un serveur Pull 1/2 et Powershell DSC: Installation d’un serveur Pull avec HTTPS 2/2.

Comment ça marche

Lors de la création de configurations MOF, il est parfois nécessaire de fournir des credentials, c’est à dire des mots de passe et noms d’utilisateurs et de les stocker dans les fichiers MOF.

Ceci est du au fait que le LCM sur le serveur cible s’exécute en tant que SYSTEM, ce qui veut dire que pour certaines opérations (Active Directory par exemple), il n’en a pas les droits.

 

Cet article explique comment le faire de façon sécurisée afin que le mot de passe ne soit pas stocké en clair, et pire, transmis en clair sur le réseau.

Comme illustré dans l’image suivante, le processus est assez simple. Le serveur PULL chiffre le mot de passe avec la clé publique du serveur cible, qui sera le seul à pouvoir la déchiffrer.

Idéalement, chaque serveur cible doit avoir son propre certificat. Idéalement on utilise également les Group Policy Objects (GPO) pour déployer ces certificats. Et idéalement on utilise la clé publique de chaque serveur pour chiffrer les données.

Attention: Dans cet article je n’utilise qu’une seule clé privée que j’installe sur chaque serveur cible. Un scénario idéal serait d’avoir un certificat par machine cible et gérer les clé publiques ainsi que les thumbprints de chaque machine dans le script de génération de configurations.

Dans l’illustration suivante, on voit le étapes nécessaires pour que les fichiers MOFs soient sécurisés, et ensuite transmis au serveur cible pour être déchiffrés et appliqués.

process

 

  1. Sécurisation des configurations MOF avec la clé publique du serveur cible (qui pour notre exemple est unique)
  2. Installation du certificat avec clé privée sur le serveur cible. Notre exemple fera ceci automatiquement.
  3. Gestion des fichiers MOF avec génération des checksum, et déploiement  via l’approche Pull sur le serveur cible
  4. Le Local Configuration Manager (LCM) détecte la nouvelle configuration, il est lui même configuré avec le thumbprint pour savoir avec quel certificat il peut déchiffrer les fichiers MOF.
  5. Le LCM déchiffre les fichiers reçus, et les applique.

Exporter la clé privée et publiques

Il y a plusieurs façons de créer de certificats, et plusieurs façons d’en exporter les clés privées (si possible) et clés publiques.

Dans cet exemple j’utilise le MMC des certificats de la local machine car c’est visuellement plus parlant. Puis cette opération ne doit être faite qu’une seule fois pour tester le chiffrement des fichiers MOFs décrits dans cet article.

Je reviens encore une fois sur la création du certificat, bien s’assurer qu’il s’agit d’une variante de la template « Computer » modifié pour avoir la possibilité d’exporter la clé privée.

Le certificat a été créé pour le serveur PULL et je fais ces opérations à partir de là.

certexport

Première étable, qui est l’export de la clé privée.

yesexport

Ensuite je renseigne un mot de passe pour accéder au fichier PFX créé. Avec une approche de déploiement des certificats via GPOs je choisirais plutôt de sélectionner un groupe.

certpass

Sélection du nom du fichier, à noter que je place tout dans C:\DSC.

certsaveprivate

Ensuite on fait la même chose pour le fichier CER, qui contiendra la clé publique.

noprivate

Sélection du format.

derencoded

Et on renseigne le nom du fichier.

publickey

 

La partie facile est finie. Passons à plus compliqué.

Séparation des données de configuration et des environnements cible

Powershell DSC permet de séparer les informations relative à la configuration propre d’un composant et l’environnement cible sur laquelle elle sera appliquée.

Ceci veut dire qu’on peut définir la configuration pour un serveur d’un type donné, disons SQL ou IIS, en séparant quels serveurs auront cette configuration.

Ceci me permet de créer une norme d’un coté, et les serveurs cible de cette norme de l’autre.

Voici un lien avec plus d’infos: DSC Configuration Data

Plus concrètement, nous on va s’en servir pour définir la configuration de notre serveur d’un point de vue composants d’un coté, et les données relatives au serveur cible, tels que le certificat à utiliser pour chiffrer le fichier MOF et le thumbprint pour le déchiffrer, de l’autre.

Voici un exemple de bloc de config data:

Il s’agit en fait d’un hash table qui contient une clé, Allnodes, qui est lui même un array de hash tables. Un noeud (node) étant une machine cible.

On peut avoir un noeud générique appelé « * » (attention ce n’est pas un wildcard, on ne peut pas faire *PAR* pour avoir tous les noeuds de Paris).

On peut aussi avoir un noeud par machine cible. Dans l’exemple plus bas, nous allons utiliser le GUID pour référencer la machine au lieu de son nom. Le GUID est utilisé dans notre exemple pour identifier de façon unique une configuration et est assigné de façon unique à une machine, donc pour nous le GUID est la cible.

Attention : le bloc de code $ConfigData, est très sensible, et très obtus, il ne comprend que des [String]. Si vous remplacez un élément de la table avec une variable, assurez-vous que cette variable est de format String, sinon elle sera ignorée. Par exemple si on crée une variable $GUID qui contient le résultat de [guid]::NewGuid(), ce n’est pas une string. Powershell pardonne beaucoup et si on l’affiche, ça s’affichera comme une string, mais le bloc $ConfigData de DSC ne pardonne rien.

Il faut soit faire:

ou alors

voire

et ensuite on peut ajouter nos variables ainsi:

On pourra ensuite appeler notre « fonction » de configuration DSC avec le paramètre -ConfigurationData $ConfigData pour qu’il soit pris en compte.

 

Regardons maintenant la « fonction » de configuration DSC:

La fonction prend en paramètre le GUID assigné à la configuration d’un serveur donné, et les credentials nécessaires à effectuer la copie de fichiers.

On remarque le bloc $AllNodes.Nodename, ceci utilisera le bloc $ConfigData dans lequel nous avons renseigné le nom en format GUID à utiliser. Ce sera l’ID de la configuration MOF.

Ensuite on voit un bloc LocalConfigurationManager dans lequel on voit l’élément CertificateId qui contient le thumprint renseigné dans $ConfigData. Cet élément est essentiel, car il permet au LCM de dechiffrer le fichier MOF.

Et finalement on voit le bloc de ressource File, appelé CopyFile qui définit les éléments suivants:

  • Ensure = « Present », on veut s’assurer que le ou les fichiers suivants, sont présents sur la machine cible.
  • L’opération est de type Directory, ou répertoire.
  • L’opération est récursive, donc si le répertoire renseigné contient plusieurs répertoires ils seront pris en compte.
  • Les paths source et destination
  • Les credentials à utiliser, c’est à dire que dans le MOF il y aura séparément le username et le mot de passe à utiliser.

Génération des configurations MOF

La cmdlet qui suit (New-ServerConfigurations) génère les fichiers MOF en prenant en compte un bloc $ConfigData et ensuite génère également les fichiers checksum (qui servent à s’assurer que les fichiers MOF n’ont pas été altérés). Et finalement copie tous ces fichiers au bon endroits, pour que le processus DSC puisse les prendre en compte et les déployer.

La cmdlet peut soit, forcer (paramètre -Force) la génération des configurations pour tous les serveurs dans la liste, ou vérifier si des configurations existent déjà, auquel cas, elle ne s’applique qu’aux serveurs qui n’ont pas de configuration.

A noter que la cmdlet retourne un array contenant toutes les configurations à appliquer. Cet array sera l’input de la cmdlet suivante qui déploie les configurations.

 

Voici à quoi ressemble le fichier MOF généré:

On voit bien le mot de passe chiffré dans la référence $MSFT_Credential1ref.

Déploiement des configurations

La cmdlet suivante, Export-ServerConfigurations fait plusieurs choses:

  • Vérifie que le certificat se trouve bien dans le store cert:\LocalMachine\My de la machine cible, et le cas échéant la copie et l’installe.
  • Utilise Invoke-Command sur les machines cible pour reconfigurer le GUID de la configuration à récupérer et appliquer.

 

Voici comment j’invoque les deux cmdlets:

Concernant le mot de passe stocké dans un fichier, voici une petite cmdlet qui permet de le faire:

 

Le tout réuni

Voici le script en entier, il définit les paramètres de script et permet d’avoir une vision globale sur l’approche utilisée:

 

Après exécution du script on peut vérifier avec le serveur de conformité, et voici le résultat:

compliant

 

Tout est conforme sur les deux machines cible que j’ai utilisé pour cet article.

Au fait, voyons si le fichier en question s’est bien copié sur le serveur cible:

magique

Magique!

octocatToutes les sources sont dans ce repository Github

Powershell DSC: Utilisation d’un module du DSC Resource Kit

Microsoft a publié toute une série de modules utilisables (et modifiables) pour DSC.

Ces modules peuvent être trouvés ici.

L’utilisation de ces modules est très intéressante, car on s’appuie sur l’approche de programmation déclarative. C’est à dire qu’on dit ce qu’on voudrait accompli, mais on ne définit pas comment. Le contraire de l’approche déclarative est l’approche impérative, qui définit le comment ou les étapes nécessaires pour accomplir une tâche.

Par exemple, on peut imaginer la création d’une règle de pare-feu ainsi:

Là on décrit ce qu’on veut dans notre règle, mais on ne dit pas comment l’accomplir. C’est DSC qui sait comment créer une règle de pare-feu.

L’avantage de cette approche est qu’on peut se focaliser sur ce qu’on veut accompli sans se soucier des détails techniques, qui eux, peuvent changer avec le temps.

Donc, on met en place notre configuration, tel qu’on l’a décrit dans les articles précédents, mais on voit qu’il y a un problème.

Sur la machine cible où on veut que cette configuration soit appliquée, on constate qu’elle ne peut pas s’appliquer. L’event log (voir ici pour le troubleshooting), nous montre ceci:

dscmodulenotfound

Si on réfléchi, c’est normal, on fait l’import du module xNetworking afin d’utiliser la ressource xFirewall avec  Import-DSCResource -ModuleName xNetworking, mais la machine cible n’a pas ce module, donc DSC ne peut rien faire.

DSC offre le moyen de distribuer les modules sur les machines cible.

Pour ceci on doit placer le fichier ZIP qu’on a téléchargé ici dans le répertoire DSCService\modules: $env:ProgramFiles\WindowsPowershell\DscService\Modules

On doit également créer le checksum du fichier zip avec la commande: New-DscCheckSum:

DscServiceModules

 

Si jamais vous tombez sur l’erreur de type 4104 qui indique à la fin d’une longue phrase:

File C:\Program Files\WindowsPowerShell\Modules\xNetworking\DscResources\MSFT_xFirewall\MSFT_xFirewall.psm1 cannot be loaded because you opted not to run this software now.

4104

Cet événement veut dire que vous avez essayé de copier les fichier manuellement afin de tester la configuration, et Windows a bloqué le fichier car il pense que le fichier vient d’internet. Pour régler ce problème il suffit d’utiliser la cmdlet Unblock-File. Mais le meilleur moyen de régler ce problème est de laisser DSC s’occuper de la copie des modules ;).

On vérifie que la configuration s’est bien appliquée sur la machine cible:

firewallconfig

 

Vérifions le pare-feu:

firewallrule

Et voilà.

 

Powershell DSC: Troubleshooting et Debugging

Comme tout programme, il est nécessaire d’avoir quelques bases en Powershell DSC pour des séances de debugging et régler d’éventuels problèmes dans ses scripts, ou en tout cas comprendre le cheminement des configurations et savoir détecter si elles ne peuvent pas s’appliquer et pourquoi.

La première chose à faire pour vérifier une configuration c’est de la visualiser avec Get-DSCConfiguration. Si elle n’a pas pu s’appliquer, on verra une erreur de type : Get-DscConfiguration : Current configuration does not exist.

ConfigNotFound

Attention, on peut aussi voir une ancienne configuration établie, et la nouvelle n’est pas visible car elle ne peut s’appliquer.

Lorsque on voit ce cas, on doit regarder l’état du Local Configuration Manager avec la commande: Get-DscLocalConfigurationManager:

LCMPendingState

 

Et ici on voit une chose importante, l’état du LCM (LCMState) est en PendingConfiguration. Ça veut dire que le LCM est en attente d’une configuration et que celle-ci à du mal à s’appliquer.

 

Les valeurs de LCMState sont les suivantes (j’en ai vu 3, peut-être qu’il y en a d’autres):

  • Idle: Le LCM ne fait rien, il attend
  • Busy: Le LCM est en train d’appliquer une configuration.
  • PendingState: Le LCM est bloqué, il sait qu’une configuration est disponible, soit il attend la période de refresh, soit il ne peut pas l’appliquer à cause d’une erreur dans la configuration.

Direction, l’Event Log.

Le log qu’on veut voir se trouve dans:

  • Applications and Services Logs
    • Microsoft
      • Windows
        • Desired State Configuration
          • Operational

EventLogError

 

Et là on voit qu’une ressource de type script appelé TestPorts a un problème. TestPorts est le nom de la ressource Script que j’ai écrit, donc ça me parle, la voici:

Le message d’erreur est : Exception calling « Connect » with « 2 » argument(s): « Cannot access a disposed object.
Object name: ‘System.Net.Sockets.TcpClient’. »

Ça veut dire que j’utilise un objet mal initialisé. La command $socket.close() rend mon objet $socket non-disponible pour une nouvelle connexion.

Je vais modifier mon script pour qu’il n’utilise qu’une seule instance de System.Net.Sockets.TcpClient à chaque fois:

Après avoir réappliqué ma configuration, je vérifie le LCM avec la commande Get-DscConfigurationManager:

LCMIdle

Et on voit que le LCM est passé en mode Idle. Il a du appliquer la configuration, allons vérifier avec Get-DscConfiguration

configOKLa configuration est bien présente, et on voit qu’elle se base sur quatre ressources, dont deux de registre et deux de script.

Tout ça nous montre deux choses intéressantes:

  1. L’automatisation est fantastique, elle nous permet de gérer des centaines voire des milliers de machines comme s’il y en avait qu’une seule. Lorsque je déploie une configuration, je sais que toutes ces machines l’appliqueront et seront exactement les mêmes. Ça veut dire aussi que si je fais une erreur, je peux mettre en carafe toutes ces machines d’un coup. DSC n’est pas le seul à induire un tel risque, les applications telles que SCCM ou Altiris ou même des GPO peuvent avoir les mêmes conséquences.
    Donc il faut un processus de mise en production en béton. Il faut un environnement de Développement et d’Intégration le plus proche de la Production que possible. Voire même un environnement de Pré-Prod, qui sera le dernier rempart de test. Il faudra aussi des processus de test pour valider les configurations avant de les mettre en production.
  2. Les scripts de génération de configurations sont des programmes, et ces programmes ont un cycle de vie, ils peuvent évoluer, des variantes peuvent être créées. Les admins qui utiliseront Powershell DSC doivent se familiariser avec des logiciels de gestion de version tels que SVN ou GIT. Ainsi on pourra développer et distribuer des configurations tout en étant capables de revenir en arrière si besoin.

L’erreur no Runspace available

Lors de l’installation d’un serveur pull sur une nouvelle machine Windows 2012 R2, nous avons eu l’erreur suivante lorsque nous exécutons Get-DscConfiguration:

 

Nous avions pensé tout d’abord à un problème de certificat, car ce problème ne se produit que si nous configurons le PULL serveur avec HTTPS.

La solution à ce problème est de s’assurer que le hotfix KB3000850 est bien installé. On voit tout de suite si ce hotfix n’est pas installé car lors de l’exécution de Get-DscLocalConfigurationManager montre qu’il manque des informations relatives au LCM (LCMstate, LCMCompatibleVersions, LCMVersion).

Faire Get-Hotfix KB3000850 et voir si le KB est bien installé.

Ce KB3000850 en requiert d’autres, avec quelques essais j’ai trouvé que les KB nécéssaires au minimum sont les suivants (avoir une machine complètement à jour est bien mieux bien sur) :

Mise à jour Lien
KB2883200 https://www.microsoft.com/en-us/download/details.aspx?id=40774
KB2884846 https://www.microsoft.com/en-us/download/details.aspx?id=40771
KB2919442 https://www.microsoft.com/en-us/download/details.aspx?id=42153
KB2938439 https://www.microsoft.com/en-us/download/details.aspx?id=42334
KB2954879 https://www.microsoft.com/en-us/download/details.aspx?id=42380
KB2919355 https://www.microsoft.com/en-us/download/details.aspx?id=42334
KB3000850 https://www.microsoft.com/en-us/download/details.aspx?id=44975

Powershell DSC: Le serveur de conformité

Dans les articles précédents, nous avons configuré un serveur Powershell DSC de type PULL. Nous l’avons ensuite sécurisé avec HTTPS pour chiffrer les échanges avec les machines recevant les configurations.

Nous allons maintenant regarder de plus près la deuxième application qui est installée lors de la configuration du serveur PULL:  PSDSCComplianceServer.svc.

Je me suis basé sur un blog de l’équipe Powershell à ce sujet pour comprendre le cheminement des commandes à passer, et j’ai adapté le script fourni avec un output en html (j’utilise beaucoup le HTML pour générer des tableaux de rapports afin des les envoyer par email ou les publier sur un site).

Nous allons utiliser les cmdlets Invoke-WebRequest et ConvertFrom-Json pour récupérer le statut de conformité des machines configurées par notre serveur PULL.

Nous allons ensuite convertir ces informations en format HTML et sauvegarder dans le Path fourni.

Voici le script:

A noter que j’ai eu initialement des erreurs de type Access Denied en essayant d’accéder au serveur. Dans les commentaires du blog mentionné plus haut, un internaute a donné la réponse à ce problème que j’indique ici:

« After some digging I finally discovered that this section is missing in Complience service web.config:
<modules>
<remove name= »WebDAVModule » />
<remove name= »AuthenticationModule » />
<add type= »Microsoft.Powershell.DesiredStateConfiguration.PullServer.AuthenticationPlugin, Microsoft.Powershell.DesiredStateConfiguration.Service » name= »AuthenticationModule » />
</modules>

It should be added under <system.webServer> configuration section. You can check Pull service web.config for example. »

Attention aux guillemets (« ) en copiant le code.

J’ai fait la modification et ça a bien fonctionné, voici le résultat:

DSCcompliance

 

Powershell DSC: Installation d’un serveur Pull avec HTTPS 2/2

Dans l’article précédent, nous avons mis en place Powershell DSC avec un serveur de type PULL afin que les nouveaux systèmes puissent récupérer leurs configurations.

Le service Web fonctionne bien, la génération des configurations se fait sans problème.

Nous allons dans cet article modifier le serveur Web pour qu’il puisse chiffrer les configurations envoyées aux nouveaux systèmes. Pour cela nous allons mettre en place le rôle Active Directory Certificate Services (AD CS) sur le DC actif du domaine ad.local.

Nous démarrons l’outil Server Manager. Puis Add Roles and features. Nous laissons le wizard nous guider jusqu’à la liste des Roles et sélectionnons Certification Authority:

ADCSrole

On le laisse terminer son installation, puis nous continuons sur la configuration post installation.

Lors de cette étape j’ai créé un Root Certificate, puis j’ai exécuté certsrv pour vérifier que mon serveur de certificats était bien configuré et démarré:

certsrv

 

Je me suis ensuite connecté sur mon serveur PULL et j’ai démarré l’application (MMC snap-in) qui gère les certificats locaux. J’ai selectionné Personal, puis right-click All Tasks puis Request New Certificate…

newcert

Une fois le Wizard démarré, nous allons sélectionner le enrollment disponible Active Directory Enrollement Policy:newcert2

Puis nous allons sélectionner PULL Server (J’ai au préalable créé une template de ce nom avec la particularité de pouvoir exporter la clé privée) et clicker sur Enroll:

certsrv2

Vérifions que notre certificat est bien installé:

newcert4Issued to PULL.ad.local et Issued by ad-DC1-CA, qui est notre root CA installé sur DC1. Tout va bien.

Nous allons maintenant chercher l’empreinte digitale (thumbprint), ou la clé publique de notre certificat. Pour cela, un peu de Powershell:

Bingo!

Exécuter (dot-sourcer) $env:programFiles\WindowsPowershell\Modules\xPSDesiredStateConfiguration\Examples\Sample_xDscWebService.ps1 afin de charger la fonction du même nom.

Nous allons tout simplement exécuter Sample_xDscWebService à nouveau en passant comme paramètre le thumbprint du certificat:

puis charger la nouvelle configuration à travers DSC:

ATTENTION: Si vous avez créé les applications Web avec l’exemple utilisant le trafic non-chiffré, il faudra enlever les deux applications, et laisser DSC en créer de nouvelles. Normalement je n’aurais pas du avoir à effectuer cette étape, mais ne voyant pas mes applications utilisant HTTPS arriver, j’ai voulu accélérer un peu le mouvement.

Il ne nous reste plus qu’à modifier le script de découverte de configurations (DiscoverConfiguration.ps1) et modifier la ligne 15 qui contient l’URL et le mode de connexion

Voici le script complet:

J’ai enlevé les fichiers du répertoire c:\temp\dsctest ainsi que la clé de registre, et ils sont bien revenus à leur place.

 

PS. Bien s’assurer que la KB3000850 est bien installé, voir la fin de cet article à ce propos.