How to Add Members to Groups using Classic Provisioning (No Portal)

Answered How to Add Members to Groups using Classic Provisioning (No Portal)

  • Monday, December 31, 2012 2:28 PM
     
     

    Can anyone point me to some example VB .NET code to add users to groups?  I am using VB .NET code called from a MV Rules Extension to Provision/De-provision users into AD (classic provisioning ... I am not using FIM Portal).  I need to add users to groups and cannot find any VB .NET examples on how to add users to groups.  For example, if an employee comes from our HR feed as a new Corporate Office employee, then I need to add the user to AD (I got that part working) and also add the user to the group 'Corp'.

All Replies

  • Tuesday, January 01, 2013 2:04 PM
     
     Answered

    As far as I know, you can't do this in your provisioning code. You need to either calculate membership in some external source (SQL or similar) and flow this through the sync engine. In most cases, I flow enough information out to a SQL database where I create a Stored Procedure or some triggers to populate a multivalue table (see SQL MA usage). Also, I've used my PowerShell MA and done calculations in PowerShell (reading the HR feed and calculating membership as part of the HR import, if it is simple data.

    So basically, flow the data to an external source where membership can be calculated.


    Regards, Soren Granfeldt
    blog is at http://blog.goverco.com | twitter at https://twitter.com/#!/MrGranfeldt

  • Thursday, January 03, 2013 8:33 PM
     
      Has Code

    Actually, Søren is right, you cant do this in your provisioning code, because you can only run the .net code to add the user into Active Directory Group, only if the user is present in the active directory.

    You can however run a powershell script or a .net code to add new users after all your MA runs have been completed.

    I would suggest to create a text file saving the accountname of new users in your provisioning code and then run a script to read that file, add users to group and then clear the text file, after the users have been created in the active directory.

    for .NET code i would suggest you look into DirectoryEntry Class.

    I have a vbs code below, feel free to use it :), it takes accountnames from a text file and add them into a group.

    'VB SCRIPT: Add Members from List to a Group
    'By: Furqan Asghar
    
    
    on error resume next
    
    Dim ADUser
    Dim Group 
    Dim FromDN
    
    Group = "CN=GROUP_NAME,OU=GROUP_OU"
    
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFile = objFSO.OpenTextFile("C:\FolderA\LOG - Users Added from List to " & Group & ".txt", 8, True)
    
    Set objUserFile = objFSO.OpenTextFile("C:\ADInputFiles\AddUsersToGroupLogonName.txt", 1)
    
    objFile.WriteLine("---------------------------------------------------------------------")
    objFile.WriteLine("")
    objFile.WriteLine("--------------------- LOG for " & Now() & " ---------------------------------")
    objFile.WriteLine(Group)
    objFile.WriteLine("From Logon Names")
    objFile.WriteLine("---------------------------------------------------------------------")
    objFile.WriteLine("")
    
    objFile.WriteLine(("Added to Group") & vbTab & ("Member") & vbtab & "")
    
    intCounter = 0
    intCounterErr = 0
    
    Set objGroup = GetObject("LDAP://" & Group & ",dc=domain,dc=com")
    
    Do While Not objUserFile.AtEndOfStream 
        ADUser = objUserFile.ReadLine
        
        Set objUser = Nothing
    	
        IF ADUser = "" THEN
        ELSE
        
    			Set objConnection = CreateObject("ADODB.Connection")
    			objConnection.Open "Provider=ADsDSOObject;"
    			Set objCommand = CreateObject("ADODB.Command")
    			objCommand.ActiveConnection = objConnection
    			objCommand.Properties("Page Size") = 1000
    			objCommand.CommandText = "<GC://dc=domain,dc=com>;" & _
    									 "(&(objectCategory=User)(sAMAccountName=" & ADUser & "));distinguishedName;subtree"
    			Set objRecordSet = objCommand.Execute
    
    			RecordFound = False
    			
    			If (Not objRecordSet.EOF) Then
    				Set objUser = GetObject("LDAP://" & objRecordSet.Fields("distinguishedName"))
    				ADUserADsPath = objUser.ADsPath
    				RecordFound = True
    			End If
    		
    		If RecordFound Then
    			Err.clear()
    			objGroup.add(ADUserADsPath)
    			if Err then
    				intCounterErr = intCounterErr + 1
    		  		objFile.WriteLine("ERROR" & vbTab & ADUserADsPath & vbTab & Err.Description & vbTab & "")
    		  		wscript.echo "ERROR" & vbTab & ADUserADsPath & vbTab & Err.Description & vbTab & ""
    			else
    				intCounter = intCounter + 1
    		  		objFile.WriteLine(Group & vbTab & ADUserADsPath & vbTab & "")
    			end if
    		Else
    	  		objFile.WriteLine("Record not Found" & vbTab & ADUser & vbTab & Err.Description & vbTab & "")
    		End If
    	End If
    Loop
     
    objFile.WriteLine(VbCrLf & "A total of " & intCounter & " Members were Added.")
    objFile.WriteLine(VbCrLf & "A total of " & intCounterErr & " Members generated Error.")
    objFile.WriteLine("---------------------------------------------------------------------")
    
    objFile.Close()
     
    objConnection.Close
    
    
    
    Function OctetToHexStr(arrbytOctet)
      ' Function to convert OctetString (byte array) to Hex string.
    
      Dim k
      OctetToHexStr = ""
      For k = 1 To Lenb(arrbytOctet)
        OctetToHexStr = OctetToHexStr _
          & Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2)
      Next
    End Function
    
    Function HexGuidToGuidStr(strGuid)
      ' Function to convert Hex Guid to display form.
      Dim k
    
      HexGuidToGuidStr = ""
      For k = 1 To 4
        HexGuidToGuidStr = HexGuidToGuidStr & Mid(strGuid, 9 - 2*k, 2)
      Next
      HexGuidToGuidStr = HexGuidToGuidStr & "-"
      For k = 1 To 2
        HexGuidToGuidStr = HexGuidToGuidStr & Mid(strGuid, 13 - 2*k, 2)
      Next
      HexGuidToGuidStr = HexGuidToGuidStr & "-"
      For k = 1 To 2
        HexGuidToGuidStr = HexGuidToGuidStr & Mid(strGuid, 17 - 2*k, 2)
      Next
      HexGuidToGuidStr = HexGuidToGuidStr & "-" & Mid(strGuid, 17, 4)
      HexGuidToGuidStr = HexGuidToGuidStr & "-" & Mid(strGuid, 21)
    End Function
    
    

  • Friday, January 04, 2013 7:43 AM
     
     
    Did you manage to resolve this? Included in the download section with my PowerShell MA (http://blog.goverco.com/p/powershell-management-agent.html) you'll find scripts to create SQL tables and SP to do simple member calculations (see Microsoft SQL sample scripts). These tables combined with the PS MA could maybe be used.

    Regards, Soren Granfeldt
    blog is at http://blog.goverco.com | twitter at https://twitter.com/#!/MrGranfeldt

  • Monday, January 07, 2013 8:37 PM
     
      Has Code

    Hi,

    This is possible using the csentry "member" attribute of the "group" object in AD MA.

    In "Configure Attrbute Flow" add an export mapping with Rule Extension to the "member" attribute.

    You have to add the exact DN of each user and every user added to the "member" attribute must exist in Active Directory before exporting the group/s, that's why you have first to export users to AD and then export groups with membership.

    csentry("member").Values.Add(dn)


    Patrick Layani

  • Tuesday, January 08, 2013 2:20 PM
     
     
    Thanks for the suggestions.  I think I might try Furqan's suggestion of exporting the newly added users' DNs to a text file and then finally run a new MA to import from the text file and export the member attribute using Patrick's suggestion.  (??)
  • Wednesday, January 09, 2013 7:24 AM
     
     

    Hey Andy

    Looks like a workable solution to me. BUT there can be other efficient ways of doing it, firstly i thought you weren't using AD MA to sync groups at all, now it seems like that you will be, and if you will be then there is other better solutions to it.

    Patrick Layani suggestion is a good one too. The only thing here is that where would you get the DN in the

    csentry["member"].Values.Add(DN);

    If it was for the MV extension i would take a DataTable (add DNs to it) as the MV Extension keeps variables and values persistant unless it unloads (sometime after all the RUNS have been finished).

    I am not sure that the Rules Extension would do the same or no, but its worth a try.

    Create a DataTable in the rules extension and add DNs to it and follow Patricks suggestion and try to get the DN from the DataTable.

    If it dosent work, then you might consider saving the DNs to the test file and reading it back from the .NET code itself.

    Also Exporting the AD MA might generate errors like 'missing object exception', dont panic :) using dual export in your run profiles will save this issue.

    hope this helps

  • Wednesday, January 09, 2013 8:20 PM
     
     

    Also, just to give you another option:

    1) Create an attribute on the user called 'groups' and populate this attribute from HR

    2) Create two views on the FIMSynchronisationService database: one which contains a list of all users and groups, and a multivalue table joining them together. Note, there are certain risks creating views on the FIMSynchronisationService DB and I would say this is definitely in the 'not supported' category, but I am aware of some major MS partners doing it this way

    3) Use the SQL MA to connect to the views you created to import the fully-formed groups.

    Depending on your level of access to HR, you could even create those two views directly on the HR database and skip steps 1 and 2. Again, probably not recommended to be creating views on the HR database, but my experience is that HR tend to do this anyway, as HR never wants to give you full access to employee data (particularly when you only need access to personal details and not payroll details), so in that case it's probably not an issue. There's also a certain elegance to being able to just perform a single import and get all the users and groups in a single MA.

    Also worth noting is that using the methods we're describing in this thread, you will be taking ownership of that group entirely - all members that meet your role criteria will be in these groups, and those that do not will be removed from the groups. FIM becomes authoritative. I only mention this because often I get clients asking me to add users to 'initial groups, so we can move them after' - which isn't really possible using this method.


    MCTS: Forefront Identity Manager 2010, Configuring

  • Monday, January 14, 2013 8:06 PM
     
     
    Thanks to all for the suggestions.  I still have not had a chance to test this, as I have been too busy with other things.