building some reports to compare ad users group memberships
whats strange is on random objects returned post add-member, the initial value is passed as {}
then when i populate the object later in the script it winds up as {X} instead of just an X
in testing, if i put any letter value in the value for add-member, for the entries that this is happening on, i see just {} as being put into the value
any help here would be greatly appreciated, i’m just at the end of my rope, i’ve passed every one of the ojects through GM and they all appear to be strings i’m just completely lost trying to trouble-shoot this
Curly brackets indicate a collection of objects, such as groups. There is one user and a user is part of many groups. If you build an object manually, you’ll see the same behavior you are referring to:
well, that’s not what the code does,
the final phase of the data is a table to compare users group memberships.
when this executes:$adgroups | Add-Member -MemberType NoteProperty -Name “$user” -Value “” -Force
I do get the new field added to the array and 95% of the objects have it appropriately, network id with a blank value.
the other 5% randomly give a {} value.
if I modify my value to validate, I tried “U”
95% of the objects have “U” as the value before I load.
but a random 5% of the objects have just “{}” as the stored value.
Add-Member isn’t being used properly and it’s not necessary, there are much easier methods to build an object. You are using a variable for the Name of the property. This would make have properties like Groups, Jim, Sally. Add-Member can add a property to an entire object
Add-Member is an antiquated way to build objects. The first, simplest approach is just using Select-Object, which generates a PSObject. Try this with a couple of users to validate it contains the data you’re looking for.
well, let’s start with the root request I have, to build a report that I can feed multiple ids into, to generate a table containing all of the ad groups the users are a member of, with separate columns for each group to indicate if that user is in the group.
so i “have” to dynamically name values in my object, which is what I am using the add-member for.
so my process is to get-adprincipalgroupmembership of the networkid provided to the script.
I then loop through all of the objects in the get-adprincipalgroupmembership results, and I add to the object a property that is named as the userid so i can populate the membership status for “that” user later in the script.
this works fine. the objects are all given an additional property for each network id i feed in.
the issue is that most times, this attribute is added properly.
at random however, some attributes are added as {}
the script itself works, it does build the objects with the additional property that I require, the only issue is the random attributes being wrapped in the {}
here is a more complete set of the code (id’s obfuscated)
good catch JS, that does speed up the information collection there.
unfortunately, it does not resolve the root issue where invalid values are passed into the added property
the values for the 2 added properties in the unique ad group check (prior to adding the indicator for group membership) looks like this
U U
{}
U U
when I get to checked groups, the values for these same entries look like:
N X
{X} X
X X
it technically indicates properly, ie if the user is in the group an X is input, and when a user is not in the group, a N is input.
its just the random entries wrapped in {} that have me confused
i mean if add-member isn’t really appropriate, what should we be using to add a property to an object?
and how else could i have a dynamically named property added?
What you are trying to do is complex because it’s not how Powershell is meant to display data. That’s why I was asking more about what you are trying to do versus what issues you are having with Add-Member. With that said, you can do what you are asking, but I would only do this for a handful of groups, otherwise you will have like a ton of columns. This should be very close to what you are looking for.
$users = "User1"
$results = foreach ($user in $users) {
Get-ADUser -Filter {SamAccountName -eq $user} -Properties MemberOf |
Select Name,
SamAccountName,
@{Name="Groups";Expression={$_.MemberOf | foreach{$_.Split(",")[0].Replace("CN=","")}}}
}
#Go thru all users and put groups in an array
$allGroups = foreach($user in $results) {
$user.Groups
}
#Create a blank hash table for properties
$props = @{}
#Add User property
$props.Add("User", $null)
#Loop thru all Unique groups and create a blank property
foreach ($grp in $allGroups | Select -Unique) {
$props.Add($grp,$null)
}
#Create a template object with the properties
$object = New-Object -TypeName PSObject -Property $props
#Go back through the results
$final = foreach ($user in $results) {
#Copy the template
$objCopy = $object.PSObject.Copy()
#Set the user property
$objCopy.User = $user.SamAccountName
#Loop through all properties except User (assume they are groups)
foreach($objProp in $objCopy.PSObject.Properties | Where{$_.Name -ne "User"}) {
$key = $objProp.Name
#Set the property and look to see if the user's groups contain the current group
$objCopy."$Key" = $($user.Groups -contains $key)
}
$objCopy
}
#Create custom sort order to start with user and then groups alphabetically
$sortProps = @()
$sortProps += "User"
$sortProps += ($allGroups | Sort)
#Pipe to format table to make it pretty. If you are exporting this somewhere, you need to use Select -Property $sortProps.
$final | Format-Table -Property $sortProps -AutoSize
thanks for the idea Rob, you are closer, just a different orientation from what i’m trying to achieve.
end-stage the actual intended results would look more like the following
user1 is a member of group 1 and 3
user 2 is a member of group 2 and group 3
USER1 User2 Groupname Groupdesc
X N group1 group1desc
N X group2 group2desc
X X group3 group3desc
hence why i am trying to add a single column to my group objects for every user piped in, and the need for the dynamically named variables.
followed up with some of my .net dev’s in-house.
we still don’t have a root cause for the add-member issue as i used it, other than we think it came down to the duplicate ad group entries.
when i use add-member on unique ad groups returned from the array of users, the value does not populate as a collection, i get just the raw strings.
$ids = "USERID1,USERID2"
$users = $ids.Split(",") | ForEach-Object { $_.trim() }
foreach ($user in $users)
{
if ($user)
{
Write-Host "Getting groups for ${user}"
$usergroups = Get-ADPrincipalGroupMembership $user
$adgroups += $usergroups
}
}
$unique = $adgroups | Sort-Object -Unique
foreach ($group in $unique)
{
foreach ($user in $users)
{
$group | Add-Member -MemberType NoteProperty -Name "$user" -Value "" -Force
}
}
$checkedgroups = @()
$unique|out-gridview
foreach ($group in $unique)
{
$groupmembers = Get-ADGroup $group.samaccountname -Properties members | Select-Object -ExpandProperty Members
if ($groupmembers)
{
foreach ($user in $users)
{
if ($user)
{
if ($groupmembers -like "*$user*")
{
$group.$user = 'X'
}
else
{
$group.$user = 'N'
}
}
}
$checkedgroups += $group
}
}
$checkedgroups|out-gridview