We had a business case whereby a filter couldn’t really create groups which catered for the purpose. We also needed to put in some static members (Explicit Members) in it.
Now by default a /Group in FIMService can either be Explicit or a Filter type group. But a Set allows you to have an explicit as well as filter on it.
WARNING: Many custom attributes are used for our purpose but you hopefully will get the gist of it
CREATE
So came up with a design for such groups (we identify them by Autogen and have an attribute called accountType)
- Create a Set with Autogen-{GroupName} with an accountType = AutogenSet
- Set the filter and explicit members needed on the set
- Create a filter group with Autogen-{GroupName} with an accountType = AutogenGroup
- Put the ResourceID of the new group in the set to an attribute called ‘connectedGroupObjectID’ and viceversa to ‘connectedSetObjectID’ – This it have relation between the group and set
- Set the filter on this group as
1 |
/*[((ObjectType = "Person") or (ObjectType = "Group")) and (ObjectID = /Set[ObjectID ="{connectedSetObjectID}"]/ComputedMember) |
CLEANUP
- Create a auth workflow with delete resource and target = [//Target/connectedSetObjectID]
- Create a set which has ‘All Autogen Groups’
- Create a MPR which ties the above i.e. when a delete resource happens for any in set ‘All Autogen Groups’ then run the Auth workflow which will delete the set as well
SCRIPT
Wrote a script so that these groups, sets and links can be created in one go using FIM/MIM Service Powershell Module.
NOTE
- I assume user already knows the XPATH for his filter (Will help you on how to create it easily as well in a post coming soon).
- Many custom attributes have been used in FIMService but you get the bigger picture and not necessarily needed for your environment.
- I am really bad at powershell so don’t be surprised if you see some ‘what the hell did he do that for?’ moment 🙂 You will definitely find mistakes but hey.. works for me.. Still please point it out 🙂
LOGIC
This script was written by me quite specific for our environment and therefore contains a lot of custom attributes and logic. This is just to give an idea what we do / can do with the idea. I have decided not to dumb it down and present it as-is. If you get confused somewhere please do contact me or leave a comment
- Asks for DisplayName (Mandatory)
- Asks for a requestedAccountName (Mandatory in our env to generate sAMAccountName and AccountName)
- Asks for a owner AccountName / uid (Mandatory in our environment to set as the owner of the group)
- Asks if the Group will have a mail address (if so then we populate some additional attributes to provision to GoogleApps)
- If Mail Enabled then asks for some additional attributes to be set like
- Mail Prefix (to generate the mail address)
- Posting Permission
- To be hidden from Global Address List or not
- Is it going to be used as a Security Group in AD (sets as Distribution else as MailEnabledSecurity)
- If not then sets it as a Security Group
- If Mail Enabled then asks for some additional attributes to be set like
- Asks for the XPATH Filter – then it goes and checks if it’s correct and does return some users back else exists.
- Creates the Set and adds the above filter to it
- Creates the Group
- Sets the filter pointing to the set above
- Links the two
- Done
The only thing it doesn’t do is setting explicit members to the set which is done manually after creation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
Import-Module LithnetRMA Set-ResourceManagementClient -BaseAddress "http://YOUR-FIMSERVICE-HOST:5725" Function MailSettings() { $requestedmailprefix = Read-Host "Requested Mail Prefix" if (!$requestedmailprefix) { Write-Warning "Enter a value" exit } Write-Host "Posting Permissions" -ForegroundColor Cyan Write-Host "[1] Anyone Can Post" Write-Host "[2] All Monash Users Can Post" Write-Host "[3] All Members Can Post" Write-Host "[4] Selected Members Can Post" Write-Host "[5] No One Can Post" Write-Host $select = Read-Host "Select one of the posting permission" switch ($select) { 1 { $gappswhocanpost = "ANYONE_CAN_POST" } 2 { $gappswhocanpost = "ALL_IN_DOMAIN_CAN_POST" } 3 { $gappswhocanpost = "ALL_MEMBERS_CAN_POST" } 4 { $gappswhocanpost = "ALL_MANAGERS_CAN_POST" } 5 { $gappswhocanpost = "NONE_CAN_POST" } default { Write-Warning "Please make correct selection" exit } } $hidemail = Read-Host "Hide From GAL (y/n)" switch($hidemail) { y { $hidefromgal = $true } n { $hidefromgal = $false } default { Write-Warning "Please input y or n only" exit } } $issecuritygroup = Read-Host "Is it a security group (y/n)" switch ($issecuritygroup) { y { $grouptype = "MailEnabledSecurity" } n { $grouptype = "Distribution" } default { Write-Warning "Please input y or n only" exit } } return ($requestedmailprefix, $gappswhocanpost, $hidefromgal, $grouptype) } Function SetConnectedGroupObjectID ($setobjectid, $groupobjectid) { $set = Get-Resource -ID $setobjectid $set.connectedGroupObjectID = $groupobjectid try { Write-Host "Linking AutogenGroup to AutogenSet" -ForegroundColor Cyan Save-Resource $set } catch { Write-Warning ("Unable to link group to set:" + $_.Exception.Message) exit } } Function CreateAutogenGroup($groupname, $requestedaccountname, $requestedmailprefix, $grouptype, $setObjectID, $ownerObjectID, $gappswhocanpost, $hidefromgal) { $group = New-Resource -ObjectType Group $group.DisplayName = $groupname $group.requestedAccountName = $requestedaccountname $group.requestedMailPrefix = $requestedmailprefix $group.Type = $grouptype $group.accountType = "AutogenGroup" $group.Owner = $ownerObjectID $group.connectedSetObjectID = $setObjectID.Value $group.Domain = $env:USERDOMAIN $group.Filter = '<Filter xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Dialect="http://schemas.microsoft.com/2006/11/XPathFilterDialect" xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration">/*[((ObjectType = "Person") or (ObjectType = "Group")) and (ObjectID = /Set[ObjectID ="' +$setObjectID.Value+ '"]/ComputedMember)]</Filter>' $group.MembershipLocked = $true $group.Scope = 'Global' $group.MembershipAddWorkflow = "None" $group.gappsWhoCanPost = $gappswhocanpost $group.hideFromGal = $hidefromgal try { Write-Host "Creating AutogenGroup:" $group.DisplayName -ForegroundColor Cyan Save-Resource $group $groupobjectid = Get-Resource -ObjectType Group -AttributeName DisplayName -AttributeValue $group.DisplayName return $groupobjectid.ObjectID } catch { Write-Warning ("Unable to create group:" + $_.Exception.Message) exit } } Function CreateAutogenSet($DisplayName, $filter) { $set = New-Resource -ObjectType Set $set.DisplayName = "Autogen-" + $DisplayName $set.accountType = "AutogenSet" $set.Filter = '<Filter xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Dialect="http://schemas.microsoft.com/2006/11/XPathFilterDialect" xmlns="http://schemas.xmlsoap.org/ws/2004/09/enumeration">' +$filter+ '</Filter>' try { Write-Host "Creating AutogenSet:" $set.DisplayName -ForegroundColor Cyan Save-Resource $set $setObjectID = Get-Resource -ObjectType Set -AttributeName DisplayName -AttributeValue $set.DisplayName return $setObjectID.ObjectID } catch { Write-Warning ("Unable to create set:" + $_.Exception.Message) exit } } Function CheckFilter($filter) { try { $filtermembers = Search-Resources -XPath $filter -AttributesToGet ObjectID Write-Host "No of dynamic members found: " $filtermembers.Count -ForegroundColor Cyan } catch { $host.UI.WriteErrorLine("Bad Filter") exit } if ($filtermembers -eq $null) { $host.UI.WriteErrorLine("No Users found in new filter") exit } } Function CreateGroup() { Write-Host "Information Required for new Autogen Group" -ForegroundColor Cyan $groupname = Read-Host -Prompt "Enter Display Name" if (!$groupname) { Write-Warning "Display Name Value Missing" exit } $accountname = Read-Host -Prompt "Requested Account Name" if (!$accountname) { Write-Warning "Requested Name Value Missing" exit } $owner = read-host "Enter uid of the owner" if ($owner) { try { $ownerObjectID = Get-Resource -ObjectType Person -AttributeName AccountName -AttributeValue $owner.Trim() -AttributesToGet ObjectID } catch { Write-Warning "Invalid Owner" exit } } else { Write-Warning "UID of Owner Missing" exit } $mailinglist = Read-Host "Is this group mail enabled (y/n)" switch ($mailinglist) { y { $mailsettings = MailSettings $requestedmailprefix = $mailsettings[0] $gappswhocanpost = $mailsettings[1] $hidefromgal = $mailsettings[2] $grouptype = $mailsettings[3] } n { $grouptype = "Security" } default { Write-Warning "Please input y or n only" exit } } $filter = Read-Host -Prompt "Enter Filter" if ($filter) { CheckFilter($filter.Trim()) } else { Write-Warning "Filter is Missing" exit } $confirmcreation = Read-Host "Do you want to continue (y/n)" switch ($confirmcreation) { y { $newSetObjectID = CreateAutogenSet ($groupname) ($filter.Trim()) $newGroupObjectID = CreateAutogenGroup ($groupname) ($accountname) ($requestedmailprefix) ($grouptype) ($newSetObjectID) ($ownerObjectID.ObjectID.Value) ($gappswhocanpost) ($hidefromgal) SetConnectedGroupObjectID ($newSetObjectID) ($newGroupObjectID) Write-Host "AutogenGroup and AutogenSet Created!!!" -ForegroundColor Cyan } n { Write-Host "Exiting without creation" } default { Write-Warning "Please input y or n only" exit } } } CreateGroup |
To the sync side you will simply see one Group come out with Member attribute containing both ExplicitMembers and ComputedMembers and a combination.
Hope this helps someone in their “complex business” environment.
0 Comments