Report list of ADUsers NOT in Security Groups

Hi,

HeadsUP I am new to this! :slight_smile:

I have been asked to write a script that can get all of our AD Users not currently in a Security Group. My issue being there are 9 Security groups numbering from 1-9.

I need the Script to check all 9 groups and if the AD user is NOT found in any of the groups export them into a report.

Import-Module activedirectory
$group = get-adgroup "Webpolicy1"
get-aduser -Properties * -filter 'enabled -eq $true' | Where-Object {$group.DistinguishedName -notin $_.memberof} |select name,samaccountname,emailaddress

As you can see, this is not checking all 9 groups but Iā€™m finding my self stuck on filtering out the users NOT in 1 or the 9 groups!

Any help is appreciated.

Hi Nay,

Here you are:

  1. Dumb way:
    Import-Module activedirectory
    for ($i = 1; $i -lt 10; $i++) {
    $groupName = Get-Adgroup ā€œWebpolicy$iā€
    Get-ADUser -Properties * -Filter ā€˜enabled -eq $trueā€™ |
    Where $groupName.DistinguishedName -notin $_.memberof |
    select name, samaccountname, emailaddress
    }

  2. A bit smarter:

Import-Module activedirectory
$securtyGroups = @()
for ($i = 1; $i -lt 10; $i++) {
$securtyGroups.Add((Get-Adgroup ā€œWebpolicy$iā€))
}

Get-ADUser -Properties * -Filter ā€˜enabled -eq $trueā€™ |
ForEach-Object {
$currentUser = $_
foreach ($securityGroup in $securityGrous) {
if ($securityGroup.DistinguishedName -notin $currentUser.memberof) {
$currentUser | select name, samaccountname,emailaddress
}
}
}

Hopefully you got the idea. I do not have a chance to test it, though.

Hi Evgeny,

Thank you for your fast response on this.

However I am receiving the following error:

Exception calling ā€œAddā€ with ā€œ1ā€ argument(s): ā€œCollection was of a fixed size.ā€
At line:4 char:2

  • $securityGroups.Add((Get-Adgroup ā€œWebpolicy$iā€))
  •  + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
     + FullyQualifiedErrorId : NotSupportedException</strong>

Hi

Try this one. I went a little different way than those before, but I think we can manage to get results with this one. I assumed that you have only these nine groups you were interrested and nothing else is named like this we can only search group ā€œWebPolicyā€ from users.

$Results = Get-ADUser -Filter {enabled -eq 'True'} -Properties MemberOf | ForEach-Object {
    
    If (!($_.memberOf -like "*WebPolicy*")) {
    
        [PSCustomObject]@{
            Name = $_.Name
            UPN = $_.UserPrincipalName
            SamAccountName = $_.SamAccountName
        }
    
    } #If

} #Get-AdUser
$Results
$Results | Export-CSV file.csv -NoTypeInformation

Try that, I managed to get all my users with this on my lab. :slight_smile:

Regards

Jarkko

Hi,

Thanks again for the rapid response!

Iā€™ve come across an issue that I naively did not anticipate. Itā€™s pulling back a lot more users than it should, after going into the users memberships, I remembered a lot of users are members of the WebPolicy groups via a RBAC group.

Is there a way I can search each ADUser memberships recursively, to check within there RBAC for a webpolicy.

However, I would safely assume every user within an RBAC group IS a member of a webpolicy as this was added upon creation of the RBACs and reviewed by out info sec team, this may mean we can check if a user is a member of an RBAC they WILL be in a webpolicy?

Many thanks!

Hi

So you need to search these webpolicy groups from other groups? Then I suggess that you would do that and collect those groups and these webpolicy groups and put these groups into the where you look those groups from user. Did I explain this right? :slight_smile:

Regards

Jarkko

Hi guys,

So just to make myself clearer on what is I am trying to achieve here, I should of been a lot more clear to begin with.

-I need to search Get all AD Users within a specific OU that are ENABLED
-Use the RecursiveMatch parameter as a lot of the users are members of Role Based groups which contain the web policies.
-I need to check each user to see if its a member of 1 of 5 groups, WebPolicy1,2,3,4,5. (all beginning with web policy)

Get-ADUser įæÆ
    -Filter 'memberOf -RecursiveMatch "CN=GroupLevel1,CN=Users,DC=CohoVineyard,DC=com"' įæÆ
    -SearchBase "CN=guest,CN=Users,DC=cohovineyard,DC=com"

Above runs without any error but returns no data - I have amended this to not display company details.

Get-ADUser įæÆ
    -Filter "memberOf -RecursiveMatch '$((Get-ADGroup "Domain Admins").DistinguishedName)'" įæÆ
    -SearchBase $((Get-ADUser Guest).DistinguishedName)

The above works correctly but again will only search for a specific user I have provided.

Another issue I am coming across is I donā€™t want the script to say a user is NOT a member of a web policy until it has checked all 5 policies.

Any helps is much appreciated.

Nay: When you say ā€œa lot of the users are members of Role Based groups which contain the web policies.ā€ do you mean that the AD users are members of role groups that are themselves members of the WebPolicy security groups, or are you saying that the WebPolicy security groups are members of the role groups? If youā€™re saying the former, then the following is what I got to work. You can parameterize it, if you want. If youā€™re saying the later, please clarify with further details on the issue.

#Array of web policy groups.
$WebPolicyGroups = 'WebPolicy1','WebPolicy2','WebPolicy3','WebPolicy4','WebPolicy5'

#Get list of the AD users in the OU you want to check.
$ADUsers = Get-ADUser -Filter * -SearchBase "OU=YourOU,DC=YourDomain,DC=com"

#Put together combined list of ObjectGuid values of the members of all web policy groups, recursively.
ForEach($WebPolicyGroup in $WebPolicyGroups)
{
  $GroupMemberObjectGuids += Get-ADGroupMember $WebPolicyGroup -Recursive | Select-Object ObjectGuid
}

#Array of non-members.
$NonMembers = @()

#Check to see if the ObjectGuid of any of the AD users in $ADUsers matches that of one of the ObjectGuid values in $GroupMemberObjectGuids.  If it's not listed, then the user is not a member, directly or indirectly (though nested groups under the Web Policy security groups), of any of the Web Policy security groups.
ForEach($ADUser in $ADUsers)
{
  If(-not ($ADUser.ObjectGuid.ToString() -in ($GroupMemberObjectGuids | Select-Object -ExpandProperty ObjectGuid).Guid))
  {
    $Object = New-Object -TypeName PSObject -Property @{Name = $ADUser.Name;UserPrincipalName = $ADUser.UserPrincipalName;SamAccountName = $ADUser.SamAccountName}
    $NonMembers += $Object
  }
}

$NonMembers | Out-File -FilePath C:\WebPolicy-NonMembers.txt

@Kevyn,

Thankyou so much! this was exactly what I needed and it worked great!

Also, thankyou everyone else for participating, learnt a lot just from asking a question!

Nay: Iā€™m glad it worked for you. Iā€™m working on creating a full blown, parameterized script so that you can provide either specify a comma-separated list of security groups, or provide them via a text file (so you donā€™t have to type the list over and over for various sets of security groupsā€¦and other options. Iā€™ll post it when Iā€™ve got it done.