web-dev-qa-db-fra.com

Créer un utilisateur Active Directory dans .NET (C #)

J'ai besoin de créer un nouvel utilisateur dans Active Directory. J'ai trouvé plusieurs exemples comme ceux-ci:

using System;
using System.DirectoryServices;

namespace test {
   class Program {
      static void Main(string[] args) {
        try {
            string path = "LDAP://OU=x,DC=y,DC=com";
            string username = "johndoe";

            using (DirectoryEntry ou = new DirectoryEntry(path)) {
               DirectoryEntry user = ou.Children.Add("CN=" + username, "user");

               user.Properties["sAMAccountName"].Add(username);

               ou.CommitChanges();
            }
         } 
         catch (Exception exc) {
             Console.WriteLine(exc.Message);
         }
      }
   }
}

Lorsque je lance ce code, je ne reçois aucune erreur, mais aucun nouvel utilisateur n'est créé. 

Le compte sur lequel je lance le test dispose des privilèges suffisants pour créer un utilisateur dans l'unité d'organisation cible. 

Me manque-t-il quelque chose (éventuellement un attribut requis de l'objet utilisateur)?

Des idées pour lesquelles le code ne donne pas d'exceptions?

MODIFIER
Ce qui suit a fonctionné pour moi:

int NORMAL_ACCOUNT = 0x200;
int PWD_NOTREQD = 0x20;
DirectoryEntry user = ou.Children.Add("CN=" + username, "user");
user.Properties["sAMAccountName"].Value = username;
user.Properties["userAccountControl"].Value = NORMAL_ACCOUNT | PWD_NOTREQD;
user.CommitChanges();

Il y avait donc quelques problèmes:

  1. CommitChanges doit être appelé le user (merci Rob)
  2. La politique de mot de passe empêchait l'utilisateur d'être créé (merci Marc)
20
Paolo Tedesco

Je pense que vous appelez CommitChanges sur le mauvais DirectoryEntry. Dans la documentation MSDN ( http://msdn.Microsoft.com/en-us/library/system.directoryservices.directoryentries.add.aspx ), il est indiqué ce qui suit (soulignement ajouté par moi)

Vous devez appeler la méthode CommitChanges sur la nouvelle entrée _ pour rendre la création permanente. Lorsque vous appelez cette méthode, vous pouvez ensuite définir des valeurs de propriété obligatoires sur la nouvelle entrée. Les fournisseurs ont chacun des exigences différentes pour les propriétés qui doivent être définies avant qu'un appel à la méthode CommitChanges ne soit effectué. Si ces conditions ne sont pas remplies, le fournisseur peut lever une exception. Vérifiez auprès de votre fournisseur quelles propriétés doivent être définies avant de valider les modifications.

Donc, si vous changez votre code en user.CommitChanges () cela devrait fonctionner, si vous avez besoin de définir plus de propriétés que le seul nom de compte, vous devriez obtenir une exception.

Étant donné que vous appelez actuellement CommitChanges () sur l'unité d'organisation qui n'a pas été modifiée, il n'y aura aucune exception.

16
RobV

En supposant que votre chemin d'accès OU OU=x,DC=y,DC=com existe vraiment - cela devrait fonctionner :-)

Choses à vérifier:

  • vous ajoutez une valeur au "samAccountName" - pourquoi ne pas simplement définir sa valeur:

    user.Properties["sAMAccountName"].Value = username;
    

Sinon, vous risquez de vous retrouver avec plusieurs samAccountNames - et cela ne fonctionnera pas .....

  • vous ne définissez pas la propriété userAccountControl sur quelque chose - essayez d'utiliser:

     user.Properties["userAccountControl"].Value = 512;  // normal account
    
  • avez-vous plusieurs contrôleurs de domaine dans votre organisation? Si vous utilisez cette liaison "sans serveur" (sans spécifier de serveur dans le chemin LDAP), vous serez peut-être surpris de la création de l'utilisateur :-) et cela prendra plusieurs minutes à une demi-heure pour synchroniser sur tout le réseau

  • avez-vous une politique de mot de passe stricte en place? Peut-être que c'est le problème. Je me souviens que nous devions d'abord créer l'utilisateur avec l'option "ne nécessite pas de mot de passe", faire un premier .CommitChanges (), puis créer un mot de passe assez puissant, le définir sur l'utilisateur et supprimer cette option.

Marc

8
marc_s

Vérifiez le code ci-dessous 

 DirectoryEntry ouEntry = new DirectoryEntry("LDAP://OU=TestOU,DC=TestDomain,DC=local");

        for (int i = 3; i < 6; i++)
        {
            try
            {
                DirectoryEntry childEntry = ouEntry.Children.Add("CN=TestUser" + i, "user");
                childEntry.CommitChanges();
                ouEntry.CommitChanges();
                childEntry.Invoke("SetPassword", new object[] { "password" });
                childEntry.CommitChanges();
            }
            catch (Exception ex)
            {

            }
        }
0
kombsh