Automatically submit requests to IT Shop

Hello

I have some 8000 users that I need to automatically request and assign to a business role. The Shelf and product are functioning fine for new users, but I need to migrate some 8000 users to show as having been approved for this product. Any ideas on how I do this?

Regards

Stuart

  • You can create the PersonInOrg entries as direct assignments (perhaps from CSV or programmatically) and then for each assignment, use the CreateITShopOrder customizer method as described here: https://support.oneidentity.com/technical-documents/identity-manager/8.1.3/it-shop-administration-guide/20#TOPIC-1483139

    Or you can create PersonWantsOrg entries programmatically, e.g. using examples from 03 Create DB objects.vb and 19 PropertyBag.vb in "Modules\QBM\dvd\AddOn\SDK\ScriptSamples\03 Using database objects" on the installset. 

  • P.s. you are free to use this solution on your own risk (test first)... 

    I've created a small function that can be used to fire the "CreateITShopOrder customizer method" in bulk

    Public Function CCC_PersonWantsOrg_CreateITShopOrder( _
    	ByVal uidMember As String, _
    	ByVal uidEntitlement As String, _
    	ByVal memberTableName As String) As Boolean
    	
    	Dim f As ISqlFormatter = Session.SqlFormatter
    	
    	Dim tableNames() As String = memberTableName.ToLower.Split({"has", "in"},
    		StringSplitOptions.RemoveEmptyEntries)
    		
        If Not tableNames.Count = 2 Then
    		Throw New Exception("Not a valid membertable")
    	End If
    	
    	If Not Session.Source.Exists(tableNames(0), 
    		f.UidComparison(String.Format("UID_{0}", tableNames(0)), uidMember)) Then
    		
    		Throw New Exception((String.Format("Member {0} not found", uidMember)))
    	End If
    	
    	If Not Session.Source.Exists(tableNames(1), 
    		f.UidComparison(String.Format("UID_{0}", tableNames(1)), uidEntitlement)) Then
    		
    		Throw New Exception((String.Format("Entitlement {0} not found", uidEntitlement)))
    	End If
    	
    	Dim w As String = f.AndRelation( _
    		f.UidComparison(String.Format("UID_{0}", tableNames(0)), uidMember), _
    		f.UidComparison(String.Format("UID_{0}", tableNames(1)), uidEntitlement)
    	)
    	
    	Dim XObjectKeyMembership As String= ""
    	If Not Session.Source.TryGetSingleValue(memberTableName, "XObjectKey", w, XObjectKeyMembership) Then
    		Throw New Exception("Membership not found")
    	End If
    	
    	Try
    		Dim membership As ISingleDbObject = Connection.CreateSingle(New DbObjectKey(XObjectKeyMembership))
    		Dim params As String() = New String() {""}
    		membership.Custom.CallMethod("CreateITShopOrder", params)
    		membership.Save()
    	Catch
            Return False
        End Try
    			
    	Return True
    End Function

    Create custom event on table 'PersonInOrg' eventname = 'CreateITShopOrder'
    Create a simple process in the assignment table in your case "PersonInOrg": ScriptExec
    that triggers on the event: "CreateITShopOrder"

    ScriptName: 'CCC_PersonWantsOrg_CreateITShopOrder'
    Parametervalue0: Value = $UID_Person$
    Parametervalue1: Value = $UID_Org$
    Parametervalue2: Value = 'PersonInOrg'

    Compile...

    Then directly assign all the 8000 users to the b-role 
    Use the Object Browser on the  'PersonInOrg' table to filter and multi-select the 8000 users...
    Then select the tab 'Actions' > 'Events' > 'CreateITShopOrder' 
    After all the jobs are done remove the direct assignments for the 8000 users.
    That should do it!

  • Thanks all, 

    That mostly worked. I just had to get the params right for the CallMethod.

    I needed to add the UID for itShopOrg, then it worked. I still have to flesh out some more, but this is what I have now that works.

    Public Function CCC_PersonWantsOrg_CreateITShopOrder( _
    	ByVal uidMember As String, _
    	ByVal uidEntitlement As String, _
    	ByVal memberTableName As String, _
    	ByVal itShopOrg As String) As Boolean
    	
    	Dim uidItShopOrg As String = CCC_GetUIDFromDescriptiveName( _
    	"O365 - License Group - ZFLC-M365-E3-ARU-BASIC", _
    	"Ident_Org", _
    	"ITShopOrg", _
    	"UID_ITShopOrg")
    	
    	Dim f As ISqlFormatter = Session.SqlFormatter
    	
    	Dim tableNames() As String = memberTableName.ToLower.Split({"has", "in"},
    		StringSplitOptions.RemoveEmptyEntries)
    		
        If Not tableNames.Count = 2 Then
    		Throw New Exception("Not a valid membertable")
    	End If
    	
    	If Not Session.Source.Exists(tableNames(0), 
    		f.UidComparison(String.Format("UID_{0}", tableNames(0)), uidMember)) Then
    		
    		Throw New Exception((String.Format("Member {0} not found", uidMember)))
    	End If
    	
    	If Not Session.Source.Exists(tableNames(1), 
    		f.UidComparison(String.Format("UID_{0}", tableNames(1)), uidEntitlement)) Then
    		
    		Throw New Exception((String.Format("Entitlement {0} not found", uidEntitlement)))
    	End If
    	
    	Dim w As String = f.AndRelation( _
    		f.UidComparison(String.Format("UID_{0}", tableNames(0)), uidMember), _
    		f.UidComparison(String.Format("UID_{0}", tableNames(1)), uidEntitlement)
    	)
    	
    	Dim XObjectKeyMembership As String= ""
    	If Not Session.Source.TryGetSingleValue(memberTableName, "XObjectKey", w, XObjectKeyMembership) Then
    		Throw New Exception("Membership not found")
    	End If
    	
    	Try
    		Dim membership As ISingleDbObject = Connection.CreateSingle(New DbObjectKey(XObjectKeyMembership))
    				
    		membership.custom.CallMethod("CreateITShopOrder", uidItShopOrg, uidMember, "")
    		membership.Save()
    	Catch ex As Exception
            Throw New Exception(ViException.ErrorString(ex))
    		Return False
        End Try
    			
    	Return True
    End Function

  • One thing I am struggling with is How to pass a script to change the "OrderReason". Any ideas would be greatly appreciated

  • Hi,

    Here's an example:

    You can see that the method is called like this:

    baseObjectN.CallMethod("CreateITShopOrder", "CCC_CreateAutoApprovedPWO_ExtraInfo")

    And it references the custom sub script as "CCC_CreateAutoApprovedPWO_ExtraInfo".

    In that script you can see that by default it gets passed 2 parameters:

    Public Sub CCC_CreateAutoApprovedPWO_ExtraInfo(ByRef dbAssignment As IEntity, ByRef dbPWO As IEntity)

    The thing that is being ordered and the pwo object that is being created.

    So in that script you can reference information about the assignment and fill values for the PWO.

    Ours is quite complicated but usually you would just fill the person who made the order and the reason.

    HTH, Barry.


    '######################################---BEGINING OF SCRIPT----####################################
    '---------------------------------------------------------------------------------------------------
    '######################################---DISPATCHING SCRIPT----####################################
    'This scripts takes as input 3 values: UID_Person for which request has to be raised, XObjectKeyEntitlement which is the effective entitlement that should be assigned as result of auto approved request and Info, which will be used in reason.
    Public Function CCC_CreateAutoApprovedPWO(ByVal UID_Person As String, ByVal XObjectKeyEntitlement As String, ByVal Info As String) As String
    Dim retValue As String = Nothing
    Dim dbKey As DbObjectKey = New DbObjectKey(XObjectKeyEntitlement)
    Dim baseObject As ISingleDbObject = Connection.CreateSingle(dbKey)
    Dim sourceTable As String = dbKey.GetTable(Connection).Tablename.ToString.ToLowerInvariant
    Dim baseObjectN As IEntity = session.Source.Get(New DbObjectKey(XObjectKeyEntitlement))
    Dim UID_ent As String
    ' Get the SQL formatter for our connection
    Dim f As ISqlFormatter = Session.SqlFormatter

    'There are 2 approaches:
    ' 1. entitlement assignment for which PWO has to be created already exists (is directly assigned) and it should be converted to indirect assignment where customizer methods can be used
    ' 2. entitlement assignment for which PWO has to be created doesn't exist yet and customizer method can't be used at that point.

    If sourceTable.Equals("PersonHasEset".ToLowerInvariant) Then
    Try
    baseObjectN.CallMethod("CreateITShopOrder", "CCC_CreateAutoApprovedPWO_ExtraInfo")
    baseObjectN.Save(Session)
    Catch ex As Exception
    If Not ex.ToString.Contains("There is already an active request") Then
    Throw New Exception(ViException.ErrorString(ex))
    End If
    End Try
    ElseIf sourceTable.Equals("PersonInOrg".ToLowerInvariant) Then
    Dim where As String = f.Comparison("ObjectKeyAssignTarget", baseObjectN.CreateWalker(Session).GetValue("FK(UID_Org).XObjectKey").String, ValType.String)
    'Get the UID_AccProduct of the Assignment resource
    Dim uidAccProduct As String = Session.Source.GetSingleValue(Of String)("QERAssign", "UID_AccProduct", where)
    'Get the UID_ITShopOrg of the AccProduct
    Dim where2 As String = f.UidComparison("UID_AccProduct", uidAccProduct)
    Dim uidOrgProduct As String = Session.Source.GetSingleValue(Of String)("ITShopOrg", "UID_ITShopOrg", where2)

    Dim uidPersonOrdered As String = baseObjectN.GetValue("UID_Person")

    Try
    baseObjectN.CallMethod("CreateITShopOrder",uidOrgProduct,uidPersonOrdered, "CCC_CreateAutoApprovedPWO_ExtraInfo")
    baseObjectN.Save(Session)
    Catch ex As Exception
    If Not ex.ToString.Contains("There is already an active request") Then
    Throw New Exception(ViException.ErrorString(ex))
    End If
    End Try
    ElseIf sourceTable.Contains("PersonIn".ToLowerInvariant) _
    OrElse sourceTable.Contains("ADSAccountIn".ToLowerInvariant) _
    OrElse sourceTable.Contains("UnsAccountBIn".ToLowerInvariant) _
    OrElse sourceTable.Contains("PersonHas".ToLowerInvariant) _
    AndAlso Not sourceTable.Contains("PersonHasEset".ToLowerInvariant) _
    AndAlso Not sourceTable.Contains("PersonInOrg".ToLowerInvariant)Then

    Try
    baseObjectN.CallMethod("CreateITShopOrder", "CCC_CreateAutoApprovedPWO_ExtraInfo")
    baseObjectN.Save(Session)
    Catch ex As Exception
    If Not ex.ToString.Contains("There is already an active request") Then
    Throw New Exception(ViException.ErrorString(ex))
    End If
    End Try
    Else
    Throw New ViException("Script can't handle source data. Please validate code and source information for: " & XObjectKeyEntitlement)

    End If

    Return retValue
    End Function

    '######################################---END OF SCRIPT----#########################################
    '######################################---BEGINING OF SCRIPT----####################################
    Public Sub CCC_CreateAutoApprovedPWO_ExtraInfo(ByRef dbAssignment As IEntity, ByRef dbPWO As IEntity)
    'Common variables
    Dim tbl As String = dbAssignment.Tablename.ToString.ToLowerInvariant
    Dim r1 As String = Nothing
    Dim userCreated As String = dbAssignment.GetValue("XUserInserted").ToString
    Dim rFinal As String = Nothing
    Dim PersonOrdered As String = Nothing
    Dim dbKey As DbObjectKey = New DbObjectKey(dbAssignment.GetValue("XObjectKey").ToString)
    Dim ProductOrdered As String = String.Empty
    ' Get the SQL formatter for our connection
    Dim f As ISqlFormatter = Session.SqlFormatter
    Dim where As String = String.Empty


    'Code below can be adjusted based on the table for which the method is called
    If tbl.Equals("PersonHasEset".ToLowerInvariant) Or _
    tbl.Equals("ADSAccountInADSGroup".ToLowerInvariant) Or _
    tbl.Equals("PersonInOrg".ToLowerInvariant) Then
    'Reason for Applications Framework
    r1 = Session.Config.GetConfigParm("Custom\AccessManagement\Applications\AutoRequestsReasons\ApplicationRoleMembershipChange")
    rFinal = r1 & " Entry added by: " & userCreated
    'rFinal = r1 & " The request was automatically approved due to the migration to the new version"
    End If


    ' Determine the person ordered and the product ordered
    Select Case tbl
    Case "PersonHasEset".ToLowerInvariant
    PersonOrdered = dbKey.Keys(1)
    where = f.UidComparison("UID_ESet", dbKey.Keys(0))
    ProductOrdered = Session.Source.GetSingleValue(Of String)("ESet", "UID_AccProduct", where)

    Case "ADSAccountInADSGroup".ToLowerInvariant
    PersonOrdered = dbAssignment.CreateWalker(Session).GetValue("FK(UID_ADSAccount).UID_Person").String
    where = f.UidComparison("UID_ADSGroup", dbKey.Keys(1))
    ProductOrdered = Session.Source.GetSingleValue(Of String)("ADSGroup", "UID_AccProduct", where)

    Case "PersonInOrg".ToLowerInvariant
    PersonOrdered = dbKey.Keys(1)
    where = f.Comparison("ObjectKeyAssignTarget", "<Key><T>Org</T><P>" & dbKey.Keys(0) & "</P></Key>", ValType.String, CompareOperator.Equal, FormatterOptions.NonUnicodeLiterals)
    ProductOrdered = Session.Source.GetSingleValue(Of String)("QERAssign", "UID_AccProduct", where)

    Case "PersonHasRPSReport".ToLowerInvariant
    PersonOrdered = dbKey.Keys(0)
    where = f.UidComparison("UID_RPSReport", dbKey.Keys(0))
    ProductOrdered = Session.Source.GetSingleValue(Of String)("RPSReport", "UID_AccProduct", where)

    Case "PersonHasTSBAccountDef".ToLowerInvariant
    PersonOrdered = dbKey.Keys(0)
    where = f.UidComparison("UID_TSBAccountDef", dbKey.Keys(0))
    ProductOrdered = Session.Source.GetSingleValue(Of String)("TSBAccountDef", "UID_AccProduct", where)

    Case Else
    Throw New ViException("Script 'CCC_CreateAutoApprovedPWO_ExtraInfo' - unrecognised assignment has been passed: " & dbAssignment.GetValue("XObjectKey").ToString)

    End Select

    ' The following code calls the pre-defined SQL to get the JA
    Dim JobAssignment As String = Nothing
    Dim runner = session.Resolve(Of VI.DB.DataAccess.IStatementRunner)()
    Using reader = runner.sqlExecute("CCC_F_GetJAsForPersAndProd", {
    QueryParameter.Create("uidPerson", PersonOrdered),
    QueryParameter.Create("uidAccProduct", ProductOrdered)})
    While reader.read()
    JobAssignment = reader.getString(0)
    End While

    reader.close()
    End Using

    'Populate values in PWO:
    dbPWO.PutValue("OrderReason", rFinal)
    If Not String.IsNullOrEmpty(JobAssignment) Then
    dbPWO.PutValue("CCC_UID_LDAPAccount", JobAssignment)
    End If

    End Sub
    '######################################---END OF SCRIPT----#########################################