Active Directory & .Net 2.0


précédentsommairesuivant
existe déjà

3. Gestion des objets utilisateurs dans Active Directory

Dans cette partie, nous allons voir ce que nous offre le Framework .Net 2.0 dans la gestion des objets utilisateurs dans Active Directory, ces explications seront agrémentées de codes d'exemple. Commençons d'abord sur comment se connecter aux services d'annuaires Active Directory.

Remarque : tout au long de cet article, je vais parler d'objets comptes d'utilisateur, de compte d'utilisateur ou même d'utilisateur, sachez que ces trois types d'appellation recoupent la même notion, à savoir un objet de type compte d'utilisateur se trouvant dans l'annuaire Active Directory. J'ai simplement utilisé trois appellations différentes pour ne pas avoir des paragraphes trop indigestes.

3.1. Lecture de propriétés des comptes d'utilisateurs

Dans un premier temps, nous allons récupérer des attributs d'un objet utilisateur. Chaque objet possède de très nombreux attributs qui, dans le cas d'un utilisateur, peuvent être sa description, ou encore prénom. Je vous renvoie à la documentation du schéma d'Active Directory pour connaître la liste de tous les attributs de chaque objet, il en existe des centaines !

3.1.1. Récupération de la valeur d'un paramètre

Voici la démarche à suivre pour effectuer une telle opération.

- Instancier un objet DirectoryEntry qui contiendra notre objet compte utilisateur, pour cela on fournit :

  • Le chemin LDAP de l'objet utilisateur concerné
  • Le compte AD utilisé pour se connecter

- Lecture et récupération du paramètre souhaité.
- Fermeture de la "connexion" établie par l'objet DirectoryEntry.

Ci-dessous, l'exemple d'une fonction permettant de récupérer le paramètre "displayName", qui correspond tout simplement au nom affiché dans l'annuaire pour ce compte utilisateur.

Récupération de l'attribut 'displayName' :
Sélectionnez

    Public Function getDisplayName(ByVal monCheminLdapUser As String, _
	                               ByVal monUsername As String, _
	                               ByVal monpassword As String) As String

		' Exemple de chemin LDAP : "CN=User 1,CN=Users,DC=monDomaine,DC=local"

        Dim monDisplayName As String = Nothing

        Try
            ' Connexion à l'objet compte utilisateur souhaité
            Dim monUser As DirectoryEntry = New DirectoryEntry("LDAP://" & _
			               monCheminLdapUser, monUsername, monpassword)

            ' Récupération de la valeur de la propriété
            monDisplayName = monUser.Properties("displayName").Value.ToString
            ' Fermeture de la "connexion"
            monUser.Close()

        Catch ex As Exception

            monDisplayName = ex.Message

        End Try

        Return monDisplayName

    End Function

3.1.2. Récupération des membres d'un groupe

Comme vous le savez déjà certainement, Active Directory permet de créer des groupes (de sécurité ou de distribution) qui contiennent d'autres objets comme des comptes utilisateurs ou des comptes d'ordinateurs par exemple. L'avantage principal de l'utilisation des groupes est qu'ils permettent de centraliser et de regrouper des objets afin d'en faciliter l'administration, mais là n'est pas le thème de cet article donc je n'entrerai pas plus dans les détails. Voyons comment récupérer par le code la liste des utilisateurs contenus dans un groupe donné.

La démarche va être la suivante :

  • Connexion à l'annuaire Active Directory
  • Récupération de la propriété " members " d'un groupe
  • Boucle pour parcourir la propriété " members "
  • Renvoi du résultat

Exemple montrant comment lister les utilisateurs du groupe "Utilisateurs du domaine" :

Lister les membres d'un groupe :
Sélectionnez

    Public Function listeMembresGroupe(ByVal cheminLdapGroupe As String, _
	                                   ByVal monUsername As String, _
	                                   ByVal monPassword As String) As ArrayList

        ' Instanciation de la liste qui va contenir le résulat
        Dim maListeMembres As New ArrayList

        Try

            ' Groupe dont les membres sont à lister
            Dim monGroupe As New DirectoryEntry("LDAP://" & cheminLdapGroupe, _
			                     monUsername, monPassword, AuthenticationTypes.Secure)

            Dim unMembre As New Object()
            ' Ajoute chaque membre trouvé à notre ArrayList à retourner
            For Each unMembre In monGroupe.Properties("member")
                maListeMembres.Add(unMembre.ToString)
            Next

            monGroupe.Close()

        Catch ex As Exception

            MessageBox.Show(ex.Message)

        End Try

        ' Retourne la liste des membres du groupe
        Return maListeMembres

    End Function

3.1.3. Liste des groupes dont un utilisateur est membre

Après avoir récupéré la liste des membres d'un groupe, intéressons nous aux utilisateurs, ainsi nous allons lister les groupes dont un utilisateur donné est membre. Pas la peine de faire plus de commentaires à ce sujet, le code suivant "parle" de lui-même :

Liste les groupes dont un utilisateur est membre
Sélectionnez

    Public Function isMemberOf(ByVal cheminLdapUser As String, _
	                           ByVal monUsername As String, _
	                           ByVal monPassword As String) As ArrayList

		' Exemple de chemin LDAP : "CN=Administrateurs de l'entreprise,CN=Users,DC=monDomaine,DC=local"

        ' Instanciation la liste qui va contenir les groupes
        Dim maListeGroupes As New ArrayList

        Dim monUser As New DirectoryEntry("LDAP://" & cheminLdapUser, _
		                   monUsername, monPassword)

        ' Appel de la méthode "Groups" d'ADSI
        Dim mesGroupes As Object = monUser.Invoke("Groups")

        ' Récupération de la liste des groupes
        For Each unGroupe As Object In CType(mesGroupes, IEnumerable)
            Dim groupEntry As DirectoryEntry = New DirectoryEntry(unGroupe)
            maListeGroupes.Add(groupEntry.Name)
            MessageBox.Show(groupEntry.Name)
        Next

        Return maListeGroupes

    End Function

3.1.4. Récupération des objets utilisateurs contenus dans une OU

Il s'agît ici de récupérer tous les utilisateurs contenus dans une OU, le chemin LDAP passé en paramètre pourrait être par exemple "CN=MesUtilisateurs,DC=contoso,DC=local".

Récupérer les comptes utilisateurs contenus dans une OU :
Sélectionnez

    Public Function getUsersOU(ByVal monCheminLdapRecherche As String, _
                               ByVal monUsername As String, _
                               ByVal monpassword As String) As ArrayList

        ' ArrayList qui va contenir le résultat retourné par la recherche
        Dim maListeUsers As New ArrayList

        Try

            ' Instanciation d'un objet DirectorySearcher

            ' Définition de l'emplacement de recherche
            Dim monEmplacementRecherche As New DirectoryEntry("LDAP://" & _
			    monCheminLdapRecherche, monUsername, monpassword, AuthenticationTypes.Secure)

            Dim maRecherche As New DirectorySearcher(monEmplacementRecherche)

            ' dureeMax initisalisée à 25 secondes
            Dim dureeMax As New TimeSpan(0, 0, 25)

            ' Emplacement  la recherche doit être effectuée 
            ' dans la hiérarchie Active Directory
            maRecherche.SearchRoot = monEmplacementRecherche

            ' Définition du Scope de la recherche, ici le conteneur 
            ' seulement et tous ses "sous conteneur"
            maRecherche.SearchScope = SearchScope.Subtree

            ' Filtre uniquement les objets de type "user"
            maRecherche.Filter = "(objectClass=user)"

            ' Détermination de la propriété à récupérer lors de la recherche
            maRecherche.PropertiesToLoad.Add("sAMAccountName")

            ' Durée maximum de la recherche
            maRecherche.ServerTimeLimit = dureeMax

            ' Fixe le nombre maximum d'objets retournés
            maRecherche.SizeLimit = 1500

            Dim unUtilisateur As DirectoryServices.SearchResult

            ' Récupération du 'sAMAccountName' des utilisateurs récupérés
            For Each unUtilisateur In maRecherche.FindAll()
                maListeUsers.Add(unUtilisateur.GetDirectoryEntry.Properties.Item("sAMAccountName").Value.ToString)
            Next

            monEmplacementRecherche.Close()

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

        Return maListeUsers

    End Function

Attention : ici, nous récupérons la propriété "sAMAccountName" donc celle-ci sera forcément toujours renseignée, puisqu'elle est obligatoire, mais pour les propriétés facultatives, il faudra faire attention, en effet, si l'une d'elles est nulle une exception sera alors levée. Il faut donc penser à gérer cela correctement dans son code, une simple vérification avec le mot clé "Nothing" suffira à éviter un crash assez ridicule de votre méthode !

3.1.5. Récupération du SID d'un objet compte d'utilisateur

SID signifie simplement Security Identifier, il s'agit en fait d'une chaîne de caractères alphanumériques unique qui permet d'identifier chaque objet (compte d'utilisateurs, groupes, ordinateurs...) dans une forêt Active Directory. Cette chaîne contient une partie fixe qui correspond au domaine d'appartenance et une partie " aléatoire et unique " qui est en fait le RID (Relative ID), et qui, elle, identifie directement l'objet au sein du domaine. Le rôle du SID est donc de permettre d'identifier de manière unique et formelle un objet dans une forêt, mais ce SID peut être modifié, dans le cas où, par exemple, l'objet auquel il se rattache est transféré d'un domaine à un autre. Il ne faut de plus pas confondre SID et GUID, ce dernier permet également d'identifier de manière unique un objet au sein d'une forêt Active Directory, mais le GUID quoi qu'il arrive ne sera jamais modifié, il est associé à un objet tout au long de son existence. Toutes les autorisations et les droits associés aux objets dans l'annuaire reposent sur le SID de chaque objet et non sur son nom comme on le croit trop souvent.

Voyons, dans un premier temps, comment récupérer ce SID dans l'annuaire, puis par la suite, nous verrons comment le formater pour l'afficher sous la forme que le connaisse tous les administrateurs.

Récupérer le SID d'un compte utilisateur :
Sélectionnez

    Public Function getUserSid(ByVal cheminLdapUser As String, _
                               ByVal monUsername As String, _
                               ByVal monPassword As String) As Byte()

        ' Tableau d'octets qui va contenir le SID
        Dim sidUser As Byte() = Nothing

        Try

            ' Récupération du SID de l'objet souhaité
            Dim monEntry As New DirectoryEntry("LDAP://" & cheminLdapUser, _
			                    monUsername, monPassword)

            sidUser = CType(monEntry.Properties("objectSid").Value, Byte())
            monEntry.Close()

        Catch ex As Exception

            MessageBox.Show(ex.Message)

        End Try

        ' Retour du SID dans un tableau d'octets sous sa forme primaire
        Return sidUser

    End Function

Vous avez vu qu'il est très simple de récupérer ce SID, par contre pour le formater correctement, vous allez voir que ce n'est pas aussi simple ! Enfin, rien d'insurmontable pour autant, rassurez-vous.

Formater un SID :
Sélectionnez

    Public Function formateSidToString(ByVal sidEnOctets As Byte()) As String

        Dim nombreSubauthority As Short = 0
        Dim monSid As StringBuilder = New StringBuilder

        monSid.Append("S-")

        Try
            monSid.Append(sidEnOctets(0).ToString)
            nombreSubauthority = Convert.ToInt16(sidEnOctets(1))


            If Not (sidEnOctets(2) = 0) OrElse Not (sidEnOctets(3) = 0) Then

                Dim strAuth As String = String.Format("0x{0:2x}{1:2x}{2:2x}{3:2x}{4:2x}{5:2x}", _
                                        CType(sidEnOctets(2), Int16), _
                                        CType(sidEnOctets(3), Int16), _
                                        CType(sidEnOctets(4), Int16), _
                                        CType(sidEnOctets(5), Int16), _
                                        CType(sidEnOctets(6), Int16), _
                                        CType(sidEnOctets(7), Int16))

                monSid.Append("-")
                monSid.Append(strAuth)

            Else

                Dim iVal As Int64 = CLng(CType((sidEnOctets(7)), Int32) & _
                                    CType((sidEnOctets(6) < 8), Int32) & _
                                    CType((sidEnOctets(5) < 16), Int32) & _
                                    CType((sidEnOctets(4) < 24), Int32))

                monSid.Append("-")
                monSid.Append(iVal.ToString)

            End If



            Dim idxAuth As Integer = 0
            Dim i As Integer = 0

            While i < nombreSubauthority

                idxAuth = 8 + i * 4

                Dim iSubAuth As UInt32 = BitConverter.ToUInt32(sidEnOctets, idxAuth)

                monSid.Append("-")
                monSid.Append(iSubAuth.ToString)

                i += 1

            End While


        Catch ex As Exception

            Return "Une erreur est survenue : " & ex.Message

        End Try

        Return monSid.ToString

    End Function

Ouf ! Voilà ce SID enfin correctement formaté !

Jusqu'à maintenant, nous avons vu comment lire des paramètres et des propriétés dans l'annuaire, maintenant voyons l'accès en écriture dans l'annuaire.

3.2. Modification des objets compte utilisateur

Désormais nous savons lire des informations dans l'annuaire Active Directory, montons d'un cran sur l'échelle de l'intérêt que présentent ces fonctionnalités, et voyons maintenant comment écrire dans l'annuaire. Vous allez voir, qu'à condition de disposer des autorisations suffisantes, cela ne présente aucune difficulté particulière.

Remarque : pour pouvoir écrire dans l'annuaire Active Directory, vous devez être membre du groupe "Administrateur du domaine", ou alors avoir reçu les droits nécessaires de la part d'un administrateur.

3.2.1. Fixer la valeur de propriété d'un objet compte d'utilisateur

Nous allons voir ici comment modifier facilement la propriété "description" d'un objet compte utilisateur, mais le fonctionnement sera le même pour l'immense majorité des autres propriétés.

Modifier la description d'un utilisateur :
Sélectionnez

    Public Function modifDescriptionUser(ByVal monCheminLdapUser As String, _
	                                     ByVal monUsername As String, _
	                                     ByVal monPassword As String, _
	                                     ByVal maValeur As String) As Boolean

        Try

            ' Connexion à l'objet utilisateur souhaité
            Dim monUser As DirectoryEntry = New DirectoryEntry("LDAP://" & _
			                                monCheminLdapUser, monUsername, monPassword)
            ' Modification de la valeur
            monUser.Properties("description").Value = maValeur
            ' Validation des modifications
            monUser.CommitChanges()
            monUser.Close()

        Catch ex As Exception

            MessageBox.Show(ex.Message)
            Return False

        End Try

        Return True

    End Function

3.2.2. Vérification de l'existence d'un objet utilisateur dans l'annuaire

Nous allons voir ici comment grâce à la classe DirectorySearch, il est possible de tester facilement l'existence d'un utilisateur. La fonction que vous allez voir ci-dessous, retourne "True" si l'utilisateur existe, et "False" évidemment s'il n'existe pas. Précédemment, nous avons suffisamment étudié le fonctionnement des recherches dans l'annuaire, je ne rentrerai donc pas plus dans les détails, les commentaires du code seront suffisants.

Vérification de l'existence d'un utilisateur :
Sélectionnez

    Public Function userExist(ByVal userAverifier As String, _
	                          ByVal cheminLdapAexaminer As String, _
	                          ByVal monUsername As String, _
	                          ByVal monPassword As String) As Boolean

        Try
            ' Connexion à l'annuaire
            Dim monEntry As New DirectoryEntry(cheminLdapAexaminer, monUsername, _
			                    monPassword, AuthenticationTypes.Secure)
            Dim maRecherche As DirectorySearcher = New DirectorySearcher

            ' Paramétrage de la requête
            maRecherche.SearchRoot = monEntry
            maRecherche.Filter = "(&(objectClass=user) (cn=" + userAverifier + "))"

            ' Récupération du résultat de la requête
            Dim results As SearchResultCollection = maRecherche.FindAll()
            monEntry.Close()

            ' Analyse du résultat
            If results.Count = 0 Then
                Return False
            Else
                Return True
            End If

        Catch ex As Exception

            MessageBox.Show(ex.Message)

        End Try

    End Function

3.2.3. Ajout ou suppression d'un utilisateur dans un groupe

Ajouter un utilisateur à un groupe
Sélectionnez

    Public Function addUserToGroup(ByVal cheminLdapGroup As String, _
	                               ByVal cheminLdapUser As String, _
	                               ByVal monUsername As String, _
	                               ByVal monPassword As String) As Boolean

        Dim monGroupe As New DirectoryEntry("LDAP://" & cheminLdapGroup, monUsername, _
		                     monPassword, AuthenticationTypes.Secure)
        Dim monUtilisateur As New DirectoryEntry("LDAP://" & cheminLdapUser, monUsername, _
		                     monPassword, AuthenticationTypes.Secure)

        Try
            ' Vérifie si l'utilisateur n'est pas déjà membre du groupe
            Dim estDejaMembre As Boolean = Convert.ToBoolean(monGroupe.Invoke("IsMember", _
			                               New Object() {monUtilisateur.Path}))

            If Not estDejaMembre Then
                ' Utilisation de la méthode ADSI "Add" pour ajouter un utilisateur à un groupe
                monGroupe.Invoke("Add", New Object() {monUtilisateur.Path})
            Else
                MessageBox.Show("L'utilisateur " & monUtilisateur.Properties("cn")._
				                 Value.ToString() & " est déjà membre de ce groupe !")
            End If

            Return True

        Catch ex As Exception

            MessageBox.Show(ex.Message)
            Return False

        Finally

            ' Libération des ressources inutiles encore utilisées
            If Not IsNothing(monUtilisateur) Then
                monUtilisateur.Dispose()
            End If

            If Not IsNothing(monGroupe) Then
                monGroupe.Dispose()
            End If

        End Try

    End Function

Entre l'ajout et la suppression d'un objet compte utilisateur dans l'annuaire il n'y a finalement que des différences infimes, vous pouvez d'ailleurs le constater dans les deux codes exemples que je vous donne. Seule la méthode ADSI qui est appelée n'est pas la même (" remove ", au lieu de " add ", ainsi que l'ordre dans lequel est vérifiée l'appartenance au groupe par l'intermédiaire d'un booléen. Evidemment, pour supprimer un compte, on vérifie auparavant qu'il existe, et inversement pour ajouter un compte, on vérifie qu'il n'existe pas déjà avant de lancer l'opération.

Retirer un utilisateur d'un groupe :
Sélectionnez

    Public Function removeUserToGroup(ByVal cheminLdapGroup As String, _
	                                  ByVal cheminLdapUser As String, _
	                                  ByVal monUsername As String, _
	                                  ByVal monPassword As String) As Boolean

        Dim monGroupe As New DirectoryEntry("LDAP://" & cheminLdapGroup, monUsername, _
		                 monPassword, AuthenticationTypes.Secure)
        Dim monUtilisateur As New DirectoryEntry("LDAP://" & cheminLdapUser, monUsername, _
		                 monPassword, AuthenticationTypes.Secure)

        Try
            ' Vérifie si l'utilisateur n'est pas déjà membre du groupe
            Dim estMembre As Boolean = Convert.ToBoolean(monGroupe.Invoke("IsMember", _
			                           New Object() {monUtilisateur.Path}))

            If estMembre Then
                ' Utilisation de la méthode ADSI "Add" pour ajouter un utilisateur à un groupe
                monGroupe.Invoke("Remove", New Object() {monUtilisateur.Path})
            Else
                MessageBox.Show("L'utilisateur " & monUtilisateur.Properties("cn")_
				                 .Value.ToString() & " n'est pas membre de ce groupe !")
            End If

            Return True

        Catch ex As Exception

            MessageBox.Show(ex.Message)
            Return False

        Finally

            ' Libération des ressources inutiles encore utilisées
            If Not IsNothing(monUtilisateur) Then
                monUtilisateur.Dispose()
            End If

            If Not IsNothing(monGroupe) Then
                monGroupe.Dispose()
            End If

        End Try

    End Function

3.2.4. Activation ou désactivation d'un compte utilisateur

Une pratique courante, et surtout indispensable au plan de la sécurité, est de désactiver chaque compte inutilisé pour une période suffisamment longue. Dans Windows Server, par le biais de la console "Utilisateurs et ordinateurs Active Directory", il ne suffit que d'un clic droit et d'un clic gauche pour désactiver ou activer un compte, vous allez pouvoir constater que le faire grâce à du code .Net est à peine plus long.

Activer un compte utilisateur :
Sélectionnez

    Public Function activeCompteUser(ByVal cheminLdapUser As String, _
	                                 ByVal monUsername As String, _
	                                 ByVal monPassword As String) As Boolean

        Try
            ' Connexion au compte utilisateur donné
            Dim monUtilisateur As DirectoryEntry = New DirectoryEntry("LDAP://" & cheminLdapUser, _
			                      monUsername, monPassword, AuthenticationTypes.Secure)
            ' Récupération du flag indiquant l'état d'activation du compte
            Dim maValeur As Integer = CType(monUtilisateur.Properties("userAccountControl").Value, Integer)
            ' Modification du flag pour activer le compte
            monUtilisateur.Properties("userAccountControl").Value = maValeur And Not 2
            ' Validation des modifications
            monUtilisateur.CommitChanges()
            Return True

        Catch ex As Exception

            MessageBox.Show(ex.Message)
            Return False

        End Try

        
    End Function

Après l'activation d'un compte utilisateur, voilà tout naturellement et sans surprise, la désactivation :

Désactiver un compte utilisateur :
Sélectionnez

    Public Function desactiveCompteUser(ByVal cheminLdapUser As String, _
	                                    ByVal monUsername As String, _
	                                    ByVal monPassword As String) As Boolean

        Try
            ' Connexion au compte utilisateur donné
            Dim monUtilisateur As DirectoryEntry = New DirectoryEntry("LDAP://" & cheminLdapUser)
            ' Récupération du flag indiquant l'état d'activation du compte
            Dim maValeur As Integer = CType(monUtilisateur.Properties("userAccountControl").Value, Integer)
            ' Modification du flag pour désactiver le compte
            monUtilisateur.Properties("userAccountControl").Value = maValeur Or 2
            ' Validation des modifications
            monUtilisateur.CommitChanges()
            Return True

        Catch ex As Exception

            MessageBox.Show(ex.Message)
            Return False

        End Try


    End Function

3.2.5. Déplacer un objet dans l'annuaire

Cet exemple vous montre comment déplacer un objet dans l'annuaire, vous pouvez ainsi, par exemple, déplacer un utilisateur d'une OU à une autre en quelques lignes, bref, une fonctionnalité tout à fait indispensable pout n'importe quel administrateur système, surtout si on la couple à d'autres comme par exemple une recherche, imaginez plutôt : vous récupérez tous les utilisateurs d'un groupe donné dans une OU et vous les déplacez dans une autre en quelques lignes de code ! De quoi vous faire une application .Net de gestion d'annuaire très performante, et cela pour un très faible coût de développement.

Déplacer un objet compte d'utilisateur :
Sélectionnez

    Public Function moveUserFromTo(ByVal cheminLdapOrigine As String, _
	                               ByVal cheminLdapDestination As String, _
	                               ByVal monUsername As String, _
	                               ByVal monPassword As String) As Boolean

        Try

            ' Connexion à l'utilisateur à déplacer
            Dim monUserAdeplacer As New DirectoryEntry("LDAP://" & cheminLdapOrigine, _
			                            monUsername, monPassword, AuthenticationTypes.Secure)
            ' Déplacement de l'utilisareur vers son nouvel emplacement dans l'annuaire
            monUserAdeplacer.MoveTo(New DirectoryEntry("LDAP://" & cheminLdapDestination, _
			                            monUsername, monPassword, AuthenticationTypes.Secure))

            monUserAdeplacer.Close()

            Return True

        Catch ex As Exception

            MessageBox.Show(ex.Message)
            Return False
        End Try

    End Function

3.3. Suppression d'objets comptes d'utilisateurs dans l'annuaire

Une autre règle de base en sécurité, après la désactivation des objets momentanément inutiles, est de supprimer ce dont on est sûr qu'ils ne serviront plus par la suite. Et comme pour tout ce que l'on a vu jusqu'ici, le namespace System.DirectoryServices et ADSI vont nous venir en aide. Ce code s'applique aux comptes utilisateurs mais également à n'importe quel autre objet de l'annuaire, à la condition que l'objet à supprimer n'ai pas d'objets enfants, comme cela peut être le cas par exemple pour une OU, l'objet ne doit donc contenir aucun autre objet, si ce n'est pas le cas, il faut utiliser une autre méthode pour supprimer cet objet.

Supprimer un objet compte d'utilisateur :
Sélectionnez

    Public Function deleteUser(ByVal cheminLdapParent As String, _
	                           ByVal cheminLdapObjetAsupprimer As String, _
	                           ByVal monUsername As String, _
	                           ByVal monPassword As String) As Boolean

        ' Noeud parent de l'objet à supprimer
        Dim entryParent As New DirectoryServices.DirectoryEntry("LDAP://" & cheminLdapParent, _
		                       monUsername, monPassword, AuthenticationTypes.Secure)

        ' Objet à supprimer
        Dim entryAsupprimer As New DirectoryServices.DirectoryEntry("LDAP://" & cheminLdapObjetAsupprimer, _
		                       monUsername, monPassword, AuthenticationTypes.Secure)

        Try

            ' Suppression de l'objet
            entryParent.Children.Remove(entryAsupprimer)
            Return True

        Catch ex As Exception

            MessageBox.Show(ex.Message)
            Return False

        Finally

            ' Fermeture des DirectoryEntry
            entryParent.Close()
            entryAsupprimer.Close()

        End Try

    End Function

3.4. Création d'objets comptes d'utilisateurs dans l'annuaire

Enfin ne manquait plus qu'une fonctionnalité principale en ce qui concerne la gestion des comptes utilisateurs depuis .Net, il s'agît bien évidemment de la création de comptes. En la matière, comme d'ailleurs pour toute la gestion de l'Active Directory que ce soit en mode graphique ou ligne de commande, Microsoft à particulièrement gaté les administrateurs systèmes, mais .Net est en quelque sorte la troisième voie, et, à mon avis, la plus prometteuse pour les années à venir, surtout pour les plus grosses infrastructures Active Directory, mais tout ceci n'engage que moi. Sans plus tarder passons au code commenté qui nous montre comment réaliser cette opération :

Créer un compte utilisateur :
Sélectionnez

    Public Function createUser(ByVal monCheminLdap As String, _
	                           ByVal monUsername As String, _
	                           ByVal monpassword As String, _
	                           ByVal nouvelUser As String) As Boolean

        Try
            Dim monEmplacement As DirectoryEntry = New DirectoryEntry("LDAP://" & _
			                   monCheminLdap, monUsername, monpassword, AuthenticationTypes.Secure)

            Dim monUser As DirectoryEntry = monEmplacement.Children.Add("cn=" & nouvelUser, "user")

            ' Nom d'ouverture de session pour les systèmes antérieurs à Windows 2000
            monUser.Properties("sAMAccountName").Add("userDeveloppez")

            ' Nom affiché dans l'annuaire
            monUser.Properties("displayName").Add("Mr Developpez")

            ' Adresse de l'utilisateur titulaire de ce compte
            monUser.Properties("street").Add("1 rue Developpez.com")

            ' Nom d'ouverture de session de l'utilisateur
            monUser.Properties("UserPrincipalName").Add("userDeveloppez@contoso.local")

            ' Description du compte utilisateur
            monUser.Properties("description").Add("Utilisateur de test")

            ' Création de l'objet utilisateur et application des paramètres définis ci-dessus
            monUser.CommitChanges()

            'monUser.NativeObject.AccountDisabled = False

            ' Création du mot de passe pour ce compte utilisateur
            monUser.Invoke("SetPassword", New Object() {"moTdePassE012"})
            monUser.CommitChanges()

            ' L'utilisateur devra changer son mot de passe à sa prochaine connexion
            monUser.Properties("pwdLastSet").Value = 0
            monUser.CommitChanges()

            Return True

        Catch ex As Exception

            MessageBox.Show(ex.Message)
            Return False

        End Try

    End Function

Remarque : une grande partie de la sécurité de vos comptes utilisateurs repose sur la robustesse et la confidentialité des mots de passe, vous pouvez constater que dans le code ci-dessus, je donne le mot de "passe en dur" ce qui n'est absoluement pas souhaitable. Je vous conseille donc de créer une méthode permettant de générer des mots de passe à la volée et surtout de manière aléatoire. La complexité ou le fait que ce mot de passe soit généré automatiquement n'est en aucun cas un problème puisque tout administrateur sensé forcera l'utilisateur à changer son mot de passe lors de la première ouverture de session. Le Framework .Net vous permettra facilement de créer des mots de passe à la volée respectant les impératifs de complexité et de longueur en vigueur sur votre réseau. Donc pour résumer : n'entrez pas vos mots de passe à la main dans votre code, mais faites le générér automatiquement !

Remarque : vous trouverez tous les liens vers la documentation nécessaire dans la section "Ressources" de cet article, cela concerne entre autre la valeur, le rôle des différents "flags" ainsi que leur fonctionnement.

Après avoir étudié comment obtenir ou modifier des propriétés d'un objet compte utilisateur dans Active Directory, voyons maintenant ce qu'il en est pour les autres objets présents dans l'annuaire.


précédentsommairesuivant
existe déjà

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2005 Ronald VASSEUR. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.