Tuesday, January 10, 2017

MemberOf in O365

Now that we have user's in o365, I've been trying to reproduce my on-premise Exchange 2010 scripts using technology available in O365. The biggest issue so far has been the lack of  AD cmdlets. No longer can I run "get-qaduser" to pull the MemberOf and AllMemberOf properties. After numerous searches to find a way to do this, I finally decided it was going to take some powershell recursion with get-distributiongroupMember.. Ugh. I was that close, when I stumbled on this post on Spiceworks. It's a basic brute-force search, but it only took a tiny portion of the time of my recursive process. (of course, I am reading in all the groups into memory with this version, instead of live reads each group).

My starts where Raven left off. My intention is to also reproduce 'allmemberof' which includes all parent groups the user is a member of.  For example:

Windows Engineering -> IT Staff -> California Staff -> All Staff

#O365MemberOf.ps1
#Finds all groups $identity belongs to in local Active Directory.
[CmdLetBinding()]
param(
[parameter(Mandatory=$true)][string]$Identity
) 
write-verbose "confirming identity"
$U = get-user $identity -ea silentlycontinue
if ($U -eq $null) { write-error "Can't find $identity. Try again.";Break}

write-verbose "reading all groups into memory"
$groups = get-group -resultsize unlimited | select name, members

write-verbose "reviewing first level groups that user belongs to."
$MemberOf = $groups | ?{$_.members -contains $u}
$childgroups = $MemberOf
$AllMemberOf = $MemberOf
Do {
    write-verbose "reviewing parent groups that user belongs to."
    $parentGroups = ForEach ($cg in $childgroups) {      
         $groups | ?{ $_.members -contains $cg.name}
    }
    write-verbose "found some parent groups, let me check those as well. Keep climbing up the tree.."
    $AllMemberOf += $parentGroups
    $childgroups = $parentGroups
} While ($ParentGroups.count -gt 0) #Only stop when I reach the top.

Write-Verbose "#Create pretty answer, add to User object that we started with."
$amoj = ($AllMemberOf | select -unique Name | %{$_.name}) -join(";")
$moj = ($MemberOf | select -unique Name | %{$_.name}) -join(";")
$u | Add-Member -Name "AllMemberOf" -MemberType NoteProperty -Value $amoj
$u | Add-Member -Name "MemberOf" -MemberType NoteProperty -Value $moj

write-verbose "#Return a modified user object to requestor."
Return $u

To use:
Example 1:

.\o365MemberOf.ps1 -identity "Joe User" | select MemberOf

- echo first-level group membership to screen

Example 2:

$UserInfo = .\o365MemberOf.ps1 -identity "Joe User"
$UserInfo.AllMemberOf.split(";") | get-distributiongroup

- grab all group membership and find associated distribution groups.

No comments:

Post a Comment