locked
Cross domain members en vbs RRS feed

  • Question

  • Bonjour,

    J'ai fait un vbs qui ajoute les membres d'un groupe X vers un groupe Y.
    Le script fonctionne bien dans le cas d'un seul domaine. Mais il ne fonctionne pas d'un domaine A vers B et cross-forest

    La commande PutEx renvoit une erreur lorsque j'essaye de synchroniser les membres du groupe X du domaine A avec le groupe Y du domaine B.

    Voici la partie du script qui pose probleme :


    Dim sourceGroup, targetGroup, objMember

    Const ADS_PROPERTY_APPEND = 3

    Set sourceGroup = GetObject("LDAP://" & dcsource & "/" & sourceDName) -> Info du domaine A  correct
    Set targetGroup = GetObject("LDAP://" & dctarget & "/" & targetDName) -> Info du domaine B correct

       
    For each objMember in sourceGroup.Members

    Err.Clear
    WScript.Echo objMember.distinguishedName -> renvoi bien le DN du membre source
             
    targetGroup.PutEx ADS_PROPERTY_APPEND, "member", Array(objMember.distinguishedName)
              targetGroup.SetInfo
              
    If Err.Number <> "0" Then
                WriteLog(Err.Number & " - " & Err.Description)
               End If
    Next

    Et j'obtiens le code erreur -2147016656 sans description.
    Je pense que c'est un problème de connexion cross-domain mais je ne vois pas comment le régler.
    Evidemment, les trusts sont ok au niveau des deux domaines.

    Une idée ?

    Merci

    Olivier Isler

    mercredi 30 juillet 2008 10:00

Réponses


  • Bonjour,

    Réponse tardive sur le sujet. Je n'ai pas eu le temps de m'en occuper mais j'ai pu replonger dedans il y a quelques jours et j'ai "enfin" trouvé une solution.

    Je précise le problème : impossibilité de rajouter un objet d'un domaine A appartenant à une forêt A, comme membre d'un groupe d'un domaine B appartenant à une forêt B en utilisant un script (ça marche parfaitement à la main .. but real men don't click ...).
    Message d'erreur : L'objet spécifié ne se trouve pas sur le serveur.

    Et voici le workaround : utiliser le SID de l'objet avec cette fonction

    '********************************************************************
    Dim oProv, oGroup, oValue, oString, oObj
       
    Set oProv = GetObject("LDAP:")
    Set oGroup = oProv.OpenDSObject("LDAP://" & targetdc & "/" & targetDName, vbnullstring, vbnullstring, 1)

    For each objMember in objGroup.Members
               
            Set oObj = oProv.OpenDSobject("LDAP://" & sourcedc & "/" & objMember.distinguishedName, vbnullstring, vbnullstring,1)
            oValue = oObj.Get("objectSid")
            oString = OctetString2String(oValue)
            oGroup.PutEx ADS_PROPERTY_APPEND, "member", Array("<Sid=" & oString & ">")
            oGroup.SetInfo
       
            If err.number<>0 Then
                  WScript.Echo "Error -> " & Err.Number & " : " & Err.Description
            End If
          
    Next

    Function OctetString2String(byVal OctetStr)
    dim result
    dim j, loByte, hiByte

        result = ""
        for j = lbound(OctetStr) to ubound(OctetStr)
            hiByte = ascb(midb(OctetStr,j+1,1))
            loByte = hiByte mod 16
            hiByte = hiByte \ 16
            result = result & hex(hiByte) & hex(loByte)
        next

        OctetString2String = result
    End Function
    '********************************************************************

    Et j'arrive enfin à faire marcher le script. Le seul petit probleme c'est que, de temps en temps, le SID n'est pas résolu et dans le target group j'obtiens un objet "<sid=xxxxxxx>".
    Mais le principal est que ça fonctionne.

    Cordialement,

    Olivier
    mardi 26 août 2008 14:22

Toutes les réponses

  • Bonjour,

     

    pourquoi n'utilises-tu pas la fonction "add" sur les objets groupes ? Ce serait beaucoup plus simple.

     

    Voici un exemple de script où j'ajoute des groupes Globaux de 2 domaines différents vers un groupe local:

     

    Code Snippet

    function AddgroupGlobalToLocal(Nom)

    Set oConnection = CreateObject("ADODB.Connection")
    oConnection.Provider = "ADsDSOObject"
    oConnection.Open "ADs Provider"

    Set oRecordset1 = oConnection.Execute("<LDAP://"&DestDomain&">;(&(objectCategory=group)(Name="&Nom&"-G));name,samaccountname,DistinguishedName,PrimaryGroupToken;subtree")
    If Not oRecordset1.EOF Then
        if isnull(oRecordset1.Fields("DistinguishedName")) Then
          DistinguishedName=""
          set ogroupG=nothing
        else
          DistinguishedName=oRecordset1.Fields("DistinguishedName")
          set ogroupG=getobject("LDAP://"&distinguishedName)
        end if
    End If

    Set oRecordset2 = oConnection.Execute("<LDAP://"&DestDomain&">;(&(objectCategory=group)(Name="&Nom&"-L));name,samaccountname,DistinguishedName,PrimaryGroupToken;subtree")
    If Not oRecordset2.EOF Then
        if isnull(oRecordset2.Fields("DistinguishedName")) Then
          DistinguishedName=""
          set ogroupL=nothing
        else
          DistinguishedName=oRecordset2.Fields("DistinguishedName")
          set ogroupL=getobject("LDAP://"&distinguishedName)
        end if
    End If

    Set oRecordset3 = oConnection.Execute("<LDAP://"&SourceDomain&">;(&(objectCategory=group)(Name="&Nom&"));name,samaccountname,DistinguishedName,PrimaryGroupToken;subtree")
    If Not oRecordset3.EOF Then
        if isnull(oRecordset3.Fields("DistinguishedName")) Then
          DistinguishedName=""
          set ogroupG2=nothing
        else
          DistinguishedName=oRecordset3.Fields("DistinguishedName")
          set ogroupG2=getobject("LDAP://"&distinguishedName)
        end if
    End If

    on error resume next

    oGroupL.Add(oGroupG.Adspath)
    If err.number<>0 Then
      If Err.number=-2147019886 Then
        wscript.echo "Le groupe "&Nom&"-G du domaine "&DestDomain&" est deja membre du groupe "&Nom&"-L"
      Else
        wscript.echo "Erreur sur le groupe "&Nom
      End If
      Err.clear
    Else
      Wscript.echo "Ajout du groupe "&Nom&"-G du domaine "&SourceDomain&"au groupe "&Nom&"-L"
    End If

    oGroupL.Add(oGroupG2.AdsPath)
    If err.number<>0 Then
      If Err.number=-2147019886 Then
        wscript.echo "Le groupe "&Nom&"-G du domaine "&DestDomain&" est deja membre du groupe "&Nom&"-L"
      Else
        wscript.echo "Erreur sur le groupe "&Nom
      End If
      Err.clear
    Else
      Wscript.echo "Ajout du groupe "&Nom&"-G du domaine "&DestDomain&"au groupe "&Nom&"-L"
    End If

    on error goto 0

    end function

     

     

    Ton problème est peut lié aux types de groupes utilisés qui n'autorisent pas l'inclusion souhaitée.

     

    Ex: Global d'un domaine vers un Global d'un autre domaine

     

    Les 2 domaines sont bien en mode natifs?

     

    A+

    jeudi 31 juillet 2008 09:48

  • Bonjour,

    J'ai essayé avec la fonction .Add mais elle n'a pas eu plus de succès.

    Par contre dans mon code je récupère des objets et la connexion se ferme ensuite ... ça vient peut être de là.
    Dans votre code vous ouvrez une connexion persistante !

    Je vais essayer avec
    une connection ADODB et je vous tiens au courant.

    PS1 : J'essaye bien de mettre des GGL dans des GDL !
    PS2 : Les 2 domaines sont bien en natifs.

    Merci pour votre aide.

    Olivier Isler
    jeudi 31 juillet 2008 09:57
  • Bonsoir

     

    le code d'erreur que vous avez provient probablement des noms de groupes ou des chemins (distinguished name) utilisés.

    => L'erreur signifie "No such name..."

    Par exemple, si les chemins ou noms contiennent des caractères spéciaux (comme le /), il faut ajouter le \ dans la chaine d'accès. Vérifier les espaces et autres caractères spéciaux (accentués), notamment en regardant avec ADSIEDIT.MSC pour voir le comment ces caractères sont interprétés.

     

    A+

     

     

    jeudi 31 juillet 2008 21:11

  • Bonjour,

    Réponse tardive sur le sujet. Je n'ai pas eu le temps de m'en occuper mais j'ai pu replonger dedans il y a quelques jours et j'ai "enfin" trouvé une solution.

    Je précise le problème : impossibilité de rajouter un objet d'un domaine A appartenant à une forêt A, comme membre d'un groupe d'un domaine B appartenant à une forêt B en utilisant un script (ça marche parfaitement à la main .. but real men don't click ...).
    Message d'erreur : L'objet spécifié ne se trouve pas sur le serveur.

    Et voici le workaround : utiliser le SID de l'objet avec cette fonction

    '********************************************************************
    Dim oProv, oGroup, oValue, oString, oObj
       
    Set oProv = GetObject("LDAP:")
    Set oGroup = oProv.OpenDSObject("LDAP://" & targetdc & "/" & targetDName, vbnullstring, vbnullstring, 1)

    For each objMember in objGroup.Members
               
            Set oObj = oProv.OpenDSobject("LDAP://" & sourcedc & "/" & objMember.distinguishedName, vbnullstring, vbnullstring,1)
            oValue = oObj.Get("objectSid")
            oString = OctetString2String(oValue)
            oGroup.PutEx ADS_PROPERTY_APPEND, "member", Array("<Sid=" & oString & ">")
            oGroup.SetInfo
       
            If err.number<>0 Then
                  WScript.Echo "Error -> " & Err.Number & " : " & Err.Description
            End If
          
    Next

    Function OctetString2String(byVal OctetStr)
    dim result
    dim j, loByte, hiByte

        result = ""
        for j = lbound(OctetStr) to ubound(OctetStr)
            hiByte = ascb(midb(OctetStr,j+1,1))
            loByte = hiByte mod 16
            hiByte = hiByte \ 16
            result = result & hex(hiByte) & hex(loByte)
        next

        OctetString2String = result
    End Function
    '********************************************************************

    Et j'arrive enfin à faire marcher le script. Le seul petit probleme c'est que, de temps en temps, le SID n'est pas résolu et dans le target group j'obtiens un objet "<sid=xxxxxxx>".
    Mais le principal est que ça fonctionne.

    Cordialement,

    Olivier
    mardi 26 août 2008 14:22