‘Sup PSHomies,
So lastblog was about adding members to a security group efficiently. Which got me thinking, can I reverse this process? If given the security groups with specified members, can I recreate the csv? I do love me a challenge!
So to pick up where we left off, I’ll be using the $addADGroupMembers to repopulate the csv…
#Security Matrix $Groups = $addADGroupMembers.Keys function Convert-ArrayToHash($a){ begin { $hash = @{} } process { $hash[$_] = $null } end { return $hash } } $template = [PSCustomObject]([Ordered]@{UserID=$null} + $($Groups | Convert-ArrayToHash))$addADGroupMembers has all the group names we need. I’m converting the group names into an empty hashtable. The $template variable is a custom object I’ll be using to move things along, I’ll explain as we go…
Now for the tricky part…
$arrMatrix = @() $Groups | ForEach-Object{ $GroupName = $_ if($addADGroupMembers.$_){ $addADGroupMembers.$_ | ForEach-Object{ if($arrMatrix.Count -eq 0) { $newItem = $template.PSObject.Copy() $newItem.UserID = $_ $newItem.$GroupName = '1' $arrMatrix += $newItem } else{ if($arrMatrix.UserID.contains($($_))){ $index = [array]::IndexOf($arrMatrix.UserID, $_) $arrMatrix[$index].$GroupName = '1' } else{ $newItem = $template.PSObject.Copy() $newItem.UserID = $_ $newItem.$GroupName = '1' $arrMatrix += $newItem } } } } }First we have an array to save the results. We only need to worry about groups with members. The $template has been initialized with $null. The first time it runs, $arrMatrix.Count will be zero, so just add this group to get things started. Here’s where it gets interesting, in order to add a newItem to the array I have to clone it first. Adding and saving this way makes sure I have a row with a unique UserID. Truth be told I had to google to figure this one out. Modifying $template and then assigning it to $newItem will only assign the reference. Change the value once more and every item in the array changes! I read it somewhere,it was fun to stumble on this… The more you know…
The next trick was to find the index of a UserID already saved. Google to the rescue! I found this neat trick of using [array]::IndexOf(). This will give you the first index with that value. Lucky for me, my UserIDs are unique:wink:Once I have my index I can add a value of ‘1’ to the group if the UserID is a member. If I can’t find a UserID then a new unique UserID is added to the $arrMatrix
Ok enough chit-chat here’s some code to play with
This should be your endresult
No too shabby eh?:stuck_out_tongue:
Ok Urv that’s all good and well but when am I going to use this?
Why thank you for asking!
If you’ve ever been in charge of implementing R ole B ased A ccess C ontrol then you could appreciate this. A security matrix like this is where I’d start, only now you don’t have to start from scratch…:wink:
Here’s how it works…
I created a security group Rol-Consultant for RBAC purposes. This group is a member of all the APP-* groups giving any member access by way of group nesting. Users who are amember of Rol-Consultantdon’t have to be adirect member for access. The down side of RBAC is it’s all or nothing, exceptions are real deal breakers…
I did ablogabout reporting a user’s nested group membership. Let take user ‘dlbouchlaghmi’. This is what his effective user group membership looks like in list form
The security matrix makes it a bit more visual. Granted, it takes some getting use to but the information is there. Now you can ‘fix’ any issues and reapply the way you see fit!:wink:
This has been on my radar for quite some time. Processing security groups this way, makes scripting, I wouldn’t say easier, but more easier to manipulate if you catch my drift…
Ok here’s the code to get the ADSecuirtyMatrix. Do be careful with groups with large memberships. I tried my hand at a group with more than 3800 member, took a couple of minutes, but it worked.