Archives de catégorie : Scripting

Gabarit de certificat pour utiliser CMSMessage de Powershell 5.0

Honte à moi. Un certificat auto-signé dans mon dernier billet. J’avoue, je l’ai écrit sur mon canapé, et uniquement survolé la page Technet avant de me rendre compte de mon impardonnable erreur. Vu que le Technet ne donne pas les spécifications du gabarit de certificat à utiliser pour ADCS, je m’y colle en pénitence.

Comme base de travail, j’ai retenu le gabarit user. Pourquoi? Car je compte limiter ce type de certificats aux seuls comptes de services membres d’un groupe spécifique. Pas besoin que tous mes systèmes disposent de ce type de certificat. En plus avec ce choix, je vais limiter l’accès à ce certificat aux seuls comptes de service et non la totalité des comptes qui peuvent accéder au magasin personnel de l’ordinateur avec des privilèges administrateur ou supérieur.

Après, vu que pour utiliser la fonctionnalité CMSMessage, il faut PowerShell 5.0, j’ai choisi de limiter les systèmes éligibles en conséquences. Pour installer de Windows Management Framework 5.0, il faut au minimum un système d’exploitation de génération Windows 7 / Windows 2008 R2.

clip_image001

Dans l’onglet général, on nomme notre nouveau gabarit de certificat « CMS Message », pas grand-chose à dire sinon que ça ne sert à rien de publier le certificat dans l’Active Directory dans notre cas.

clip_image002

Dans l’onglet « Request Handeling », une seule chose compte, la capacité à exporter la clé privée. C’est grâce à elle qu’on sera en mesure de déchiffrer notre CMSMessage.

clip_image003

Pour la construction du Subject Name, il y a eu un peu de travail. Par défaut, le gabarit de certificat était prévu pour construire l’attribut en utilisant les informations issues de l’annuaire Active Directory. Bien, mais le problème, il est rare qu’un compte de service ou même un ordinateur se voit affecté une adresse de messagerie. Pour cela, j’ai dû procéder à quelques adaptations :

  • Ne pas inclure l’adresse de messagerie dans l’attribut Alternate Subject Name
  • Ne pas inclure l’attribut E-Mail
  • Ne pas inclure le DNS Name (pas de sens pour un utilisateur)
  • Mais bien inclure un UPN

clip_image004

C’est maintenant qu’il faut introduire la subtilité. Pour que la commande Protect-CMSMessage accepte d’utiliser notre certificat, il doit avoir un rôle bien particulier. Pas de bol, il est pas dans le gabarit de certificat que nous avons utilisé comme base de travail. Qu’à cela ne tienne, on va le personnaliser.

clip_image005

Pour être sûr que notre certificat ne soit pas détourné pour un autre usage, on va faire le ménage dans les EKU et ne positionner que « Document Encryption ».

clip_image006

Maintenant, c’est mieux.

clip_image007

On approche de la fin. Ne pas limiter la capacité d’enregistrement de certificat, c’est la porte ouverte à toutes les fenêtres, des certificats délivrés à gogo sans se soucier qu’un jour il faudra les renouveler, ce qui bien sûr arrive toujours au pire moment. En limitant la capacité d’enrôlement aux seuls membres d’un groupe, on saura déjà à qui on a délivré ces certificats.

clip_image008

Y a plus qu’à publier notre gabarit de certificat et Zou, à la signature.

clip_image009

Une fois la session ouverte avec notre compte de service, on peut réaliser la demande.

clip_image010

C’est fini. Pour s’assurer que cela fonctionne, une rapide commande Powershell « Get-ChildItem Cert:\CurrentUser\My -DocumentEncryptionCert » nous confirme que nous avons bien un certificat prévu pour cet usage dans le magasin. Vu que c’est le cas, y a plus qu’à chiffrer notre message :

$Cert = Get-ChildItem Cert:\CurrentUser\My -DocumentEncryptionCert

$CMSMessage = Protect-CMSMessage -Content « Ilachangé! » -To $Cert/Thumbprint

clip_image011

 

Aller, je retourne me punir, j’ai du python sur le feu. Je ne déconne pas

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Cacher les mots de passe dans les scripts Powershell

Nous passons tous beaucoup de temps à industrialiser avec PowerShell. Il n’est pas rare que je retrouve les mots de passe codés en dur dans les scripts. Pour éviter ces dérives, j’ai compilé dans ce billet quelques méthodes pour cacher ces mots de passe, du plus simple, au plus sexy

En PowerShell, la gestion des credentials est quelque chose que nous semble très simple. On sait tous que l’on peut « sécuriser » les mots de passe avec le fameux ConvertTo-SecureString. Le problème, c’est que cette fonction est réversible avec la méthode « Get-NetworkCredential ». Pour vous donner une idée, une rapide démonstration :

clip_image002

Le problème, c’est que dans l’exemple ci-dessous, PowerShell utilise Windows Data Protection API (DAPI). Cela signifie que seul le même compte est capable de chiffrer/déchiffrer notre secret. Stocker l’information dans un fichier ou dans le registre. On va devoir ruser pour ne pas utiliser une clé de chiffrement locale au système d’exploitation. Si on creuse un peu la commande ConvertFrom-SecureString, on trouve deux paramètres intéressants :

clip_image004

Donc si on utilise une clé externe de taille assez grande, on devrait être capable de chiffrer nos données en étant indépendant du système d’exploitation. Commençons par chiffrer notre information avec notre nouvelle clé.

$ScriptPath = (Split-Path -parent $MyInvocation.MyCommand.Definition)

[Object] $Cred = $null

[Guid] $Key = « e8bdc7c5-a62c-4fa3-9228-5abe22488141 »

[String] $CredFile = « $ScriptPath\CredData.ps1xml »

if ( $Cred -isnot [System.Management.Automation.PSCredential] )

{

[Object] $Cred = (Get-Credential -Message « Service Account »)

[Object] $CredData = $Cred | Select-Object -Property UserName,@{Name= »SecurePassword »; Expression={ ConvertFrom-SecureString -SecureString $_.Password -Key $Key.ToByteArray() }}

$CredData | Export-CliXml -Path $CredFile -Encoding Unicode -Force

Remove-Variable -Name CredData -Force

}

Get-Content $CredFile

clip_image006

Logiquement, on doit pouvoir faire l’inverse facilement avec le script suivant :

$ScriptPath = (Split-Path -parent $MyInvocation.MyCommand.Definition)

[Guid] $Key = « e8bdc7c5-a62c-4fa3-9228-5abe22488141 »

$CredFile = « CredData.ps1xml »

[Object] $CredData = Import-CliXml -Path ($ScriptPath + »\ » + $CredFile)

if ( $? )

{

$SecurePassword = ConvertTo-SecureString -String $CredData.SecurePassword -Key $Key.ToByteArray()

$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($CredData.UserName, $SecurePassword)

$Credential.GetNetworkCredential() | Format-Table *

}

clip_image008

Note : On m’a fait remarqué cette semaine que cela aurait été encore mieux d’utiliser le paramètre « -SecureKey ». Notre clé aurait alors été encodée dans un System.Security.SecureString. Merci Sylvain.

Le problème, c’est que ma clé est lisible dans le script. Ce qu’il faudrait, c’est de pouvoir la disposer d’un mécanisme me permettant de chiffrer des données avec une clé qui soit reconnue d’autres systèmes mais qu’on ait pas besoin de la même clé. Un truc comme une clé asymétrique. Chiffrer des données avec un certificat, c’est utiliser la clé publique pour cela. Pour déchiffrer, on aura besoin de la clé privée. Nous allons avoir besoin d’un certificat qui devra être présent :

  • Sur le système qui assure le chiffrement du message (en l’occurrence un mot de passe)
  • Sur les systèmes qui devront accéder à cette information

Cela implique que le certificat que nous allons demander devra être :

  • Reconnu comme issu d’une autorité de certification reconnue de toutes les parties
  • Être exportable

Ces points techniques résolus, attaquons nous au chiffrement de notre message avec quelques lignes de PowerShell :

$cert=Get-ChildItem Cert:\LocalMachine\my | where {$_.Subject -like « CN=Powershell Authentification* »}

$Password = ‘Il a changé!’

$EncodedPassword = [System.Text.Encoding]::UTF8.GetBytes($Password)

$EncodedBytes = $Cert.PublicKey.Key.Encrypt($EncodedPassword, $True)

$EncryptedPassword = [System.Convert]::ToBase64String($EncodedBytes)

clip_image010

Quelques explications s’imposent. On commence par localiser le certificat que nous allons utiliser et encoder notre mot de passe au format UTF8. Ceci-fait, on encode notre mot de passe à l’aide de la clé publique de notre certificat et con convertit le tout en Base 64. Ca ressemble plus du tout à notre mot de passe. On peut communiquer cela tel que, aucun risque que cela puisse être décodé sans la privée. Justement, allons voir comment décoder cela sur un autre système avec un peu de PowerShell :

$cert=Get-ChildItem Cert:\LocalMachine\my | where {$_.Subject -like « CN=Powershell Authentification* »}

$Encryptedcontent = Get-Content .\secret.txt

$Encryptedcontent

$EncryptedBytes = [System.Convert]::FromBase64String($Encryptedcontent)

$DecryptedBytes = $Cert.PrivateKey.Decrypt($EncryptedBytes, $True)

$DecryptedPassword = [System.text.Encoding]::UTF8.GetString($DecryptedBytes)

clip_image012

Si on a compris la logique, on commence par reconvertir notre contenu en une chaine de caractères pour laquelle on va utiliser la clé privée de notre certificat pour déchiffrer notre message. L’avantage de cette approche est qu’elle est indépendante du système d’exploitation, même Cross-Plateforme. Autre avantage, on peut limiter l’accès à la clé privée. Il faut juste décider qui à accès à la clé privée.

clip_image014

Ça c’était bien avec les vieilles versions de PowerShell, ça fonctionne super, même avec Orchestrator, c’est pour dire, … On ne peut pas faire plus sexy avec des versions plus récentes ? Oui, car depuis la version 5.0, on dispose de la fonctionnalité CMSMessage. L’aide intégrée de PowerShell ne vas pas vous aider beaucoup.

clip_image016

Avec la version en ligne de Protect-CMSMessage, c’est déjà mieux. On utilise toujours un certificat, sauf que cette fois, notre certificat devra comprendre l’EKU « Document_Encryption » pour qu’on puisse l’utiliser avec la commande Protect-CMSMessage. J’ai donc préparé une demande de certificat en bonne et due forme ou presque. En fait, ce sera un certificat auto-signé (j’ai fait court pour la démonstration).

clip_image018

Au passage, un switch bien pratique que je ne connaissais pas pour filtrer les certificats : Get-ChildItem Cert:\CurrentUser\My -DocumentEncryptionCert

En une seule commande on va être capable de chiffrer notre message : $Message = Protect-CmsMessage -Content $Password -To « *benoit@simplebydesign.fr ». Après, y a plus qu’à empaqueter et transmettre.

clip_image020

De l’autre côté, même principe. On commence par localiser le certificat que nous allons utiliser pour déchiffrer à l’aide de la commande Get-ChildItem Cert:\CurrentUser\My DocumentEncryptionCert. Reste plus qu’à déchiffrer.

clip_image022

Jusque-là, on parlait On-Premises, Old-School IT. Et si on regardait comment faire de même dans Azure. Y a forcément un service pour cela. Oui, C’est Azure Key Vault. Avant cela, faut un peu préparer le terrain. On peut faire cela en PowerShell assez rapidement :

Install-Module AzureRM

Install-AzureRM

clip_image024

Justement, le dernier installé nous intéresse. Continuons notre mise en place, on y reviendra. Continuons avec l’installation du module PowerShell Azure, chargeons tous les modules Azure Resource Managers et celui d’Azure avec les trois commandes suivantes :

Install-Module Azure

Import-AzureRM

Import-module Azure

clip_image026

La première étape d’Azure, c’est l’authentification. Ça se règle en deux commandes PowerShell :

$Cred = get-Credential

Login-AzureRMAccount -Credential $Cred

clip_image028

La commande Get-AzureRMSubscription nous indique que j’ai accès à plusieurs souscriptions. Nous allons nous fixer sur l’une d’entre elle.

clip_image030

Les prérequis sont en place. Nous devons mettre en place notre Azure Key Vault au sein d’un groupe de ressources dédié (sécurité oblige)

New-AzureRmResourceGroup -Name ‘MyKeyVault’ -Location ‘North Europe’

New-AzureRMKeyVault -VaultName ‘MesPrecieux’ -ResourceGroupName ‘MyKeyVault’ -Location’North Europe’

clip_image032

A noter que lors de la création, il faudra prouver son identité. A ce niveau, nous sommes le seul à y avoir accès via l’URL suivante : . Stockons notre mot de passe avec les commandes PowerShell suivantes :

$Password = « Ilachangé! »

$SecretValue = ConvertTo-SecureString $Password -AsPlaintext -Force

Set-AzureRMKeyVaultSecret -VaultName ‘MesPrecieux’ -Name « Password » -SecretValue $SecretValue

clip_image034

Nous pouvons vérifier que nous avons bien un secret dans notre coffre aux précieux :

Get-AzureKeyVaultSecret -VaultName ‘Mesprecieux’

clip_image036

Jusque-là, ça casse pas trois pattes à un canard. Montons un peu le niveau. Si on a un coffre-fort pour nos secrets, la moindre des choses, ce serait de pouvoir retrouver l’historique de notre mot de passe, voyons le résultat de la commande Get-AzureKeyVaultSecret -VaultName ‘Mesprecieux’ -Name ‘Password’ -IncludeVersions.

clip_image038

La ça devient intéressant. Non seulement, on a l’historique des valeurs mais on peut aussi filtrer pour utiliser le dernier disponible. Voyons comment retrouver la dernière version de notre mot de passe :

$liste = get-AzureKeyVaultSecret -VaultName ‘Mesprecieux’ -Name ‘Password’ -IncludeVersions

$Password = $liste | Sort-object -property updated -Descending | select -first 1

$secret = get-AzureKeyVaultSecret -VaultName ‘Mesprecieux’ -Name ‘Password’ -Version $password.Version

$Secret | Get-member

$Secret.SecretValue

$Secret.SecretValueText

clip_image040

Nous avons retrouvé le dernier mot de passe associé. Entre temps, il a été changé (sécurité oblige). OK, c’est pas mal. Le problème, c’est de partager nos secrets. La, Azure Key Vault fait fort car grâce à Azure Resource Manager, on peut déléguer l’accès. La commande ci-dessous délègue l’accès à un utilisateur, uniquement pour lire le contenu de mon coffre.

Set-AzureRmKeyVaultAccessPolicy -VaultName ‘MesPrecieux’ -UserPrincipalName ‘test@XXXXXXXXXX.onMicrosoft.com’ -PermissionsToSecrets ‘Get’

Get-AzureRmKeyVault -VaultName ‘mesprecieux’

clip_image042

Après, j’aurai pu pousser le vice de déléguer uniquement l’accès à mon mot de passe. On peut même autoriser des applications à accéder aux précieux.

Pour les amateurs, quelques lectures supplémentaires :

 

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Un peu de magie avec la QoS Windows

A la base, la fonctionnalité des « Offline Files » est une bonne idée. Le problème, c’est quand on tente de dépasser les limites de nos tuyaux réseau. La volonté de centraliser les données des utilisateurs va rapidement saturer le réseau WAN, c’est ce qui est arrivé à un de mes clients. La situation était telle que les applications métiers devenaient difficile à utiliser à cause de la bande passante consommée pour la synchronisation des données. Un vrai casse-tête, qui a conduit ce client à bloquer le trafic SMB à destination des partages contenant les « Offline Files » en central.

Problématiques posées

Voilà un challenge intéressant. On a beau retourner le problème dans tous les sens, il faudra bien réintroduire le service. C’est pas sans poser quelques problèmes :

  • Réintroduire la fonctionnalité c’est assurément atomiser le réseau. Plus on va attendre, plus les utilisateurs auront accumuler des données à synchroniser
  • Plus on tarde, plus on prend le risque de la perte de données en cas de perte du poste de travail.
  • Les performances du réseau WAN ne sont pas extensibles, rien n’interdit un utilisateur de vouloir synchroniser des Go de données.
  • La dispersion géographique des utilisateurs était pour mon client un véritable problème. Plus de 200 implémentations géographiques avec des utilisateurs essentiellement nomades

 

La solution ne pouvant pas venir de la fonctionnalité « Offline Files », on a donc commencé à chercher ailleurs. Mon premier réflexe a été d’aller faire un tour dans mon éditeur local de stratégies de groupes pour voir si une des nombreuses fonctionnalités natives de Windows ne pourrait pas nous aider. Effectivement, Windows sait faire de la QoS réseau.

clip_image001

 

Si on regarde la fonctionnalité de plus près, c’est pas mal du tout. A la base, cela permet de tagger les flux réseau qui sortent du poste de travail pour que les équipements réseau puissent y associer une politique de QoS. Moins connu, il est aussi possible de maitriser le bande passante consommée directement depuis le poste de travail. En voilà une bonne idée. Techniquement oui mais au final, c’est une fausse bonne idée. Avec plus de 200 implémentations géographiques, c’est autant de situations différentes. Avec les GPO, cela reviendrait à mettre en place autant de stratégie de groupe que d’implémentations géographiques. Après, la fonctionnalité de QoS ne traite réellement que les flux sortants du poste de travail, pas les flux entrants. Lorsqu’on regarde dans la configuration avancée, on constate qu’on ne dispose pas du même niveau de finesse.

clip_image002

 

C’est une politique est globale, pour tous les flux entrants. Le tableau ci-dessous documente la QoS :

Niveau

QoS

0 64Kb
1 256Kb
2 1Mb
3 16Mb

 

La QoS de Windows a aussi ses limites. Si en face le serveur de fichiers avait été un serveur Windows, on aurait pu aussi utiliser la QoS de la même manière. Vu que ce n’était qu’un simple NAS, il ne disposait pas de la fonctionnalité. Dans la pratique, cela va nous poser quelques problèmes :

  • Si un utilisateur ouvre une session sur un poste de travail qui n’est pas le sien, on ne pourra pas maitriser la copie des fichiers
  • Si un utilisateur se voit doté d’un nouveau poste de travail, même punition

 

Malgré ces limitations, j’ai continué mon exploration de la QoS. Certes elle a ses limites mais on peut déjà l’utiliser pour maitriser le flux sortant à destination du NAS. Fallait juste trouver un moyen d’industrialiser un peu tout cela. Quand on pense, industrialisation, on pense rapidement à Powershell. Bingo, je me souviens maintenant qu’il existe un module Powershell introduit avec Windows 8 et Windows 2012. Un peu de recherche et effectivement, le module NetQoS existe bien. Plus important, il existe bien sur le socle Windows 8 de mon client.

clip_image003

 

Une idée commence à germer. Et si on pouvait industrialiser la mise en place d’une politique de QoS au niveau des postes en fonction de sa situation réseau. En voilà un beau challenge. Faisons quelques expériences :

New-NetQosPolicy « Synchro NAS » -NetworkProfile Domain -DSCPAction 40 -DestinationIpAddress <Adresse du mon NAS> -IPProtocol TCP -IPSrcPort 445 -ThrottleRateActionBitsPerSecond 1Mb

clip_image004

Globalement, on dit à Windows de mettre en place une politique de QoS pour limiter le trafic SMB à destination du NAS uniquement pour le cas où la connectivité réseau est de type domaine (pare-feu). Pour vérifier si cela fonctionne, faut des gros fichiers. J’ai créé le script PowerShell suivant :

$Path = « c:\testFile.Txt »

$File = [IO.File]::Create($path)

$File.Setlength(1Gb)

$File.Close

Get-Item $Path

clip_image005

 

OK, 1Mbits, c’est juste un peu trop hardcore, on va passer à 2Mbits en reconfigurant la policy avec la commande PowerShell suivante :

Set-NetQosPolicy -name « Synchro NAS » -ThrottleRateActionBitsPerSecond 2Mb

clip_image006

 

Maintenant, faut des chiffres et prouver que cela fonctionne. Par expérience, l’explorateur Windows, c’est pas fiable. Le petit script PowerShell ci-dessous devrait nous aider :

cls

$startdate = get-date

Write-host « Début de test de copie d’un fichier de 1Go sur un share SMB $(Get-date) »

Copy « C:\Temp\TESTFILE.TXT » « \\<Adresse IP destination>\partage$\Datas\\TESTFILE.TXT » -Force

Write-host « Fin de test de copie d’un fichier de 1Go sur un share SMB $(Get-date) »

$enddate = get-date

Write-Host (New-TimeSpan -Start $startdate -End $enddate).TotalSeconds

clip_image007

 

A quand même, 1217 secondes pour copier mon fichier de 1Go. Au passage, je suis sur un portable en config « Full patate » avec connexion réseau Gigabit et SSD. Sceptique? Peut-être que le gestionnaire de tâche sera plus parlant alors.

clip_image008

 

Oui, il y a des pics de consommation mais ils sont régulés automatiquement. Tentons la même expérience avec une QoS à 5Mb.

clip_image009

 

Déjà, ça va mieux, que 503 secondes. Logiquement avec une QoS à 10Mb, on devrait être deux fois plus rapide, bingo.

clip_image010

 

Avec une QoS à 25Mb, on arrive à 103 secondes. Pour information, sans aucune QoS, le temps de copie de référence est de 42 secondes.

clip_image011

 

Donc, c’est industrialisable. Maintenant, les derniers détails :

  • Comment industrialiser la configuration?
  • Comment centraliser le paramétrage?

 

Comment industrialiser la configuration?

La y a pas 36 solutions. On a vu que les GPO, c’était pas possible. Il faut donc travailler au plus proche du poste. Un script de démarrage exécuté par GPO? Oui mais il ne s’applique que lorsqu’on démarre le système d’exploitation, pas quand l’ordinateur sort de veille. Très logiquement, ce sont les tâches planifiées qui se sont imposées, surtout quand on sait qu’on peut les déclencher quand on en a besoin :

  • A l’ouverture de session
  • Au déverrouillage de session
  • Après période d’activité
  • Sur détection d’un évènement dans les journaux d’évènements

OK pour exécuter un script PowerShell via tâche planifiée mais sous quel contexte? Faudra bien un compte de service, qu’il faudra maintenir. Oui mais c’est pas moi qui vais maintenir ce compte de service. Mon client utilisant Windows 8 sur ses postes de travail, l’utilisation de Group Managed Services Accounts alias GMSA s’impose. Avec Windows 8, ce qui est cool, c’est qu’on peut utiliser ce type de compte pour les tâches planifiées : Windows Server 2012: Group Managed Service Accounts.

 

Comment centraliser le paramétrage?

On sait comment configurer, reste le paramétrage. Un rapide cahier des charges s’impose :

  • Faut que ce soit facile à maintenir et faire évoluer (Que celui qui a proposé une base SQL lève la main, …)
  • Faut que ce soit léger sur le réseau
  • Faut qu’on puisse le faire évoluer rapidement pendant le développement
  • Enfin, toujours respecter la règle de base : Simple by Design

 

OK, on aurait pu développer un Web Service qui délivre la configuration mais c’est un peu too much. On va se contenter d’un simple fichier XML.

clip_image012

 

Effectivement, un fichier XML, c’est simple à maintenir, facile à faire évoluer et ça pèse pas trop lourd sur le réseau. En plus, c’est super simple à utiliser dans le script Powershell que nous exécutons dans notre tâche planifiée.

 

Le tour de magie

Le tour de magie, c’est donc un script Powershell, exécuté dans le contexte d’un compte de service dont nous n’avons pas à maintenir le mot de passe. Ce script va récupérer sa configuration en central dans un partage SMB pour conserver une copie locale en cas d’impossibilité d’accéder au partage. Le script va exploiter le fichier XML pour mettre en place des politiques de QoS pour tous les cas d’usage (interne, externe, VPN …).

clip_image013

 

Au final, ça donne cela.

clip_image014

 

A chaque ouverture de session, déverrouillage de session ou même changement d’état de la connectivité réseau, la politique de QoS est automatiquement adaptée. Donc même en sortie de veille, on s’adapte.

Et maintenant?

Maintenant, le client est en mesure de proposer une politique de QoS pour chaque implémentation géographique. Au début, il va positionner la QoS à une valeur très basse, (genre 1Mb) pour augmenter progressivement jusqu’à trouver le point d’équilibre entre la synchronisation des fichiers des utilisateurs et les applications métiers.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Nouvelles versions d’ADMPWD

J’ai déjà publié quelques billets sur ADMPWD d’une mise en œuvre classique, jusqu’à son intégration dans des processus complexes avec SCSM. Fin novembre 2014, la solution avait été mise à jour pour intégrer un mécanisme de protection contre les politique d’expiration de mot de passe abusive. Ca permettait d’éviter qu’on puisse éviter qu’ADMPWD ne renouvèle le mot de passe avec une date d’expiration trop lointaine.

clip_image001

 

Début Janvier 2015, l’auteur nous gratifiait d’une dernière version en intégrant :

  • Correction de la valeur "SearchFlags" dans l’extension de schéma pour éviter que le mot de passe ne soit notifié dans les audit tracking de Windows Server 2012/2012 R2
  • La création des comptes administrateurs locaux directement dans le package d’installation

clip_image002

 

Mais l’auteur nous promettait une nouvelle version avec plein de fonctionnalités sexy.

clip_image003

 

Bonne nouvelle, cette nouvelle version existe. Mauvaise nouvelle, elle sera dédiée aux clients ayant souscrit un contrat du support Premier ;). En contrepartie, beaucoup de nouveautés :

  • Prise en charge du chiffrement des mots de passe dans l’Active Directory
  • Diffusion de la clé de chiffrement par GPO
  • Configuration automatique des agents ADMPWD par mécanisme d’auto-découverte
  • Mise à disposition d’un Web Service pour gérer la révélation des mots de passe sécurités par ADMPWD
  • Une interface Web

clip_image004

 

Par contre implique un nouvel attribut pour prendre en compte l’historique des mots de passe. Si la solution vous intéresse, je vous recommande de consulter la présentation suivante : https://sway.com/OFNqS4N9i5d3neb_

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Identifier les GPO préparées pour ADMPWD

Dans la série ADMPWD, une petite problématique d’exploitation. Le commandlet Powershell propose la commande Register-ADMPWDWithGPO permet de référencer le Client-Side extension lié à ADMPWD. techniquement, la commande se contente de configurer l’attribut ‘gpcmachineextensionnames’ avec le bon contenu : L’identifiant du Client-Side Extension d’ADMPWD.

 

C’est bien mais comment vérifier que c’est bien fait? Pour cela, il faut faire le travail nous même. le script ci-dessous permet de rechercher parmi toutes les GPO celles pour lesquelles l’attribut ‘gpcmachineextensionnames’ a été configuré pour ADMPWD.

$allGPOs = ([adsisearcher]'(objectCategory=groupPolicyContainer)’).FindAll()

$allGPOs | ForEach-Object {

    if ($_.Properties.gpcmachineextensionnames -ne $null)

    {

        $content = $_.Properties.gpcmachineextensionnames

        If ($content -match ‘{D76B9641-3288-4f75-942D-087DE603E3EA}{D76B9641-3288-4f75-942D-087DE603E3EA}]’)         

{

            $_.Properties.displayname

        }

    }

}

BenoîtS – Simple and secure by design but business compliant

Un peu de process d'ADMPWD dans ce monde de cloud (5/5)

Je sais très bien qu’au fur et à mesure de cette série de billet, j’ai perdu beaucoup de lecteurs à chaque étape, je m’en excuse. Pour les survivants, c’est la meilleure partie, à savoir comment appeler notre Runbook Orchestrator d’interface avec SCSM depuis SCSM. Pour les autres un petit interlude est nécessaire avant de reprendre et de se dire que je suis loin d’atteindre son niveau pour écrire des tutos pareils!

clip_image002

Vous êtes convaincus maintenant? Doumé, allons-y.

Commençons par les bas-fonds. Si on doit manipuler des objets extérieurs à Service Manager, il faut les référencer dans la CMDB. Orchestrator étant un produit de la gamme System Center, il y a donc un connecteur dans Service Manager. Il faut juste s’assurer que celui-ci a bien importé nos Runbook. Par défaut, il réalise cette opération selon un cycle de 24 heures et importe les Runbook qui ont été "Check-in". Histoire de ne pas attendre, on va lui forcer la main avec un peu de Powershell et quelques Commandlet issus du module de Service Manager.

clip_image004

Cette fois, c’était les dernières commandes Powershell dans ce monde de cloud. Le lien entre Orchestrator et Service Manager se fait au travers de la classe d’objets "Runbook Automation Activity" de la CMDB. On peut constater que tous les Runbook développés sont visibles. Celui qui nous intéresse, c’est celui en charge de l’interface avec SCSM (la seconde version).

clip_image005

Pour ce Runbook, j’ai créé un objet de classe "Runbook Automation Activity" dans la CMDB.

clip_image006

La caractéristique la plus importante pour un "Runbook Automation Activity", c’est la case d’option "Is ready for Automation" qui doit obligatoirement être cochée si on veut voir le Runbook être exécuté.

clip_image008

Lors du processus d’import, SCSM a clairement identifié les paramètres en entrée et en sortie. Dans notre cas, un seul paramètre en entrée nommé "ActivityID". Il faut juste faire le mapping entre un attribut de la CMDB et ce que nous allons passer en paramètre d’entrée à notre Runbook.

clip_image010

J’ai retenu de passer l’identifiant unique (le SC Object GUID) de l’objet "Runbook Automation Activity" qui sera créé lors de l’exécution de la "Service Request".

clip_image012

L’interface avec le Runbook est maintenant terminée. Il faut juste un appelant. Cet appel sera réalisé au travers d’une "Service Request" que nous allons créer sous forme de template.

clip_image013

Un objet "Service Request" est un ensemble d’activité qui sera réalisée. Cela peut contenir des activités de type "Runbook automation Activity", "Review Activity" (validation) ou même "Manual activity"). L’interface principale ne nous apprend pas grand-chose.

clip_image015

Par contre dans l’onglet "Activity", on retrouve bien notre template d’objet "Runbook Automation Activity" qui sera créé lors de l’exécution de la "Service Request".

clip_image017

Dernier étage, les interfaces. Par soucis de simplification, nous ne parlerons que de "Request Offering".

clip_image018

Une "Request Offering" est l’objet que nous voyons dans le portail. Il fait référence à une "Service Request" mais aussi aux paramètres à passer et l’interface utilisateur à mettre en place.

clip_image020

Passons justement aux saisies demandées par l’utilisateur. Pour notre requête, nous avons juste besoin d’un compte ordinateur que nous allons proposer parmi une liste d’objets issus de la CMDB.

clip_image022

Là je vais perdre du monde (Doumé, …). Qu’est-ce que c’est que la classe Cloud Services Extended Virtual machine (Advanced)? OK, cela aurait été plus simple de choisir la classe "Windows computers" ou "Windows Computers (Advanced)" qui référence les objets ordinateurs du domaine importés dans la CMDB. Oui mais je voulais ne filtrer que les objets déployés avec le Cloud Services Process Pack. En plus, je voulais pouvoir identifier le propriétaire de ces machines virtuelles.

clip_image024

Pour mon filtre, j’ai retenu de n’afficher que les systèmes qui :

  • Ont été installé à l’aide du Cloud Services process Pack (donc provisionnés via une requête et associé à un contrat lui-même lié à un tenant pour pouvoir facturer)
  • Sont référencés comme actifs (donc non archivés dans la library de SCVMM)
  • Et dont l’utilisateur propriétaire correspond à celui qui exécute la requête dans le portail

C’est là qu’on découvre la magie du token. Merci à l’équipe produit SCSM pour ce billet qui a éclairé beaucoup de choses.

clip_image026

Le filtre est en place, ne reste plus qu’à définir les informations qui seront affichées à l’utilisateur dans le portail SCSM concernant cette classe d’objets, le nom de cet objet sera amplement suffisant.

clip_image028

On comprend l’intérêt des deux premières options, par contre, c’est un peu plus complexe pour les deux autres. C’est un peu plus subtil. Attention, c’est uniquement si vous voulez comprendre tous les mécanismes. Pour faire plus court, voilà les parties intéressantes:

  • Add user-selected objects to template object as related items: If this field is checked, the portal will create System.WorkItemRelatesToConfigItem or System.WorkItemRelatesToWorkItem relationship instances to link each of the objects selected by the user to the target instance specified in the drop-down immediately beneath the check box. The appropriate relationship is selected based on the type of object being displayed in the Query Results control. The instances available in the drop-down include the target template instance selected for the Request Offering and any of its embedded activities.
  • Add userselected objects to template object as affected configuration items: This field is enabled only if the objects being displayed in the Query Results control inherit from Configuration Item (System.ConfigItem). If this field is checked, the portal will create System.WorkItemAboutConfigItem relationship instances to link each of the objects selected by the user to the target instance selected in the drop-down. The instances available in the drop-down include the target instance and any of its embedded activities.

clip_image030

Félicitations à ceux qui sont arrivés jusque-là. Je sais parfaitement que vous n’êtes pas si nombreux que cela. Maintenant que vous avez un exemple concret de ce qu’on peut faire avec Service Manager, il se peut que vous en vouliez encore plus, voire même tenter d’étendre à d’autres briques du système d’information. Si c’est le cas, c’est normal, vous commencez à penser industrialisation du SI. Vous vous rapprochez des nuages.

BenoîtS – Simple and Secure by design but business compliant

Un peu de process d'ADMPWD dans ce monde de cloud (4/5)

C’est l’heure des sujets qui piquent mais juste un peu. Mais pourquoi donc ne pas tout faire dans un seul et unique Runbook? C’est une bonne question. Ça m’a pris comme ça. Plus sérieusement, c’est un choix personnel de toujours séparer :

  • Les Runbook d’interfaces avec SCSM
  • Les Runbook au cœur de l’activité
  • Les Runbook "Sub-routines" que j’utilise

De cette manière on évite le Runbook monstrueux impossible à maintenir. Dans le cas présent, nous avons un Runbook d’interface avec SCSM. Il a pour objectif de :

  • Récupérer les informations en provenance de la CMDB
  • Appeler un ou plusieurs Runbook "Sub-Routines"
  • Appeler le Runbook au cœur de l’activité
  • D’appeler un Runbook d’interface avec SCSM permettant de remonter des informations dans la Service Request

Mon Runbook d’interface doit récupérer les paramètres dont a besoin le Runbook que l’on va appeler et retourner un statut suite à l’exécution. Plongeons dans ce Runbook qui finalement n’est pas si compliqué qu’il n’y parait :

clip_image002

Pour ceux qui avaient esquivé la série A la surface d’un service dans System Center Service Manager, petit rappel. D’un point de vue technique, Service Manager va créer un objet "Runbook Automation Activity" qui va référencer les paramètres à passer sous forme de liaisons. Nous allons passer l’identifiant unique de cet objet en paramètre du Runbook ("SC Object Guid" le bien nommé). Ce choix me permettra d’utiliser l’IDP SCSM d’Orchestrator pour illustrer quelques manipulations de base de la CMDB. Donc revenons à notre Runbook d’interface. Il commence par une activité qui référence notre seul et unique paramètre.

clip_image004

Pour les plus curieux, voilà un objet "Runbook Automation Activity" ainsi que l’identifiant unique de l’objet RBA qui est passé en paramètre. Le Fameux "SC Object Guid" que nous allons revoir souvent.

clip_image006

Justement cet identifiant, nous allons l’utiliser immédiatement pour identifier notre paramètre, à savoir la machine virtuelle pour laquelle nous allons demander de révéler le mot de passe Administrateur. On va exploiter le potentiel de la CMDB. Au lieu de simplement coder le nom de la VM "en dur" dans l’objet "Runbook Automation Activity", on exploite les relations entre les objets et c’est plus classe. Dans le cas présent, lors de la création de l’objet "Runbook Automation Activity", une relation a été créée avec le paramètre qui n’est autre qu’un objet de la classe "Virtual Machine".

clip_image008

A noter que je suis parti du principe qu’il n’y avait qu’une seule relation, donc un seul paramètre. Si on autorisait la sélection multiple dans la "Request Offering" de SCSM, il faudrait en tenir compte pour traiter chaque cas. Dans le cas qui nous occupe, j’exploite un attribut de la relation pour déterminer qu’il n’y a qu’un seul objet en sortie de cette activité. Si ce n’est pas le cas, le Runbook sort en erreur.

A ce stade, nous avons la référence d’un objet de la classe "Virtual Machine", allons chercher des informations sur cet objet dans la CMDB avec l’activité "Get Object". <Mode Astuce SCSM ON> Nous faisons référence à un paramètre en relation avec une autre classe. Donc l’identifiant unique que nous cherchons (le "SC Object GUID") est référencé dans l’attribut Related Objet GUID" <Mode Astuce SCSM Off>.

clip_image010

Nous avons tous les paramètres ou presque. Au final, on doit dévoiler le mot de passe administrateur de la machine virtuelle que nous venons d’identifier. Encore faut-il savoir à qui envoyer un mail. Facile me direz-vous, dans la "Service Request", on a nécessairement cette information dans l’attribut "Created by user". C’est vrai, nous y reviendrons. Pour l’instant, nous allons appeler un Runbook qui va se charger pour nous de retrouver cette information à l’aide de l’identifiant de l’objet "Runbook Automation Activity" passé en paramètre.

clip_image012

Si on arrive ici, c’est qu’on a toutes les informations pour appeler le Runbook que nous avons développé dans le billet précédent. En retour, le Runbook nous retournera une variable indiquant le bon déroulement de l’exécution (OK, NOK).

clip_image014

Cette variable est importante car à ce stade de notre Runbook nous devons prendre une décision. Si le service a été correctement rendu, alors nous pouvons poursuivre dans une branche (OK). Si ce n’est pas le cas, c’est l’autre branche (NOK). Dans les deux cas, on appelle un Runbook qui va se charger de remonter un statut dans la "Service Request" avant de terminer le Runbook d’interface avec SCSM.

clip_image016

Maintenant que les grandes lignes sont tracées, penchons-nous sur les petits détails pour comprendre deux tours de magie utilisés. Commençons par comprendre comment on retrouve l’utilisateur initiateur de la "Service Request" dans SCSM. La méthode la plus basique aurait été de passer l’information en paramètre (d’où la V1 de la "Request Offering"). Or, cette information est présente dans la CMDB, encore faut-il faire son chemin pour y accéder. J’ai volontairement créé un Runbook dédié pour cela (Runbook "Sub-routine"). Ici encore, c’est une histoire de relation mais avec un objet de la classe "Service Request", lequel a lui-même une relation avec un objet de la classe "User" que nous allons identifier pour enfin en extraire son adresse de messagerie.

clip_image018

Je ne détaille plus le pourquoi mais nous repartons de notre identifiant unique de l’objet "Runbook Automation Activity", c’est notre point d’entrée dans la CMDB.

clip_image020

Cette fois, la relation concerne un objet de la classe "Service Request". Sauf que sur ma maquette qui a déjà beaucoup vécu, j’ai intégré quelques personnalisations de CMDB. J’utilise donc mon extension de la classe "Service Request" que j’ai nommé "My Service Request".

clip_image022

On remarquera que j’ai volontairement fait l’impasse sur la gestion d’erreur. Il y a forcément un objet de la classe "My Service Request" que nous allons identifier à l’aide de son identifiant "SC Object Guid" référencé dans l’attribut" Related Object Guid". Ça commence à rentrer maintenant?

clip_image024

Etage "Service Request", direction "Created user". Ici encore, c’est une relation avec un objet de la classe "Active Directory User". Jusqu’ici, rien de bien compliqué.

clip_image026

C’est en sortie de cette activité que cela se complique (Ce n’est pas la faute à Powershell). En retour, nous n’avons pas un objet en relation mais deux. On s’en rend compte lors qu’on regarde le détail de l’exécution de l’activité. Problème, comment identifier l’un ou l’autre.

clip_image028

C’est une bonne piste, maintenant, faut faire le tri. Pour cela, il a été nécessaire d’utiliser le débogueur pour clairement identifier les différents "Related Object Guid" en question. Avec un peu de persévérance, on finit par comprendre la différence :

clip_image030

Nous avons deux relations :

  • La première pour l’utilisateur qui a créé la requête
  • La seconde pour l’utilisateur à qui on a affecté la requête (notion d’analyste dans SCSM)

Ce qui nous intéresse, c’est le premier. Pour filtrer uniquement celui-ci, nous allons jouer sur les propriétés "Include" et Exclude" de la relation. Même les liaisons entre les activités ont des propriétés que l’on peut configurer (sic). J’ai donc indiqué que nous ne retenons les objets que si l’activité "Get-Relation" s’est déroulée avec succès ou que celle-ci nous désigne bien un attribut dont la valeur est "Created By user".

clip_image032

Au contraire, je veux exclure, tout objet pour lequel la valeur de ce même attribut n’est pas celle attendue.

clip_image034

La gestion des propriétés "include" et "exclude" est importante dans Orchestrator car c’est grâce à elles que l’on va introduire la gestion d’erreur au sein de nos Runbooks. Il faut donc s’assurer de bien les configurer. Dès lors qu’on est assuré d’avoir la référence au bon objet, allons rechercher ses caractéristiques avec une activité "Get-Object".

clip_image036

Nous avons maintenant toutes les informations pour retourner l’adresse mail de l’utilisateur créateur de la "Service Request" en résultat de Runbook. On notera que si cette information est dans la CMDB, c’est que le connecteur Active Directory en a importé l’objet et la majeure partie de ses propriétés.

Second tour de magie, utilisé : La mise à jour de la "Service Request" en fonction du résultat du Runbook. C’est ce qui permettra d’informer l’utilisateur que sa requête a été traitée avec succès. Le cas échéant d’indiquer l’erreur rencontrée. Vous reprendrez bien un petit Runbook pour la route? Sans Powershell ajouté!

clip_image038

Notre Runbook attend deux paramètres en entrée, à savoir l’identifiant du Runbook Automation Activity qui sera notre point de départ pour remonter vers la "Service Request" ainsi que l’information que nous allons inscrire comme résultat de la "Service Request".

clip_image040

On ne change pas une méthode qui gagne en recherchant l’objet "Service Request" en relation avec notre objet "Runbook Automation Activity".

clip_image042

Je sais qu’il y a nécessairement qu’une seule relation, donc pas la peine de tester, allons à l’essentiel en mettant à jour objet "Service Request" dans la CMDB. La mécanique est maintenant rodée, on va juste passer un peu de temps sur les attributs que l’on met à jour.

clip_image044

Pour le second, rien de bien sorcier, c’est du texte qui est issu d’un retour du Runbook qui a révélé le mot de passe Administrateur de notre serveur. Pour le premier par contre, c’est un peu plus subtile. Dans la "Service Request", cet attribut n’accepte que des valeurs définies dans une liste SCSM (encore un objet dans la CMDB) nommée "Service Request Implementation results".

clip_image046

C’est ce contenu qu’Orchestrator nous propose. J’ai donc deux Runbooks. Le premier pour indiquer que tout s’est déroulé avec succès et le second pour indiquer qu’une erreur est survenu lors de l’exécution. Au passage deux piqures de rappel sur le sujet pour éviter les déconvenues suite à une installation malencontreuse d’Orchestrator sur un système autre qu’US :

Vous lisez encore? Bien, reste plus maintenant qu’à mettre tout cela en musique dans Service Manager. Courage, plus qu’un seul billet à supporter.

BenoitS – Simple and Secure by Design but business compliant

Un peu de process d'ADMPWD dans ce monde de cloud (1/5)

ADMPWD, répond à une problématique bien connue. Maintenant qu’on a l’essentiel, passons à l’étape suivante : construire des processus autour. Historiquement, on ne voulait jamais donner le compte administrateur local de nos stations de travail/serveur car, il risquait d’être identique sur un grand nombre de serveurs. Avec ADMPWD, on a résolu ce problème. Voyons comment faire en sorte de pouvoir communiquer le mot de passe Administrateur local d’un système en s’assurant que cette information ne soit valable pour une durée limitée dans le temps (vous avez dit magie?).

Dans l’idée, c’est de faire appel à ADMPWD pour lui imposer de changer de mot de passe plus rapidement que ce qu’il a été prévu. De cette manière, même si on communique le mot de passe que nous avons extrait de l’annuaire Active Directory, sa durée de vie sera limitée. Dans le cadre de ce billet, j’ai volontairement retenu une durée de 24 heures. Le composant ADMPWD installé sur mes serveurs réévalue le besoin de changer le mot de passe du compte administrateur local selon les conditions suivantes :

  • Cycliquement toutes les 90/120 minutes
  • manuellement en exécutant Invoke-GPUPDATE / GPUPDATE.EXE
  • Au démarrage du système d’exploitation

Donc en configurant une date d’expiration à 24 heures , nous sommes presque assurés qu’au bout de 24heures + 120 minutes le processus de rafraichissement des stratégie de groupe aura eu lieu et ADMPWD réalisé le changement de mot de passe. Et comme la sécurité n’est rien sans de bons processus pour l’encadrer, je n’ai pas résisté à la tentation de développer une “Request Offering” SCSM pour : 

  • Révéler le mot de passe administrateur local d’un serveur
  • En s’assurant que ce mot de passe ne soit utilisable que pendant une période de 24 heures
  • Que le mot de passe soit communiqué au demandeur par mail

Qui dit SCSM, dit obligatoirement Orchestrator et Powershell, le tiercé gagnant. Les bases sont posées voyons comment le mettre en musique. Pour simplifier l’approche et la lecture, c’est non pas un billet mais plusieurs qui seront nécessaires. Commençons par les fondations avec le Runbook chargé des opérations techniques :

Pour ceux qui ont suivi la série "A la surface d’un service dans System Center Service Manager", on est dans la même approche, peut-être un peu plus simple, mais ça c’est by design. En plus, c’est toujours Secure”".

BenoîtS – Simple and Secure by Design but Business compliant

Un peu de process d'ADMPWD dans ce monde de cloud (3/5)

On a plongé tête baissée dans Orchestrator. Pourtant, avant de de se perdre dans les méandres d’Orchestrator et SCSM, ce serait bien de comprendre à quoi cela va ressembler à la fin. Au passage, cela permettra d’introduire quelques sujets de fonds. Donc billet un peu plus léger pour cette fois.

Pour cette série de billets, j’ai fait bien plus simple que pour la série "A la surface d’un service dans System Center Service Manager", pas de "Service Offering", donc toutes les Request Offering sont directement accessibles depuis la vue "List view" dans le portail SCSM (j’ai dit léger non?). J’ai nommé ma Request Offering "Disclose local Administrator Password (V2)". Le développement de mon service s’est fait par itération successive. On n’arrive que très rarement au résultat escompté du premier coup.

clip_image002

C’est une étape obligatoire dans le portail SCSM. L’idée générale est de pouvoir communiquer autour de la Request Offering avec les différents éléments qui peuvent s’y rapporter (articles de la bases de connaissance associés, autres “Request Offering” proposés dans le même Service Offering, …). Pour faire simple, la WebPart est tel que, on n’y changera rien.

clip_image004

Nous arrivons au cœur de la Request Offering. Pour quel serveur va-t-on demander de dévoiler le mot de passe administrateur local? On verra plus tard que cette liste de serveurs n’est pas construite par hasard. Ne sont affichés que les serveurs que j’ai commandé dans mon Cloud Services Process pack. Dans la construction de ma "Request Offering", j’ai retenu qu’on ne puisse sélectionner qu’un seul serveur. D’un point de vue technique il est bien entendu possible d’autoriser une sélection multiple, c’est juste coté Orchestrator que cela va se compliquer (billet simple).

clip_image006

Par contre, on ne voit pas encore comment cette liste a été construite. Toutes ces machines virtuelles sont-elles les miennes? Allons voir les propriétés de l’objet sélectionné. Ce que nous allons voir est la vue consolidées des informations contenues dans la CMDB de Service Manager. Déjà premier constat, l’objet présente des informations en provenance de plusieurs classes d’objets, dont "VirtualMachines". L’objet sélectionné est bien un objet de la classe "virtualmachine" mais aussi un objet de la classe "Cloud Services Virtual Machine". Cette classe d’objets a été introduite par le Cloud Services Process Pack pour assurer la mise à disposition et gestion de machines virtuelles. L’intérêt est de pouvoir identifier le propriétaire de la machine virtuelle.

clip_image008

Ce qu’on peut aussi remarquer ici, ce sont les éléments de configuration issus de la CMDB qui sont en relation avec mon objet sélectionné.

clip_image010

Le premier désigne le contrat de souscription de ressources auquel est associé la machine virtuelle (Il faut bien être capable de tracer/facturer l’utilisation des ressources). C’est un élément apporté par le Cloud Services Process Pack.

clip_image012

Mais aussi le propriétaire associé à la ressource. C’est cette information que nous utiliserons lors de l’intégration avec SCSM.

clip_image014

En passant par la relation, je retrouve le propriétaire associé à l’objet. Pour finir, une étape obligatoire du portail SCSM pour rappeler les choix de l’utilisateur avant de commencer le traitement de la "Request Offering".

clip_image016

Maintenant, plus moyen de revenir en arrière, le traitement a commencé. Dans SCSM les choses sérieuses commencent. La "Request Offering" que nous avons appelé fait référence à une "Service Request" qui elle-même référence une ou plusieurs activités à traiter. Dans notre cas, il n’y en a qu’une seule et c’est même une activité de type "Runbook Automation Activity".

clip_image018

Le portail SCSM permet de suivre l’avancement de notre "Request Offering". Dans l’illustration ci-dessous, notre requête est indiquée comme étant en cours de traitement, et qu’elle ne fait appel qu’à une seule activité, plus précisément une "Runbook Automation Activity". Cette dernière indique un état "In Progress". Ce sont donc deux objets qui ont un statut bien distinct (Une "Service Request" peut faire appel à plusieurs "Activity").

clip_image020

Quelques temps plus tard, le "Runbook Automation Activity" indique un état "Completed", tout comme la "Request Offering". C’est un sujet que nous allons revoir plus tard.

clip_image022

Passons de l’autre côté pour voir ce que nous ne voyons pas depuis le portail. Lorsqu’on consulte le détail de la "Service Request" générée, on peut constater la présence de notes additionnelles indiquant la date de fin de validité du mot de passe que nous venons de relever. On verra dans le billet suivant que c’est le travail d’un de mes Runbook Orchestrator de remonter cette information au niveau de la "Service Request" ainsi que le bon déroulement ou non des activités réalisées.

clip_image024

Ma maquette étant quelque peu limitées en terme de capacités (32Go de mémoire, on fait plus rien avec ça mon bon monsieur), pas possible de présenter le mail reçu dans un beau client de messagerie. On se contentera de sa version brute de fonderie dans la file d’attente SMTP. Pour faire cela bien, il aurait été nécessaire de mettre en place le connecteur Exchange de SCSM 2012.

clip_image026

Pour les sceptiques, il reste possible d’aller voir ce qui se passe sous la moquette et plus précisément dans l’annuaire Active Directory. Avec le CommandLet Get-ADObject du module Active Directory on est capable de récupérer toutes les informations dont les deux attributs qui nous intéressent :

  • Ms-Mcs-AdmPwd
  • Ms-Mcs-AdmPwdExpirationTime

clip_image028

C’est ce dernier attribut qui va nous intéresser. Comme toutes les dates, elles sont exprimées au format UTC. Il aurait été possible de réaliser cette conversion directement, sans l’étape intermédiaire mais cela rend le code un peu plus complexe (Powershell oui mais simple, j’avais promis).

Jusque-là je ne dois avoir perdu personne. Pour le prochain billet, ça va se corser puisqu’on va aborder le sujet de l’intégration SCSM avec Orchestrator (sic). Courage, le pire est à venir.

BenoîtS – Simple and Secure by Design but Business compliant.

Un peu de process d’ADMPWD dans ce monde de cloud (2/5)

Après le teaser, rentrons directement dans le vif du sujet avec le Runbook au cœur de tout cela. Une activité de début et trois activités de fin pour traiter :

  • Le compte ordinateur qui n’existe pas
  • Le succès de l’opération
  • Une erreur dans le traitement

Minimaliste certes mais avec une gestion d’erreur quand même.

clip_image002

Notre Runbook a un début. Cette activité permet de référencer les paramètres qui sont attendus pour l’exécution. Dans notre cas, nous avons besoin :

  • De l’ordinateur pour lequel on désire révéler le mot de passe
  • De l’adresse de messagerie à laquelle on doit envoyer le mot de passe

clip_image004

Pour pouvoir accéder au mot de passe, nous allons utiliser une activité de l’Integration Pack Active Directory et rechercher un objet bien particulier et retourner toutes les informations le concernant (d’où le « Return Distinguished Names Only » configuré à « False »).

clip_image006

Pour cela encore faut-ll préciser quel objet désire t’on rechercher. Dans notre cas, le filtrage s’effectue sur le « Common Name » en utilisant le paramètre passé en paramètre notre Runbook.

clip_image008

C’est maintenant que ça commence à piquer. Une petite pointe de Powershell. Le problème, c’est que l’éditeur proposé par l’activité Powershell n’est pas des plus ergonomiques. <Mode capitaine Haddock activé>. Donc à la demande générale quelques lignes de Powershell dans ce monde de clouds. Premier truc, je n’ai volontairement pas utilisé les commandlet Powershell livrées avec le composant ADMPWD. Pourquoi? Pour rester indépendant. En plus, on peut simplement exploiter le CommandLet ActiveDirectory et arriver au même résultat. Enfin, on s’évite de gérer le problème de Framework Dot.Net 4.0 dans Orchestrator avec le module ADMPWD. <Mode capitaine Haddock désactivé>.

clip_image010

Le script se décompose en deux parties. La première réalise un invoke-command pour récupérer le contenu de l’attribut « MS-mcs-AdmPwd ». C’est lui qui contient le mot de passe. Pour ceux qui ont lu le billet « ADMPWD une solution de gestion du mot de passe administrateur local de vos systèmes Windows », cet attribut ne m’est accessible que par ce que le compte de service utilisé par Orchestrator est membre des groupes de sécurité nécessaires.

clip_image012

En retour d’exécution, on obtient le mot de passe demandé. C’est une information que nous allons passer à l’activité suivante du Runbook. La seconde partie du script va elle configurer une nouvelle date d’expiration dans l’attribut « ms-mcs-AdmPwdExpirationTime ». Cette information sera retournée comme second paramètre de l’activité Powershell. Pour rappel, dans mon cas, j’ai ajouté 24 heures à la date courante.

clip_image014

Si on veut récupérer deux paramètres, encore faut-il les avoir préalablement déclarés dans l’activité Powershell.

clip_image016

Le job est fait, reste plus qu’à communiquer l’information. Pour des raisons de simplicité, j’ai utilisé l’activité « Send Mail » disponible nativement qui va générer le message correctement formaté à destination de l’adresse mail indiquée en paramètre de notre Runbook.

clip_image018

Reste plus qu’à référencer le serveur de messagerie à utiliser ainsi que l’adresse mail à utiliser pour envoyer le message. Ma maquette étant assez limitée, j’ai volontairement installé le moteur SMTP de IIS sur mon serveur Orchestrator.

clip_image020

Job is done. A ce stade, si tout s’est bien déroulé, on arrive à l’activité « success », laquelle retourne « OK » comme valeur de retour du Runbook. Voilà pour la partie simple.

A partir de maintenant, on s’attaque au gros du sujet. Jusque-là je ne pense avoir perdu personne. Ce n’était que quelques lignes de Powershell et une pointe d’Orchestrator dans ce monde de cloud. Il restera un peu de Powershell dans la suite des billets mais juste quelques commandes isolées. Maintenant, direction les nuages avec SCSM et Orchestrator.

BenoîtS – Simple and Secure by Design but Business compliant