Random Entitlements

We have a requirement to split the user’s who get an entitlement between 2 groups. These are AD groups where they want half of users in GroupA and half in GroupB.

The only way I can see to do this is with a Powershell script called from an After Modify rule.

Has anyone else had this same type of requirement, and solved it differently?

Thanks,
Chris

What is the criteria for joining GroupA and GroupB? If there is a certain attribute on each user that will determine if they get assigned A or B, then this might be possible within IDN. If it is simply to have a 50/50 split, then I think this is only possible via the script as you are doing it now.

Also, are you able to share your use case? I’ve not yet heard of a customer requirement to split users with an entitlement evenly between two groups.

@colin_mckibben The client wants to spread WIFI use across 2 AD groups, and there may also be multiple groups in a location. So, for example, the London office has 2 WIFI groups that they want to split user access to.

You may be right, we may have to do this assignment using a PowerShell script.

Thanks,
Chris

I just had a thought. You could use the random number generator transform to generate random numbers to randomly split between two WIFI groups in any location. To do this, you would need to create a new identity profile mapping attribute called something like wifiGroup. The source would be your authoritative source that specifies the employee’s location, the attribute will be the location, and the transform will be a custom transform with the following logic.

POST /v3/transforms

Request Body:

{
    "name": "Random WIFI Group",
    "type": "concat",
    "attributes": 
    {
        "values": [
            {
                "type": "accountAttribute",
                "attributes": {
                    "sourceName": "Employees",
                    "attributeName": "location"
                }
            },
            ":",
            {
                "type": "lookup",
                "attributes": {
                    "table": {
                        "0": "1",
                        "1": "1",
                        "2": "1",
                        "3": "1",
                        "4": "1",
                        "5": "2",
                        "6": "2",
                        "7": "2",
                        "8": "2",
                        "9": "2"
                    },
                    "input": {
                        "type": "randomNumeric",
                        "attributes": {
                            "length": 1
                        }
                    }
                }
            }
        ]
    }
}

Once you run the aggregation, all of your identities should now have a new identity attribute called wifiGroup with the name of the location and the random WIFI group number, like London:1 or Dallas:2. Then, you can create roles for each WIFI group that you need to manage, and use the standard criteria builder to automatically assign users to roles based on their wifiGroup.

Each role can grant the appropriate AD group membership via an access profile.

This approach would have the benefit of being easily maintained and certified, since it’s using standard processes and roles to manage the access to WIFI groups, rather than a custom script. It would also make it easier to assign temporary WIFI access to identities that travel between locations, since the roles can be requestable.

However, the caveat here is the randomness, which you don’t really have control over. You can’t control the random number generator, which could produce more users in WIFI group 1 than group 2. Also, as users leave the company, you could see an imbalance if, coincidentally, more users in WIFI group 1 leave than group 2. If you truly need an even split, for reasons like WIFI load balancing, then you may want to look to your WIFI hardware vendor to see if there is a solution within their product that can do this, or at least plan for the event where you need to redistribute users across the two WIFI groups to balance them out. One contingency could be to add a “WIFI Group” account attribute to your authoritative source, and leave it blank. In the event you need to balance WIFI access, you could then manually set the “WIFI Group” attribute in the source for select identities. Just make sure you roles prefer to use the “WIFI Group” account attribute over the calculated identity attribute if it is present.

2 Likes

@chrisp, Great to see you again; let us know if the proposed solution above was able to help you!

@jordan.violet I haven’t had a chance to see if this will work yet, but it looks like @colin_mckibben has me pointing in the right direction. Now I just need to figure out what the client really needs!

This, like all of his comments/suggestions has me thinking of solutions in different ways.

Thanks,
Chris

1 Like

@colin_mckibben This worked great.

Thanks,
Chris

Hello,

I’ve been trying out this idea and it works great when the Identity attribute is first introduced in the Identity Profile. however it looks like it changes with every refresh. Would it be possible to set it when added to the Identity Profile and stay static?

Hmmmm. You could try wrapping the above transform in a conditional operation. If the attribute is null, then apply the transform. Otherwise, leave the value that is there. If that doesn’t work, you could try the same with a static transform and use comparisons in the velocity template to do the same.

Try it out, and if you find a solution let us know.

I will definitely try that, for the null in both cases how is it evaluated? as ‘’ or as a variable $null?

What would the condition statement look like?

Try using a firstValid transform.

Hmm Here’s what I’ve tried so far but getting errors for it

{
 "attributes":{
   "sharedGroup":{
     "attributes":{
       "name": "filingsharinggroup"},
     "type":"identityAttribute"},
   "Calculation": {
    "type": "concat",
    "attributes": {
        "values": [
            "Share Group:",
            {
                "type": "lookup",
                "attributes": {
                    "table": {
                        "00": "50",
                        "01": "01",
                        "02": "02",
                        "03": "03",
                        "04": "04",
                        "05": "05",
                        "06": "06",
                        "07": "07",
                        "08": "08",
                        "09": "09",
                        "10": "10",
                        "11": "11",
                        "12": "12",
                        "13": "13",
                        "14": "14",
                        "15": "15",
                        "16": "16",
                        "17": "17",
                        "18": "18",
                        "19": "19",
                        "20": "20",
                        "21": "21",
                        "22": "22",
                        "23": "23",
                        "24": "24",
                        "25": "25",
                        "26": "26",
                        "27": "27",
                        "28": "28",
                        "29": "29",
                        "30": "30",
                        "31": "31",
                        "32": "32",
                        "33": "33",
                        "34": "34",
                        "35": "35",
                        "36": "36",
                        "37": "37",
                        "38": "38",
                        "39": "39",
                        "40": "40",
                        "41": "41",
                        "42": "42",
                        "43": "43",
                        "44": "44",
                        "45": "45",
                        "46": "46",
                        "47": "47",
                        "48": "48",
                        "49": "49",
                        "50": "50",
                        "51": "01",
                        "52": "02",
                        "53": "03",
                        "54": "04",
                        "55": "05",
                        "56": "06",
                        "57": "07",
                        "58": "08",
                        "59": "09",
                        "60": "10",
                        "61": "11",
                        "62": "12",
                        "63": "13",
                        "64": "14",
                        "65": "15",
                        "66": "16",
                        "67": "17",
                        "68": "18",
                        "69": "19",
                        "70": "20",
                        "71": "21",
                        "72": "22",
                        "73": "23",
                        "74": "24",
                        "75": "25",
                        "76": "26",
                        "77": "27",
                        "78": "28",
                        "79": "29",
                        "80": "30",
                        "81": "31",
                        "82": "32",
                        "83": "33",
                        "84": "34",
                        "85": "35",
                        "86": "36",
                        "87": "37",
                        "88": "38",
                        "89": "39",
                        "90": "40",
                        "91": "41",
                        "92": "42",
                        "93": "43",
                        "94": "44",
                        "95": "45",
                        "96": "46",
                        "97": "47",
                        "98": "48",
                        "99": "49"
                    },
                    "input": {
                        "type": "randomNumeric",
                        "attributes": {
                            "length": 2,
                            "requiresPeriodicRefresh":"false"
                        }
                    }
                }
            }
        ]
    }
 },

 "value" :"#if(!$sharedGroup)$Calculation#{else}$sharedGroup#end"
 },
     "name": "Random Share Group - Testing",
     "type":"static",
    "internal": "false"
}

Hello this Transform works to ensure the attribute is not changed after the first run

    {
        "name": "Random Group - 1",
        "type": "static",
        "attributes": {
            "sharedGroup": {
                "attributes": {
                    "values": [
                        {
                            "attributes": {
                                "name": "sharedfilegroup"
                            },
                            "type": "identityAttribute"
                        },
                        {
                            "attributes": {
                                "value": "N/A"
                            },
                            "type": "static"
                        }
                    ]
                },
                "type": "firstValid"
            },
        "Calculation": {
            "type": "concat",
            "attributes": {
                "values": [
                    "Share Group:",
                    {
                        "type": "lookup",
                        "attributes": {
                            "table": {
                                "00": "50",
                                "01": "01",
                                "02": "02",
                                "03": "03",
                                "04": "04",
                                "05": "05",
                                "06": "06",
                                "07": "07",
                                "08": "08",
                                "09": "09",
                                "10": "10",
                                "11": "11",
                                "12": "12",
                                "13": "13",
                                "14": "14",
                                "15": "15",
                                "16": "16",
                                "17": "17",
                                "18": "18",
                                "19": "19",
                                "20": "20",
                                "21": "21",
                                "22": "22",
                                "23": "23",
                                "24": "24",
                                "25": "25",
                                "26": "26",
                                "27": "27",
                                "28": "28",
                                "29": "29",
                                "30": "30",
                                "31": "31",
                                "32": "32",
                                "33": "33",
                                "34": "34",
                                "35": "35",
                                "36": "36",
                                "37": "37",
                                "38": "38",
                                "39": "39",
                                "40": "40",
                                "41": "41",
                                "42": "42",
                                "43": "43",
                                "44": "44",
                                "45": "45",
                                "46": "46",
                                "47": "47",
                                "48": "48",
                                "49": "49",
                                "50": "50",
                                "51": "01",
                                "52": "02",
                                "53": "03",
                                "54": "04",
                                "55": "05",
                                "56": "06",
                                "57": "07",
                                "58": "08",
                                "59": "09",
                                "60": "10",
                                "61": "11",
                                "62": "12",
                                "63": "13",
                                "64": "14",
                                "65": "15",
                                "66": "16",
                                "67": "17",
                                "68": "18",
                                "69": "19",
                                "70": "20",
                                "71": "21",
                                "72": "22",
                                "73": "23",
                                "74": "24",
                                "75": "25",
                                "76": "26",
                                "77": "27",
                                "78": "28",
                                "79": "29",
                                "80": "30",
                                "81": "31",
                                "82": "32",
                                "83": "33",
                                "84": "34",
                                "85": "35",
                                "86": "36",
                                "87": "37",
                                "88": "38",
                                "89": "39",
                                "90": "40",
                                "91": "41",
                                "92": "42",
                                "93": "43",
                                "94": "44",
                                "95": "45",
                                "96": "46",
                                "97": "47",
                                "98": "48",
                                "99": "49"
                            },
                            "input": {
                                "type": "randomNumeric",
                                "attributes": {
                                    "length": 2,
                                    "requiresPeriodicRefresh": "false"
                                }
                            }
                        }
                    }
                ]
            }
        },
            "value": "#if($sharedGroup=='N/A')$Calculation#{else}$sharedGroup#{end}"
        },
        "internal": false
    }

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.