Last active
August 3, 2017 19:11
-
-
Save NathanTheGr8/2dc92d05d97b11d7067fae6a2be285eb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Function Get-ADGroupsDifference { | |
<# | |
.SYNOPSIS | |
PowerShell function intended to compare group membership for two Active Directory users. | |
.DESCRIPTION | |
Using this function you can compare groups membership for two users Active Directory users. | |
The first is reference user, the second is compared with it and as the result groups different for both users will be displayed. | |
.PARAMETER ReferenceUser | |
Active Directory user object used as source for comparison - reference user | |
The acceptable values for this parameter are: | |
-- A Distinguished Name | |
-- A GUID (objectGUID) | |
-- A Security Identifier (objectSid) | |
-- A SAM Account Name (sAMAccountName) | |
.PARAMETER User | |
Active Directory user object for which group membership comparison will be performed | |
The acceptable values for this parameter are: | |
-- A Distinguished Name | |
-- A GUID (objectGUID) | |
-- A Security Identifier (objectSid) | |
-- A SAM Account Name (sAMAccountName) | |
.PARAMETER DomainName | |
Active Directory domain name - NETBIOS or FQDN - if not given than current domain for logged user is used. | |
.PARAMETER IncludeEqual | |
If selected also groups for what both users belong will be returned. | |
.EXAMPLE | |
Get-ADGroupsDifference -ReferenceUser XXXX -User YYYY | |
ReferenceUser : XXXX | |
User : YYYY | |
GroupDistinguishedName : CN=GroupA,OU=Groups NonSpecials,DC=domain,DC=local | |
GroupCanonicalName : domain.local/Groups NonSpecials/GroupA | |
SideIndicator : 1 | |
SideIndicatorName : Only User | |
ReferenceUser : XXXX | |
User : YYYY | |
GroupDistinguishedName : CN=GroupB,OU=Groups NonSpecials,DC=domain,DC=local | |
GroupCanonicalName : domain.local/Groups NonSpecials/GroupB | |
SideIndicator : -1 | |
SideIndicatorName : Only ReferenceUser | |
ReferenceUser : XXXX | |
User : YYYY | |
GroupDistinguishedName : CN=Group-007-License,OU=Groups Special,DC=domain,DC=local | |
GroupCanonicalName : domain.local/Groups Special/Group-007-License | |
SideIndicator : -1 | |
SideIndicatorName : Only ReferenceUser | |
.EXAMPLE | |
Get-ADGroupsDifference -ReferenceUser XXXX -User YYYY | Where { $_.SideIndicator -eq -1 } | ForEach { Add-ADGroupMember -Identity $_.GroupDistinguishedName -Members $_.User } | |
As a result for this command the user YYYY will be a member for all groups for the user XXXX belongs | |
.LINK | |
https://github.com/it-praktyk/Get-ADGroupsDifference | |
.LINK | |
https://www.linkedin.com/in/sciesinskiwojciech | |
.NOTES | |
AUTHOR: Wojciech Sciesinski, wojciech[at]sciesinski[dot]net | |
KEYWORDS: PowerShell, Active Directory, Groups | |
VERSION HISTORY | |
- 0.3.0 - 2015-08-01 - The first version published on GitHub | |
- 0.3.1 - 2015-08-01 - Help updated | |
- 0.4.0 - 2016-08-22 - Scenarios when evaluated accounts are not members of any group added partially, | |
the function renamed from Get-ADGroupDifferences to Get-AdGroupsDifference | |
- 0.4.1 - 2016-08-24 - Scenarios when evaluated accounts are not members of any group added partially, TODO added, help updated | |
- 0.4.2 - 2016-09-07 - Error with returning groups corrected | |
LICENSE | |
Copyright (c) 2015-2016 Wojciech Sciesinski | |
This function is licensed under The MIT License (MIT) | |
Full license text: http://opensource.org/licenses/MIT | |
TODO | |
- add support for taking users from pipeline | |
- add support to include/compare PrimaryGroup also | |
- add verbose messages | |
- add INPUTS, OUTPUS | |
#> | |
Param ( | |
[parameter(Mandatory = $true)] | |
[alias("BaseUser")] | |
[String]$ReferenceUser, | |
[parameter(Mandatory = $true)] | |
[alias("CurrentUser")] | |
[String]$User, | |
[parameter(Mandatory = $false)] | |
[String]$DomainName, | |
[parameter(Mandatory = $false)] | |
[Switch]$IncludeEqual | |
) | |
BEGIN { | |
if ($null -eq (Get-Module -name 'ActiveDirectory' -ErrorAction SilentlyContinue)) { | |
Import-Module -Name 'ActiveDirectory' -ErrorAction Stop | Out-Null | |
} | |
If ($DomainName -eq $Null) { | |
$DomainName = (Get-ADdomain -Current LoggedOnUser).DNSRoot | |
} | |
[String]$DomainController = (Get-ADDomainController -DomainName $DomainName -Discover).HostName | |
$Results = @() | |
} | |
PROCESS { | |
$Error.Clear() | |
Try { | |
$ReferenceUserObject = Get-ADUser -Identity $ReferenceUser -Properties MemberOf, PrimaryGroup -server $DomainController | |
$ReferenceUserGroups = $ReferenceUserObject | Select-Object -Property MemberOf -ExpandProperty MemberOf | |
$CurrentUserObject = Get-ADUser -Identity $User -Properties MemberOf, PrimaryGroup -server $DomainController | |
$CurrentUserGroups = $CurrentUserObject | Select-Object -Property MemberOf -ExpandProperty MemberOf | |
} | |
Catch { | |
Write-Error -Message $error[0] | |
} | |
If ($Error.count -eq 0) { | |
if ($null -eq $ReferenceUserGroups) { | |
$ReferrenceUserGroups = @() | |
} | |
elseif ($null -eq $CurrentUserGroups) { | |
$CurrentUserGroups = @() | |
} | |
$Differences = @(Compare-Object -ReferenceObject $ReferenceUserGroups -DifferenceObject $CurrentUserGroups -IncludeEqual:$($IncludeEqual.IsPresent)) | |
$table = @() | |
$onlyRef = @() | |
$Both = @() | |
$OnlyUser = @() | |
ForEach ($Difference in $Differences) { | |
If (($Difference.SideIndicator).ToLower().Contains("<=".ToLower())) { | |
$group = ConvertFrom-DN ($Difference.InputObject) | |
$onlyRef += $group | |
} | |
elseif (($Difference.SideIndicator).ToLower().Contains("=>".ToLower())) { | |
$group = ConvertFrom-DN ($Difference.InputObject) | |
$OnlyUser += $group | |
} | |
Else { | |
$group = ConvertFrom-DN ($Difference.InputObject) | |
$Both += $group | |
} | |
} | |
$index = 0 | |
while (($index -lt $onlyRef.Length) -or ($index -lt $Both.Length) -or ($index -lt $onlyUser.Length)){#while all arrays in bounds | |
# Ref User column | |
if ($index -lt $onlyRef.Length){ | |
#$onlyRef[$index] | |
$table | Add-Member -MemberType NoteProperty -Name "Only $($ReferenceUser)" -Value $($onlyRef[$index]) | |
} | |
else { #array out of bounds add blank | |
$table | Add-Member -MemberType NoteProperty -Name "Only $($ReferenceUser)" -Value "" | |
} | |
# both column, only include if was asked for | |
if ($IncludeEqual.IsPresent){ | |
if ($index -lt $Both.Length){ | |
$table | Add-Member -MemberType NoteProperty -Name "Both" -Value $Both[$index] | |
} | |
else { #array out of bounds add blank | |
$table | Add-Member -MemberType NoteProperty -Name "Both" -Value "" | |
} | |
} | |
# User column | |
if ($index -lt $onlyUser.Length){ | |
$table | Add-Member -MemberType NoteProperty -Name "Only $($User)" -Value $onlyUser[$index] | |
} | |
else { #array out of bounds add blank | |
$table | Add-Member -MemberType NoteProperty -Name "Only $($User)" -Value "" | |
} | |
$index++ | |
} | |
} | |
} | |
END { | |
Return $table | |
} | |
} | |
function ConvertFrom-DN { | |
#Based on: http://practical-admin.com/blog/convert-dn-to-canoincal-and-back/ | |
#Credit: Andrew | |
#Corrected by Wojciech Sciesinski | |
param ([string]$DN = (Throw '$DN is required!')) | |
foreach ($item in ($DN.replace('\,', '~').split(","))) { | |
switch -regex ($item.TrimStart().Substring(0, 3)) { | |
"CN=" { $CN += , $item.replace("CN=", ""); $CN += '/'; continue } | |
"OU=" { $OU += , $item.replace("OU=", ""); $OU += '/'; continue } | |
"DC=" { $DC += $item.replace("DC=", ""); $DC += '.'; continue } | |
} | |
} | |
$canonical = $dc.Substring(0, $dc.length - 1) | |
If ($ou.count -gt 0) { | |
for ($i = $ou.count; $i -ge 0; $i--) { $canonical += $ou[$i] } | |
} | |
If ($CN.count -gt 0) { | |
for ($i = $CN.count; $i -ge 0; $i--) { $canonical += $CN[$i] } | |
} | |
return $canonical | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment