Reputation: 337
I'm working on a script that compares an AD user's group memberships to an existing list. One of the things I want to check for is if the user does not belong to any of the groups on the list and only to the default "Domain Users" group that all domain users are a part of, then it should output a message like, "TestUser01 is not a member of any of the groups"
Is there an operator that can check to see if that is the only value that exists? My script may be a bit odd since it's not testing against objects but the string equivalent of the object value, so that may be where my problem lies. I'm not quite sure. Partial output of the script is below. I did it this way because it was the only way I could compare the group names. When I tried comparing the object.name values, I could not make it work:
#gets a list of all groups in a given OU and stores the objects in the $groups variable
$groups = Get-ADGroup -Filter * -SearchBase 'OU=TUNE_TEST_GROUPS,OU=TUNE_TEST,DC=tune,DC=priv' -Properties name | select name
#pipe each group object into a foreach loop and output a string value of the same group name and stores it into the $groups_string variable
$groups_string = $groups | % {$_.name}
#gets a list of all users in a given OU and stores the objects in the $users variable
$users = Get-ADUser -Filter * -SearchBase 'OU=TUNE_TEST_USERS,OU=TUNE_TEST,DC=tune,DC=priv'
#hash table containing the $table properties
$props=@{
"Username" = ""
"Groupname" = ""
}
#empty array to store each user/group output object
$table=@()
#iterates through every user in the $users variable and retrieves their group memberships
foreach ($user in $users) {
#selects each group name and stores it in the $groupMembership variable
$groupMembership = Get-ADPrincipalGroupMembership $user | select name
#compares the names of each user's group to the baseline group name.
$groupMembership | foreach ($_) {
#If there is a match add the group name and the username to the $results hash table
if ($groups_string -contains $_.name) {
$props."Groupname" = $_.name
$props."Username" = $user.Name
#create a new PS object and supply the properties of the $results hash table to each object
$objresults = New-Object psobject -Property $props
#add each object to the $table array
$table += $objresults
}
}
}
#display/output the $table array and format it to fit
$table | ft -AutoSize
I've deleted the else statement since that's what I am currently trying to figure out. Right now, I can only get it to output the username and the group name when there is a match. What I need to accomplish/figure out, is to make it so that my other test users who are not part of any groups except the domain users group, appear on the report as not being a part of any of the main groups. During my tests, the only time I was able to make this happen was when the same message would also appear for my other test users. This does not make sense to the person looking at the report because those test users do belong to groups on the main group list, but because they are a part of Domain Users, an object get's outputted saying they're not a part of any of the main groups when it iterates through the Domain Users group.
I played around with some different combinations of comparison operators but could not get any to work properly. Any suggestions would be appreciated.
Upvotes: 2
Views: 6284
Reputation: 337
Thanks Ansgar. I tried variations of your suggestion and I could not get it working for what I need. I ended up mixing parts of my original script with the script I posted above and came out with the script below:
#queries all groups in a specified OU
$groups = Get-ADGroup -Filter * -SearchBase 'OU=TUNE_TEST_GROUPS,OU=TUNE_TEST,DC=tune,DC=priv'
#iterates through each group object and outputs just the string value of the name property
$groups_string = $groups | % {$_.name}
#queries all users in a specified OU
$users = Get-ADUser -Filter * -SearchBase 'OU=TUNE_TEST_USERS,OU=TUNE_TEST,DC=tune,DC=priv'
foreach ( $user in $users ) {
#iterates through each user, find their group memberships, and outputs just the name property value
$userGroups = Get-ADPrincipalGroupMembership $user | select name
#if user belongs to more than one group, add following string
if ( $userGroups.Count -gt 1){
"{0} is a member of the following groups:" -f $user.SamAccountName
#iterates through each group, if group name matches group name in original query, output the matching group name
$userGroups | foreach ($_) {
if ($groups_string -contains $_.name){
"`t{0}" -f $_.Name}
}
}
#if user belongs to 1 or lesser groups perform the next check
elseif ( $userGroups.Count -le 1 ) {
#iterates through each group, if group name in check matches "Domain Users", output string saying user doesn't belong to any groups
$userGroups | foreach ($_) {
if ($_.name -contains "Domain Users") {
"{0} is not a member of any groups" -f $user.SamAccountName}
}
}
}
This actually works well for what I need. I was able to test by adding a few of the test users to different groups out of those in the base OU I was querying. I can confirm it only outputs the groups I care about, those that match groups in the baseline query. It also allows me to output a message saying that a user doesn't belong to any of the baseline groups when they are only a part of the default Domain Users group, and it also excludes the other users from this check who are a part of Domain Users by default but also belong to groups on the baseline check. Posting final script for anyone who's interested.
Upvotes: 0
Reputation: 200293
Use Compare-Object
just like I told you in response to your previous question, expand the InputObject
property to get the (group) objects that are equal in both arrays, then expand the objects' Name
property.
$common = Compare-Object $userGroups $groups -IncludeEqual -ExcludeDifferent |
Select-Object -Expand InputObject |
Select-Object -Expand Name
Now you can check if the result contains only the name Domain Users
like this:
if ($common -contains 'Domain Users' -and $common.Count -eq 1) {
...
} else {
...
}
or like this:
if ($common.GetType().Name -eq 'String' -and $common -eq 'Domain Users') {
...
} else {
...
}
You could also just select the first object's name from the list:
$common = Compare-Object $userGroups $groups -IncludeEqual -ExcludeDifferent |
Select-Object -Expand InputObject |
Select-Object -First 1 -Expand Name
if ($common -eq 'Domain Users') {
...
} else {
...
}
Upvotes: 1