PI Services

Le blog des collaborateurs de PI Services

Active Directory - Comment exporter la chaîne de certification d'un contrôleur de domaine ?

Certaines applications pour pouvoir voir communiquer à travers des protocoles SSL sécurisés telles que LDAPS (port 636) et GC over SSL (3269) doivent avoir l'ensemble de la chaîne de certification d'un certificat d'un contrôleur de domaine (DC). L'export des certificats de la chaîne de certification ainsi que la constitution du certificat finale peut se faire à travers les outils natifs de Windows Server.

Exporter un certificat depuis la console de certification

L'ensemble des manipulations décrites peuvent se faire à distance depuis la console de certificat, mais dans un souci de clarté, les actions décrites sont réalisés directement depuis un contrôleur de domaine.

Depuis une invite de commande, entrer la commande suivante

certlm #cmdlet qui permet d'ouvrir la console de certificats avec le contexte de l'ordinateur local, donc ici le contrôleur de domaine

 

Déployer le dossier Personal puis Certificates

 

Identifier le certificat qui sert à l'authentification des clients du contrôleur de domaine :

  • La colonne Issued To contient habituellement : le FQDN du contrôleur de domaine
  • La colonne Intended Purposes contient habituellement : Client Authentication, Server Authentication
  • La colonne Certificate Template contient habituellement : Domain Controller

 

Faire un click droit sur le certificat > All Tasks > Export...

 

L'utilitaire d'exportation de certificat se lance, choisir de ne pas exporter la clé privée : No, do not export the private key

 

Choisir un format Base-64 encoded X.509 (.CER)

 

Choisir un dossier de destination dans lequel exporter le certificat



Finir l'export du certificat via l'utilitaire

Le certificat du contrôleur de domaine a été exporté, il faut désormais exporter les autres certificats de la chaîne de certification : le certificat racine et les certificats intermédiaires 

 

Exporter chaque certificat de la chaîne de certification

De retour dans la console certlm, faire un click droit sur le certificat > All Tasks > Export...


 

Ouvrir l'onglet Certification Path, l'ensemble des certificats de la chaîne de certification est listé, le premier de la liste étant le certificat racine, le dernier le certificat du contrôleur de domaine, et les certificats entre les deux sont les certificats intermédiaires.

Cliquer sur le certificat racine puis sur View Certificate, le certificat racine s'affiche alors dans son propre onglet, cliquer sur l'onglet Details puis Copy to File...

Le même utilitaire d'export de certificat s'affiche, compléter l'exporter du certificat racine avec les mêmes options que pour le certificat du contrôleur de domaine en donnant un nom explicite au certificat pour pouvoir le différencier.

Exporter de la même façon l'ensemble des certificats intermédiaires.

 

Assembler les certificats de la chaîne de certification

Une fois l'ensemble des certificats de la chaîne de certification exportés, il faut les assembler dans un seul certificat.

  • Créer un fichier texte et remplacer l'extension .txt par .cer, dans cet exemple, on l'appellera DCCertificateFullChain.cer 
  • Ouvrir le certificat racine avec un éditeur de texte comme Notepad et copier coller le contenu dans le certificat jusqu'alors vide DCCertificateFullChain.cer
  • Dans le fichier DCCertificateFullChain.cer faire un saut de ligne après ----END CERTIFICATE----
  • Ouvrir chaque certificat intemédiaire et les copier coller à la suite du certificat racine dans le fichier DCCertificateFullChain.cer en respectant le saut de ligne
  • Finir par le certificat du contrôleur de domaine

Les certificats doivent se suivre comme suit :

 

Le certificat avec l'ensemble de la chaîne de certification est prêt.

 

Active Directory Federation Services - identifier rapidement la source d'un problème avec ADFS diagnostic analyser

Active Directory Federation Services ou ADFS est un service cœur de tout système d'informations. Les problèmes qui peuvent survenir entraînent la plupart des temps des interruptions de services directement visibles par les utilisateurs finaux. Il est alors essentiel d'identifier et de résoudre la panne au plus vite. ADFS diagnostic analyser est un outil produit par Microsoft qui permet d'analyser très simplement la conformité d'une ferme ADFS.

Installer le module PowerShell ADFSToolbox

ADFSToolbox est un module PowerShell qui permet d'exporter la configuration de serveurs ADFS. Il est conseillé de faire l'installation du module sur un serveur de la ferme ADFS pour s'affranchir des problématiques de communications réseaux. 

L'installation du module se fait via la commande PowerShell suivante :

Install-Module -Name ADFSToolbox -Force


Si la version ciblée d'ADFS est la version 2.1 ou inférieur, il faut utiliser la commande PowerShell suivante :

Install-Module -Name ADFSToolbox -RequiredVersion 1.0.13 -Force 

 

Les versions d'ADFS sont liées à la version de Windows Server de la machine virtuelle, ADFS 2.1 correspond à Windows Server 2012.

Si le module ne peut pas être installé en raison de problème de connectivité internet, l'article suivant explique comment procéder pour contourner cette restriction : Active Directory - Comment installer un module PowerShell sans connexion internet ?

 

Exporter la configuration de serveurs ADFS via le module PowerShell ADFSToolbox

Une fois le module installé, ouvrir une fenêtre PowerShell en tant qu'administrateur avec un compte administrateur du serveur ADFS et entrer la commande :

Import-Module -Name ADFSToolbox -Force #pour les versions ADFS 3.0 et suivantes

Import-Module -Name ADFSToolbox -RequiredVersion 1.0.13 -Force #pour les versions d'ADFS 2.1 et précédentes

Pour exporter la configuration d'un serveur ADFS, enter la commande PowerShell suivante :

Export-AdfsDiagnosticsFile -ServerNames @("adfs1.contoso.com", "adfs2.contoso.com") #remplacer adfs1.contoso.com et adfs2.contoso.com par les FQDN des serveurs ADFS, d'autres serveurs ADFS peuvent être ajoutés en les ajoutant à la suite des parenthèses

Export-AdfsDiagnosticsFile -ServerNames adfs1.contoso.com" #la commande peut être raccourci si on ne souhaite requêter qu'un seul serveur

 

Dans le cas d'un serveur Web Application Proxy ou WAP qui n'est pas joint au domaine Active Directory, entrer la commande PowerShell suivante depuis une fenêtre PowerShell locale au serveur (installation du module comme expliqué précédemment nécessaire) :

Export-AdfsDiagnosticsFile

 

Le fichier généré se trouve dans le dossier C:\Windows\System32 et se nomme AdfsDiagnosticsFile-[DateDuJour] ou [DateDuJour] correspond à l'heure et à la date à laquelle l'export a été réalisé.

 

Analyser l'export de la configuration ADFS avec ADFS diagnostic analyser

L'URL d'ADFS diagnostic analyser est la suivante : adfshelp.microsoft.com/DiagnosticsAnalyzer/UploadFile

Cliquer sur le point 3 - Diagnostic Analyzer > Select (choisissez le fichier AdfsDiagnosticsFile précédemment généré) > Upload a diagnostic file

Plusieurs tests sont effectués, focalisez vous sur les erreurs et notamment celles qui sont simples à résoudre, par exemple une expiration de certificat :

Active Directory - Comment installer un module PowerShell sans connexion internet ?

Pour limiter la surface d'attaque d'un système d'information, il est courant que les serveurs n'aient pas de connexions internet. C'est un problème pour l'installation de modules PowerShell via la commande Install-Module qui va utiliser une URL internet pour télécharger ses sources. Comment peut-on alors faire pour récupérer ces précieux modules ?

 

Les messages d'erreurs type lorsque le serveur n'est pas autorisé à récupérer un module depuis internet

Message d'erreur type pour Install-Module

 

Message d'erreur type pour Get-PSRepository

 

On peut essayer de réinitialiser les paramètres par défaut du répertoire PowerShell avec la commande Register-PSRepository - Default mais une nouvelle saisie de Get-Repository démontre que rien n'a été changé.

 

Il existe également d'autre paramètres pour la commande Register-PSRepository qui nous permettent par exemple de spécifier nous-mêmes les URL de repository PowerShell mais quel que soient les paramètres entrés sans connexion internet la connexion ne sera jamais établie.

 

Sauvegarder le module PowerShell depuis un ordinateur avec une connexion internet

La commande Save-Module permet de sauvegarder un module PowerShell dans un dossier défini.

Un dossier du module téléchargé est alors dans le dossier spécifié.

Le dossier du module PowerShell doit être ensuite copié sur le serveur qui n'a pas de connexion internet. Le dossier cible doit être celui par défaut pour l'installation de module PowerShell ou s'il a été changé ce dernier.

 

Pour trouver les répertoires de modules PowerShell la variable d'environnement $env:PSModulePath peut être utilisé.

 

Habituellement, il est préférable que le module soit disponible à l'ensemble des utilisateur du serveur, le dossier C:\Program Files\WindowsPowerShell\Modules va donc être utilisé comme cible pour la copie du module PowerShell.

 

La commande Import-Module peut ensuite être utilisée pour chargé le nouveau module dans une session PowerShell. 

Active Directory - Comment déléguer l'affichage d'un mot de passe LAPS d'un ordinateur supprimé ?

LAPS ou Local Admin Password Solution est une solution développée par Microsoft qui permet de gérer un mot de passe local de chaque ordinateur d'un domaine Active Directory de façon individuel et autonome. Cet article ne couvrira pas la mise en place de LAPS ni son modèle de délégation, mais se focalisera sur la délégation de la récupération d'un mot de passe LAPS d'un objet ordinateur supprimé.

 

Important : la corbeille Active Directory doit être activée pour récupérer le mot de passe LAPS d'un ordinateur supprimé.

 

Les méthodes par défaut pour lire le mot de passe LAPS d'un ordinateur supprimé

Par ordre de simplicité, les méthodes classiques sont :

  1. Utiliser la console Active Directory Administative Center
  2. Utiliser la cmdlet PowerShell Get-ADObject avec le paramètre -IncludeDeleteObjects
  3. Utiliser l'utilitaire LDP.exe

Pourquoi ne pas utiliser une de ces méthodes pour lire les mots de passe LAPS des ordinateurs supprimés ? Parce que les droits nécessaires sont Domain Admin. Seul un nombre restreint d'administrateurs doit être membre de ce groupe à haut privilège.

 

 

Déléguer la lecture du mot de passe LAPS d'un ordinateur supprimé

Les tâches suivantes doivent être réalisées avec un utilisateur membre du groupe Domain Admin

 

1. Vérifier que l'utilisateur à la possibilité de voir et modifier les objets dans la corbeille AD

Dans une invite de commande exécuter en tant qu'administrateur, saisir la commande suivante :

dsacls "CN=Deleted Objects,DC=contoso,DC=intern" #Les mots contoso et intern sont à remplacer par le domaine à requêter

#Si le message suivant apparaît, les droits actuels de l'utilisateur sont insuffisants

Insufficient access rights to perform the operation.

The command failed to complete successfully.

 

 

Si le message précédent s'affiche et donc que les permissions ne s'affichent pas, il faut s'approprier la propriété du container Deleted Obects

dsacls "CN=Deleted Objects,DC=contoso,DC=intern" /takeownership #commande qui permet de devenir le propriétaire du container Deleted Objects

#Les permissions s'affichent alors, voici un exemple de permission

Owner: CONTOSO\Domain Admins
Group: NT AUTHORITY\SYSTEM

Access list:
{This object is protected from inheriting permissions from the parent}

Allow BUILTIN\Administrators          SPECIAL ACCESS
                                      LIST CONTENTS
                                      READ PROPERTY
Allow NT AUTHORITY\SYSTEM             SPECIAL ACCESS
                                      DELETE
                                      READ PERMISSONS
                                      WRITE PERMISSIONS
                                      CHANGE OWNERSHIP
                                      CREATE CHILD
                                      DELETE CHILD
                                      LIST CONTENTS
                                      WRITE SELF
                                      WRITE PROPERTY
                                      READ PROPERTY

 

 

 

2. Déléguer la lecture des mots de passe LAPS qui se trouvent dans la corbeille AD

Dans une invite de commande exécuter en tant qu'administrateur, saisir la commande suivante :

dsacls "CN=Deleted Objects,DC=contoso,DC=intern" /G CONTOSO\AD-GROUP-LAPS-DELETED-OBJECTS-READ:LCRP # commande qui permet de donner au groupe AD-GROUP-LAPS-DELETED-OBJECTS-READ les autorisations nécessaires pour lire les mots de passe LAPS des objets supprimés LC = list content et RP = read property

# ces permissions sont alors ajoutés à l'access list qui s'affiche

Allow CONTOSO\AD-GROUP-LAPS-DELETED-OBJECTS-READ
                                      SPECIAL ACCESS
                                      LIST CONTENTS
                                      READ PROPERTY

 

Remarique : il est nécessaire de créer le groupe AD-GROUP-LAPS-DELETED-OBJECTS-READ avant de taper la commande ci-avant, le nom du groupe peut être différent. 



3. Lire le mot de passe LAPS d'un objet ordinateur dans la corbeille AD

Les méthodes habituelles pour lire le mot de passe LAPS tel que LAPS UI ou la console Active Directory Users and Computers ne fonctionnent que sur les ordinateurs présents dans l'Active Directory, il est ainsi recommandé d'utiliser la cmdlet PowerShell Get-ADObject, par exemple :

Get-ADObject -Filter 'msds-LastKnownRDN -like "NameOfTheDeletedComputer"' -IncludeDeletedObjects -Properties ms-mcs-admpwd | Select ms-mcs-admpwd # il faut remplacer NameOfTheDeletedComputer par le nom de l'ordinateur dont le mot de passe LAPS doit être récupéré

# le mot de passe LAPS s'affiche en clair

 

Remarque : l'utilisateur qui doit récupérer le mot de passe de l'objet ordinateur supprimé doit être membre du groupe auquel la délégation a été fournie, dans cet exemple CONTOSO\AD-GROUP-LAPS-DELETED-OBJECTS-READ

Remarque 2 : l'utilisateur qui doit récupérer le mot de passe de l'objet ordinateur supprimé devait déjà avoir la possibilité de lire le mot de passe LAPS de l'ordinateur avant sa suppression

Active Directory - Comment afficher les attributs LDAP non-visibles dans l'utilitaire de délégation Active Directory ?

Cela fait 1 h que vous cherchez dans l'utilitaire de délégation de permission d'Active Directory votre attribut, mais impossible de le trouver ?

Dans un premier temps, il faut savoir que les noms affichés dans cet utilitaire sont sous le format "friendly name" qui n'est pas le nom technique dit "LDAP name". Vous pouvez vous référer à l'article suivant qui fait la correspondance entre les 2 représentations pour les attributs les plus utilisés : tableau de correspondance attribut LDAP et friendly name

Si votre attribut n'est toujours pas visible, c'est parce que par défaut certains attributs sont volontairement cachés.

 

Afficher un attribut caché dans l'utilitaire de délégation Active Directory

 

Pour afficher un attribut caché dans l'utilitaire de délégation Active Directory, il faut se connecter à un contrôleur de domaine (DC) et ouvrir le fichier dssec.dat.

Par défaut, celui-ci se trouve sous C:\Windows\System32

Le fichier est divisé par type d'objet LDAP : utilisateur, ordinateur, etc.

Lorsqu'un attribut est égale à 7 l'attribut n'est pas visible dans l'utilitaire de délégation, il faut modifier la valeur à 0 pour le rendre visible.

 

Exemple sur l'attribut "st" dont le friendly name est "State/Province"

Avant :

 

Après :

 

Remarque : les modifications dans le fichier dssec.dat ne sont pas répliqués sur les autres DC, il faut donc réutiliser le même DC pour de futures modifications ou refaire les mêmes manipulations sur le nouveau DC. À noter que cela ne concerne que l'affichage dans l'utilitaire de délégation, toute modification de permission via l'utilitaire est répliquée sur l'ensemble des DC.

Active Directory - À quels attributs LDAP correspondent les friendly name dans l'AD ?

Vous êtes-vous déjà mordus les doigts dans l'utilitaire de délégation de permissions Active Directory (AD) en essayant désespérément de savoir à quel attribut LDAP correspond tel attribut sous sa forme "friendly" name ?

 

Le tableau de correspondance attribut LDAP et friendly name

 

LDAP_name Friendly_name
c Country Abbreviation
cn Name
co Country
comment Comment
company Company
department Department
description Description
directReports Direct Reports
displayName Display Name
distinguishedName Distinguished Name
division Division
employeeID Employee ID
facsimileTelephoneNumber Fax Number
generationQualifier Generational Suffix
givenName First Name
homeDirectory Home Folder
homeDrive Home Drive
homePhone Home Phone
homePostalAddress Home Address
info Notes
initials Initials
internationalISDNNumber International ISDN Number (Others)
ipPhone IP Phone Number
l City
mail E-Mail Address
manager Manager
memberOf Member Of
middleName Middle Name
mobile Mobile Number
mSDS-PhoneticCompanyName Phonetic Company Name
mSDS-PhoneticDepartment Phonetic Department
mSDS-PhoneticDisplayName Phonetic Display Name
mSDS-PhoneticFirstName Phonetic First Name
mSDS-PhoneticLastName Phonetic Last Name
msRTCSIP-PrimaryHomeServer Office Communications Server
msRTCSIP-PrimaryUserAddress Office Communications Server Address
msRTCSIP-UserEnabled Enabled for Office Communications Server
otherFacsimileTelephoneNumber Fax Number (Others)
otherHomePhone Home Phone Number (Others)
otherIpPhone IP Phone Number (Others)
otherMailbox E-Mail Address (Others)
otherMobile Mobile Number (Others)
otherPager Pager Number (Others)
otherTelephone Phone Number (Others)
pager Pager Number
personalTitle Title
physicalDeliveryOfficeName Office Location
postalCode ZIP/Postal Code
postOfficeBox Post Office Box
primaryInternationalISDNNumber International ISDN Number
primaryTelexNumber Telex Number
samAccountName Logon Name (pre-Windows 2000)
sn Last Name
st State/Province
streetAddress Street Address
telephoneNumber Telephone Number
telexNumber Telex Number (Others)
title Job Title
url Web Page Address (Others)
userPrincipalName Logon Name
userWorkstations Logon Workstations
wWWHomePage Web Page Address

 

Remarque : certains attributs ne sont pas disponibles par défaut dans l'utilitaire de délégation de permission, il faut modifier le fichier dssec.dat sur un contrôleur de domaine

PowerShell - Convertir les signes diacritiques

Un signe diacritique ou diacritique est un élément ajouté à une lettre, par exemple dans la langue française, les biens connus : à, é, ç mais également les ł, ø, ß utilisés dans d'autres langues. La plupart des logiciels ne sont pas capables de traiter les diacritiques correctement ce qui peut avoir pour conséquence une simple gêne utilisateur ou dans le pire des cas des accès non fonctionnels.

Comment alors se débarrasser de ces diacritiques ? Hors de question de les retirer complétement, car ils font partie intégrante des mots, il faut alors essayer de les convertir vers des caractères connus par les logiciels. 

 

La fonction de conversion des diacritiques

function Convert-Diacritic #Fonction qu'il faudra appeler pour convertir le diacritique
{
    [CmdletBinding()] #Déclaration des paramètres qu'il faudra fournir à la fonction pour qu'elle puisse s'exécuter
    Param
    (
        [Parameter(Mandatory=$true)] #Indique que ce paramètre est facultatif
        [ValidateNotNullOrEmpty()] #Indique que ce champ ne peut pas être vide ou null, s'il est obligatoire
        [string]$InputString #Paramètre qui attend la chaîne de caractères qui contient les diacritiques à convertir
    )

    Begin 
    {
        $Return = @{} #Tableau de retour qui contient la chaîne de caractères sans diacritiques
        
        $DiacriticsArray = @{ #Hashtable, aussi appelé tableau de conversion dans ce script, qui contient à droite du signe égal le caractère avec diacritique et à gauche du signe égale, le caractère cible post conversion
            #Par exemple à deviendra a après conversion
            #Pour déterminer vers quel caractère convertir un diacritique, une simple recherche internet peut être utilisé
            a = 'à', 'á', 'â', 'ã', 'ā', 'ă', 'ą'
            aa = 'å'
            ae = 'ä', 'æ'
            c = 'ç', 'ć', 'ĉ', 'ċ', 'č'
            d = 'ď', 'đ'
            e = 'è', 'é', 'ê', 'ë', 'ē', 'ĕ', 'ė', 'ę', 'ě'
            g = 'ĝ', 'ğ', 'ġ', 'ģ'
            h = 'ĥ', 'ħ'
            i = 'ì', 'í', 'î', 'ï', 'ĩ', 'ī', 'ĭ', 'ı', 'į'
            ij = 'ij'
            j = 'ĵ'
            k = 'ķ', 'ĸ'
            l = 'ĺ', 'ļ', 'ľ', 'ŀ', 'ł'
            n = 'ñ', 'ń', 'ņ', 'ň', 'ŋ'
            o = 'ò', 'ó', 'ô', 'õ', 'ō', 'ŏ', 'ő'
            oe = 'ö', 'ø', 'œ'
            r = 'ŕ', 'ŗ', 'ř'
            s = 'ś', 'ŝ', 'ş', 'š'
            ss = 'ß'
            t = 'ţ', 'ť', 'ŧ'
            th = 'þ'
            u = 'ù', 'ú', 'û', 'ũ', 'ů', 'ū', 'ŭ', 'ű', 'ų'
            ue = 'ü'
            w = 'ŵ'
            y = 'ý', 'ÿ', 'ŷ'
            z = 'ź', 'ż', 'ž'
        }
    }

    Process
    {
        $OutputString = $InputString.ToLower() #Transforme tous les caractères majuscules de la chaîne de caractères d'entrée en minuscule
        #Le tableau ne peut convertir que les diacritiques minuscules, cela simplifie également la maintenabilité du tableau de conversion et du code

        foreach ($Letter in $DiacriticsArray.GetEnumerator()) #On parcourt chaque paire lettres/diacritiques du tableau de conversion
        #La méthode GetEnumerator permet de générer deux propriétés Key et Value pour chaque paire du tableau de conversion, ci-après appelé $Letter.Value et $Letter.Key
        {
            $DiacriticsLetter = $Letter.Value #Letter.Value contient l'ensemble des diacritiques d'une paire (ligne) du tableau de conversion
            foreach ($Diacritic in $DiacriticsLetter) #On parcourt chaque diacritique d'une ligne
            {
                if ($OutputString -match $Diacritic) #Si le diacritique qui est en train d'être parcouru est contenu dans la chaîne de caractères d'entrée, le code suivant sera exécuté
                {
                    $OutputString = $OutputString.Replace($Diacritic, $Letter.Key) #Le diacritic qui en train d'être parcouru est remplacé par le caractère cible de conversion contenu dans la propriété $Letter.Key 
                }
            }
        }

        #La boucle précédente va donc répéter les actions décrites précédemment pour chaque paire et chaque diacritique du tableau de conversion

        $Return.outputStringObject = $OutputString #Attribution de la chaîne de caractères sans diacritiques à la variable de sortie
        Return $Return #Retourne la chaîne de caractères sans diacritiques
    }
}

 

Exemple d'utilisation de la fonction de conversion

Le script suivant appelle la fonction de conversion de diacritique lorsque lui-même est appelé

. .\Convert-Diacritic_article.ps1 #Permet de déclarer (dot source) la fonction de conversion de diacritique pour qu'elle puisse être utilisée

$String = Convert-Diacritic -InputString "DébutăîœăßøFin" #Appelle de la fonction de conversion de diacritique et lui passe en paramètre une chaîne de caractères qui contient des diacritiques 

$String.outputStringObject #La chaîne de caractères sans diacritiques est contenu dans la propriété outputStringObject, elle est donc appelée pour afficher le résultat

 

Appel du script précédent

PS D:\A_folder> .\Just_call_me_already.ps1 #Appel du script précédent qui contient l'appelle de la fonction de conversion de diacritique
debutaioeassoefin #Les diacritiques dans la chaîne de caractères ont été convertis selon les règles du tableau de conversion 

 

Remarque : les scripts qui manipulent des diacritiques, tels que les scripts ci-avant, doivent être encodés avec du BOM, par exemple UTF-8 with BOM, sans quoi les diacritiques seront mal convertis par l'IDE (integrated development environment) et empêcheront la bonne exécution du code.

PowerShell - Déchiffrer un mot de passe

Comme vu dans l'article Powershell - Chiffrer un mot de passe la santé de votre équipe de sécurité a été préservé car vos mots de passe sont désormais chiffrés dans vos scripts. Un mot de passe chiffré c'est bien mais comment le déchiffrer pour pouvoir l'utiliser ?

 

La fonction de déchiffrement

function Get-SecureStringFromEncryptedFile #Fonction qu'il faudra appeler pour déchiffrer le mot de passe
{
    [CmdletBinding()] #Déclaration des paramètres qu'il faudra fournir à la fonction pour qu'elle puisse s'exécuter
    Param
    (
        [Parameter(Mandatory=$true)] #Indique que ce paramètre est obligatoire
        [ValidateNotNullOrEmpty()] #Indique que ce champ ne peut pas être vide ou null
        [string]$Name, #Paramètre qui attend le nom de l'utilisateur, il est utilisé pour créer un credential object

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$PwdPath #Paramètre qui attend le chemin complet du fichier qui contient le mot de passe chiffré
    )

    Begin 
    {
        $Return = @{} #Tableau de retour qui contient le mot de passe sous forme de secure string et le credential object généré à partir du nom du compte de service et de son mot de passe
    }

    Process
    {
        $PwdSecureString = Get-Content $PwdPath | ConvertTo-SecureString #Récupére le mot de passe chiffré depuis le fichier txt fourni et le convertit en secure string
        $Return.pwdSecureString = $PwdSecureString #Attribution de la secure string générée dans la variable de sortie de la fonction

        $Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Name, $PwdSecureString #Génére un credential object à partir de l'utilisateur et de son mot de passe
        $Return.credentials = $Credentials #Attribution du credential object générée dans la variable de sortie de la fonction

        Return $Return #Retourne le mot de passe ainsi que la secure string en sortie de la fonction
    }
}

 

 

Exemple d'utilisation de la fonction de déchiffrement

. .\Get-SecureStringFromEncryptedFile_article.ps1 #Permet de déclarer (dot source) la fonction de chiffrement pour qu'elle puisse être utilisée

$Password = Get-SecureStringFromEncryptedFile -Name "Svc-test-01" -PwdPath "D:\A_folder\Svc-test-01_encrypted_password.txt" #Appelle de la fonction de déchiffrement et lui passe en paramètre le nom de l'utilisateur le chemin complet du fichier qui contient le mot de passe chiffré

#Le mot de passe sous forme de secure string est conservé dans la propriété pwdSecurestring, on peut y accéder comme ceci $Password.pwdSecureString
#Le credential object qui contient le jeu d'identifiant nom d'utilisateur et mot de passe est conservé sous forme de credential object dans la propriété credentials, on peut y accéder comme ceci $Password.credentials

$Credentials = $Password.Credentials #Attribution du credential object à la variable $Credentials
Get-ADUser -Identity "Toto" -Credential $Credentials #Utilisation de la cmdlet Get-ADUser avec le credential object précédemment généré

 

Remarque : lorsque le fichier est généré, une combinaison du compte utilisateur et du compte machine est utilisée. Cela implique que le mot de passe ne peut être déchiffré que par l'utilisateur qui l'a chiffré et sur la machine sur laquelle le chiffrement a eu lieu.

PowerShell - Chiffrer un mot de passe

À moins que votre but ne soit d'essayer de causer une crise cardiaque à votre équipe sécurité et d'entre autres faciliter le travail des hackers, il est conseillé de conserver les mots de passe dans les scripts chiffrés.

 

La fonction de chiffrement

function New-EncryptedPasswordFile #Fonction qu'il faudra appeler pour générer un fichier txt qui contiendra le mot de passe chiffré
{
    [CmdletBinding()] #Déclaration des paramètres qu'il faudra fournir à la fonction pour qu'elle puisse s'exécuter
    Param
    (
        [Parameter(Mandatory=$true)] #Indique que ce paramètre est obligatoire
        [ValidateNotNullOrEmpty()] #Indique que ce champ ne peut pas être vide ou null
        [string]$User, #Paramètre qui attend le nom de l'utilisateur, il n'est utilisé que pour le nom du txt de sortie ainsi n'importe quelle valeur peut être renseigné

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [securestring]$Password #Paramètre qui attend une secure string, 
    )

    Process
    {
        $EncryptedPasswordPath = $PSScriptRoot + "\" + $User + "_encrypted_password.txt" #Génére dynamiquement le chemin complet du txt qui contiendra le mot de passe chiffré
        $Password | ConvertFrom-SecureString | Out-File $EncryptedPasswordPath #Génére le txt qui contient le mot de passe chiffré
    }
}

 

Exemple d'utilisation de la fonction de chiffrement

Le script suivant appelle la fonction de chiffrement lorsque lui-même est appelé 

. .\New-EncryptedPasswordFile_article.ps1 #Permet de déclarer (dot source) la fonction de chiffrement pour qu'elle puisse être utilisée

New-EncryptedPasswordFile -User "Svc-test-01" #Appelle de la fonction de chiffrement et lui fournit volontairement uniquement le nom de l'utilisateur
#Le mot de passe sera demandé sous forme de secure string

 

 

Appel du script précédent

PS D:\A_folder> .\Call_me_maybe.ps1 #Appel du script précédent qui contient l'appelle de la fonction de chiffrement

cmdlet New-EncryptedPasswordFile at command pipeline position 1
Supply values for the following parameters: #La saisie du mot de passe sous forme de secure string est demandé
Password: ****

 

Le résultat

Le mot de passe contenu dans le fichier txt généré est chiffré

 

Remarque : lorsque le fichier est généré, une combinaison du compte utilisateur et du compte machine est utilisée. Cela implique que le mot de passe ne peut être déchiffré que par l'utilisateur qui l'a chiffré et sur la machine sur laquelle le chiffrement a eu lieu.

PowerShell - Créer une fonction de génération de mot de passe

La génération de mots de passe dans un script est un besoin fréquent lors de création de compte utilisateur. Au lieu d'appeler les cmdlets pour générer un mot de passe aléatoire à chaque besoin, il est plus esthétique de créer une fonction de génération de mots de passe dédiée et de l'utiliser quand le besoin se présente.

Le code suivant propose une fonction de génération de mots de passe qui essaye d'être simple, compréhensible et adaptative.

 

La fonction de génération de mots de passe

function New-RandomPassword #Fonction qu'il faudra appeler pour générer un mot de passe aléatoire
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$false)] #Indique que ce paramètre n'est pas obligatoire
        [ValidateNotNullOrEmpty()] #Indique que ce champ ne peut pas être vide ou null
        [int]$PasswordLength = 16, #Paramètre optionel qui spécifie la longueur du mot de passe, valeur par défaut 16

        [Parameter(Mandatory=$false)]
        [ValidateNotNullOrEmpty()]
        [int]$NumberOfAlphaNumericCharacters = 2, #Paramètre optionnel qui spécifie le nombre de caractères alphanumériques que le mot de passe doit contenir, valeur par défaut 2

        [Parameter(Mandatory=$false)]
        [ValidateNotNullOrEmpty()]
        [switch]$ConvertToSecureString #Paramètre qui si présent convertit le mot de passe en secure string pour pouvoir construire un PSCredential Object utile par exemple pour exécuter des cmdlets avec un compte de service 
    )

    Begin
    {
        Add-Type -AssemblyName 'System.Web' # Ajout d'une classe .NET à la session PowerShell qui permet d'accéder aux fonctions nécessaires à la génération du mot de passe
        
        $Return = @{} #Tableau de retour qui contient le mot de passe en clair et le mot de passe sous forme de secure string 
    }

    Process
    {
        $Password = [System.Web.Security.Membership]::GeneratePassword($PasswordLength,$NumberOfAlphaNumericCharacters) #Génération du mot de passe en clair avec les paramètres fournis
        $Return.passwordObject = $Password #Attribution du mot de passe généré dans la variable de sortie de la fonction

        if ($ConvertToSecureString.IsPresent) #Si le paramètre ConvertToSecureString est présent, génère une secure string du mot de passe
        {
            $Password = ConvertTo-SecureString -String $Password -AsPlainText -Force #Génération de la secure string du mot de passe
            $Return.passwordSecureObject = $Password #Attribution de la secure string du mot de passe dans la variable de sortie de la fonction
        }

        Return $Return #Retourne le mot de passe ainsi que la secure string en sortie de la fonction
    }
}

 

 

 

Exemple d'utilisation de la fonction de génération de mots de passe

. .\New-RandomPassword_article.ps1 #Permet de déclarer (dot source) la fonction de génération de mots de passe pour qu'elle puisse être utilisée

$Password = New-RandomPassword -PasswordLength 20 -ConvertToSecureString #Appelle de la fonction de génération de mots de passe
#Avec génération d'une secure string du mot de passe et une longueur de mot de passe de 20 caractères

$Password.passwordObject #Le mot de passe en clair est dans l'attribut passwordObject de la variable de sortie définit ci-avant $Password
$Password.passwordSecureObject #Le mot de passe sous forme de secure string est dans l'attribut passwordSecureObject de la variable de sortie définit ci-avant $Password

 

Le résultat


Appel du script PowerShell Call_me_maybe.ps1 ci-avant

PS D:\Hey_Im_a_folder> .\Call_me_maybe.ps1
LmcfY>5O$-GZ^z/fvfB1 #Affichage du mot de passe en clair
System.Security.SecureString #Mot de passe sous forme de secure string