I am trying to read group membership of computers from a particular OU and write to a CSV file. The input criteria for the group membership is like if the computer is part of say "admin" and i need the csv file in the below format
---------------------------------------------------------
Computer Group1 Group2 Group3 Group4
ABCD admin1 admin2 admin3 admin4
EFGH admin2 admin3
XYZZ admin1 admin4
--------------------------------------------------------------
but end up like this.
---------------------------------------------------------
Computer Group1 Group2 Group3 Group4
ABCD admin1 admin2 admin3 admin4
EFGH admin2 admin3
XYZZ admin1 admin4
--------------------------------------------------------------
The code is like this
$All_computer = Get-ADComputer -Filter * -Property * -SearchBase $ou -Server $server | Select-object Name,DNSHostName,Description,memberof
$computerExport = $All_computer |
ForEach-Object {
$ComputerName = $_.Name
$Description = $_.description
$DNSHostname = $_.DNSHostName
$memberof = $_.memberof
$groups = $memberof.where{$_ -like "*$unput_group*"}
$Group_member = [pscustomobject]#{
Workstation = $ComputerName
Comp_Description = $Description
DNS_Hostname = $DNSHostname
}
$i = 0
foreach($group in $Groups)
{
$i++
$member = $group.split('=')[1].split(',')[0]
$Group_member | add-member -MemberType NoteProperty -Name "Group$i" -Value $member
}
$Group_member
}
}
$computerExport | export-csv .\Membership_status.csv -NoTypeInformation
What do i need to do to get the group membership to populate to proper column.
Well of course it does. I mean it's doing what you're asking it to do.
You're only adding the number of properties to the custom object that is found from the where object query. I am really struggling to understand what you're trying to do this for but I THINK what you really want is for each object to have all the possible properties but to have null values for those that don't match that particular computer or better yet to use a boolean.
So... Maybe like this:
[string]$GroupSearch = "admin"
$All_computer = Get-ADComputer -Filter * -Property DNSHostName, Description, memberof -SearchBase $ou -Server $server | Select-Object Name, DNSHostName, Description, memberof
$MatchedGroups = $All_Computer.MemberOf | Sort -Unique | ?{$_.Name -match $GroupSearch}
$computerExport = ForEach ($C in $All_computer) {
$Group_member = [pscustomobject]#{
Workstation = $($C.Name)
Comp_Description = $($C.Description)
DNS_Hostname = $($C.DNSHostName)
}
ForEach ($group in $MatchedGroups) {
[string]$GrpName = $($group.split('=')[1].split(',')[0])
If ($C.MemberOf -contains $group) {
$Group_member | Add-Member -MemberType NoteProperty -Name $GrpName -Value $true
} else {
$Group_member | Add-Member -MemberType NoteProperty -Name $GrpName -Value $false
}
}
$Group_member
}
$computerExport | Export-Csv .\Membership_status.csv -NoTypeInformation
If I understand the question, you need to get all computers from a certain OU that are member of group(s) with a similar partial name.
To do that, I would suggest creating an array of computer objects at first with a temporary extra property called 'Groups' in which the group names that match the partial name are stored.
Later, we'll put these in the correct order as new properties called 'Group1', 'Group2' etc.
# the partial groupname to search for
$unput_group = 'admin'
# Get-ADComputer by default already returns these properties:
# DistinguishedName, DNSHostName, Enabled, Name, ObjectClass, ObjectGUID, SamAccountName, SID, UserPrincipalName
# get an array of computer objects that are member of 'admin*' group(s) with the desired properties
# one extra temporary property is added which contains an array of 'admin*' group names
$All_computer = Get-ADComputer -Filter * -Property Description, MemberOf -SearchBase $ou -Server $server |
Where-Object { $_.MemberOf -match $unput_group} |
Select-Object #{Name = 'Workstation'; Expression = {$_.Name}},
#{Name = 'Comp_Description'; Expression = {$_.Description}},
#{Name = 'DNS_Hostname'; Expression = {$_.DNSHostName}},
#{Name = 'Groups'; Expression = { #($_.MemberOf |
Where-Object { $_ -match "CN=($unput_group[^,]+)" } |
ForEach-Object { $matches[1] }) }}
# get all the group names from the computers we have collected and sort unique
$All_Groups = $All_computer.Groups | Sort-Object -Unique
# build a lookup hashtable with property names ('Group1', 'Group2' etc)
$hash = [ordered]#{}
for ($i = 1; $i -le $All_Groups.Count; $i++) {
$hash["Group$i"] = $All_Groups[$i - 1]
}
# now loop through the collection and add the group properties in order
$result = foreach ($computer in $All_computer) {
foreach ($propertyName in $hash.Keys) {
$group = if ($computer.Groups -contains $hash[$propertyName]) { $hash[$propertyName] }
$computer | Add-Member -MemberType NoteProperty -Name $propertyName -Value $group
}
# output the updated object and remove the temporary 'Groups' property
$computer | Select-Object * -ExcludeProperty Groups
}
# finally, save the results to disk
$result | Export-Csv -Path .\Membership_status.csv -NoTypeInformation
Related
I need to find AD group members from given groups in csv file as input. the groups contains Users and Groups also. below is sample input data
I wrote the below code. for users I am getting the output (i.e. for the first entry), but for the second one, as they are groups within group, I am not able to fetch the email.
$GroupCollection= Import-csv -Path "C:\Groups.csv"
$Report = #()
Foreach($Group in $GroupCollection){
$MemberGroup=#()
$Group = $Group.'OPE DLs'
if($Group -match '#')
{
$pos = $Group.IndexOf("#")
$leftPart = $Group.Substring(0, $pos)
}
else
{
$leftPart = $Group
}
$MemberGroup = Get-ADGroupMember -identity $leftPart -recursive | Get-ADUser -Properties mail | Select-Object mail
$MemberGroups = ($MemberGroup.mail) -join "`r`n"
if($MemberGroups -ne ""){
$Out = New-Object PSObject
$Out | Add-Member -MemberType noteproperty -Name 'Contract Details' -Value $Group.'Customer subset'
$Out | Add-Member -MemberType noteproperty -Name 'Group Name' -Value $leftPart
$Out | Add-Member -MemberType noteproperty -Name 'Member Groups' -Value $MemberGroups
$Report += $Out
}
}
$Report | Sort-Object Name | FT -AutoSize
$Report | Sort-Object Name | Export-Csv -Path ‘C:\Group-MemberGroups-Report.csv’ -NoTypeInformation
Please let me know how to get the details. Is the approach is fine or there is any other way to do this.
expected output
As commented, if the object returned by Get-ADGroupMember is a group, you won't get results by piping it through to Get-ADUser, because... it is a group, not a user.
You need to loop over the results and depending on what type the object is (group, user or computer) you use either Get-ADUser or Get-ADGroup (not interested in computer objects).
Try
$Report = foreach ($Group in $GroupCollection){
$groupName = ($Group.'OPE DLs' -split '#')[0]
$groupMembers = Get-ADGroupMember -Identity $groupName -Recursive | ForEach-Object {
$adObject = $_
switch ($adObject.objectClass) {
'group' { ($adObject | Get-ADGroup -Properties mail).mail }
'user' { ($adObject | Get-ADUser -Properties EmailAddress).EmailAddress }
}
}
if (#($groupMembers).Count) {
[PsCustomObject]#{
'Group Name' = $groupName
'Contract Details' = $Group.'Customer subset'
'Member Groups' = $groupMembers -join [environment]::NewLine
}
}
}
$Report = $Report | Sort-Object 'Group Name'
$Report | Format-Table -AutoSize
$Report | Export-Csv -Path 'C:\Group-MemberGroups-Report.csv' -NoTypeInformation
Notes:
adding to an array with += is extremely wasteful because the entire array needs to be rebuilt in memory on each iteration
To take the group name as the part left of the # character, I simply use the -split operator and take the first element ([0])
To output an object, I'm using a [PsCustomObject]#{..} construct rather than the old (pre PowerShell 3.0) New-Object PSObject method
I am trying to get a powershell script to export all users in an OU and sub OUs which I can do fine, but when I try to get the user's OU, I get nothing for the OU. I have looked all over online and found a few scripts that pull just the user's OU, but they are a little slow and I can't seem to get them to pull groups or is for pulling from one group instead of listing all users and their groups.
I am trying to export this list and sort by OU so that I can ensure each student is in the proper groups. We have had a few students that were in extra groups and I want a quick and easy look to find those students.
#Student
$Report = #()
#Collect all users
$Users = Get-ADUser -Filter * -SearchBase 'OU=Student,DC=domain,DC=com' -Properties distinguishedname, Name, GivenName, SurName, SamAccountName, UserPrincipalName, MemberOf, Enabled -ResultSetSize $Null
# Use ForEach loop, as we need group membership for every account that is collected.
# MemberOf property of User object has the list of groups and is available in DN format.
Foreach($User in $users){
$UserGroupCollection = $User.MemberOf
#This Array will hold Group Names to which the user belongs.
$UserGroupMembership = #()
#To get the Group Names from DN format we will again use Foreach loop to query every DN and retrieve the Name property of Group.
Foreach($UserGroup in $UserGroupCollection){
$GroupDetails = Get-ADGroup -Identity $UserGroup
#Here we will add each group Name to UserGroupMembership array
$UserGroupMembership += $GroupDetails.Name
}
#As the UserGroupMembership is array we need to join element with ',' as the seperator
$Groups = $UserGroupMembership -join ','
#Creating custom objects
$Out = New-Object PSObject
$Out | Add-Member -MemberType noteproperty -Name DistinguishedName -Value #{Name="DistinguishedName";Expression={$_.distinguishedname | ForEach-Object {$_ -replace '^.+?(?<!\\),',''}}}
$Out | Add-Member -MemberType noteproperty -Name Name -Value $User.Name
$Out | Add-Member -MemberType noteproperty -Name UserName -Value $User.SamAccountName
$Out | Add-Member -MemberType noteproperty -Name Status -Value $User.Enabled
$Out | Add-Member -MemberType noteproperty -Name Groups -Value $Groups
$Report += $Out
}
#Output to screen as well as csv file.
$Report | Sort-Object DistinguishedName | FT -AutoSize
$Report | Sort-Object DistinguishedName | Export-Csv -Path $env:temp\students.csv -NoTypeInformation
There you go, I added some comments to help you understand the thought process.
This should be a lot faster than what you were doing.
The problem while adding your OUs was here:
$Out | Add-Member -MemberType noteproperty -Name DistinguishedName -Value #{Name="DistinguishedName";Expression={$_.distinguishedname | ForEach-Object {$_ -replace '^.+?(?<!\\),',''}}}
Which should've been:
$Out | Add-Member -MemberType noteproperty -Name DistinguishedName -Value ($user.distinguishedname -replace '^.+?(?<!\\),','')
#Student
$Report = [system.collections.generic.list[pscustomobject]]::new()
# Using Collection.Generic.List instead of System.Array for efficiency
#Collect all users
$Users = Get-ADUser -Filter * -SearchBase 'OU=Student,DC=domain,DC=com' -Properties MemberOf
# -> Use -SearchScope Subtree if you want to go all the way down in OU recursion starting from the 'OU=Student'
# -> distinguishedname, Name, GivenName, SurName, SamAccountName, UserPrincipalName and Enabled are Default Properties
# of Get-ADUser, no need to call them.
# -> -ResultSetSize $Null is default for Get-ADUSer, no need to call it
# Use ForEach loop, as we need group membership for every account that is collected.
# MemberOf property of User object has the list of groups and is available in DN format.
Foreach($User in $users)
{
#This Array will hold Group Names to which the user belongs.
$UserGroupMembership = [system.collections.generic.list[string]]::new()
#To get the Group Names from DN format we will again use Foreach loop to query every DN and retrieve the Name property of Group.
Foreach($UserGroup in $User.MemberOf)
{
# $GroupDetails = Get-ADGroup -Identity $UserGroup
# -> Instead of this, we can do some string manipulation
# which will be a lot faster and give you the same results.
$UserGroupMembership.Add($UserGroup.Split(',OU=')[0].replace('CN=',''))
}
#As the UserGroupMembership is array we need to join element with ',' as the seperator
$Groups = $UserGroupMembership -join ','
#Creating custom objects
<#
$Out = New-Object PSObject
$Out | Add-Member -MemberType noteproperty -Name DistinguishedName -Value #{Name="DistinguishedName";Expression={$_.distinguishedname | ForEach-Object {$_ -replace '^.+?(?<!\\),',''}}}
$Out | Add-Member -MemberType noteproperty -Name Name -Value $User.Name
$Out | Add-Member -MemberType noteproperty -Name UserName -Value $User.SamAccountName
$Out | Add-Member -MemberType noteproperty -Name Status -Value $User.Enabled
$Out | Add-Member -MemberType noteproperty -Name Groups -Value $Groups
$Report += $Out
-> Again, Add-Member is highly inefficient compared to casting PSCustomObject
-> += is evil ( •̀ᴗ•́ )و ̑̑
#>
$Report.Add(
[pscustomobject]#{
OrganizationalUnit = ($user.DistinguishedName -replace '^.+?(?<!\\),','')
Name = $user.Name
UserName = $user.sAMAccountName
Status = $user.Enabled
Membership = $Groups
})
}
#Output to screen as well as csv file.
$Report | Sort-Object OrganizationalUnit | FT -AutoSize
$Report | Sort-Object OrganizationalUnit | Export-Csv -Path $env:temp\students.csv -NoTypeInformation
I don't know how many users you have but every time you += on an array the entire array plus the new element is copied to a completely new array. This is a bad practice and gets exponentially worse with every item added the array. You can avoid this by building the arrays as a loop result or by using dotnet list object with an efficient add() method.
You also look up the same group names repeatedly. I don't know the numbers but it's probably a lot better to put all your groups in a hashtable once and then look them up.
Your question is unclear, but if you want a list of users and their groups, you are going the long way around. You mention the ou but AFAICS there is no org unit used in the code. Do you want the AD ou property or a part of the DN? You don't seem to be using either.
Note that the DN is a string and sorting by DN will just give an alpha string sort which is not helpful. Are your students in separate org units under OU=students ? This is not clear. If so, use the AD canonicalName to sort the list.
No need to include default properties in -property. Splatting is nice.
You should improve your question by indicating what your AD structure looks like and what you think your output should look like.
Also, format your code for readability.
You want something along these lines:
# group hashtable, for efficient name lookup
$groupName = #{}
$ignoredGroups = #( 'AllStudents','AllUsers', 'etc' ) # don't clutter list with these groups
Get-AdGroup -filter '*' | # any restrictions? searchbase, etc
ForEach-Object {
if ( $ignoredGroups -notcontains $_.Name ) {
$groupName[ $_.distinguishedName ] = $_.Name
}
}
# ADsplat, for readability
$AD_Splat = #{
Filter = '*'
SearchBase = 'OU=Student,DC=domain,DC=com'
Properties = 'MemberOf,CanonicalName,sn,givenName'.split(',') # split to array
ResultSetSize = $Null # !? also, there are system limits to size
}
$results = Get-ADUser #ad_splat |
ForEach-Object {
$DN = $_.distinguishedName # do you need this at all?
$CName = $_.canonicalName # for sorting by AD org unit
$XName = $_.sn + ', ' + $_.givenName
if ( $_.Enabled ) { $Enabled = 'Y'} else { $Enabled = '.' }
$groups = (
$_.memberOf |
ForEach-Object { $GroupName[ $_ ] } | # lookup name
where-Object { $_ } | # ignore nulls (when group not in hashtable)
sort-object # consistent ordering between users
) -join ';' # don't use comma, csv conflict
# leave custom object in pipe! This builds the array efficiently.
New-Object PSObject -Property #{
DistinguishedName = $dn
Name = $_.name
XName = $XName
Login = $_.SamAccountName
CName = $CName
Groups = $Groups
}
} | Sort-Object CName # sort the objects by canonical name
$results | format-table
$results | Export-Csv -Path 'c:\temp\usersgroups.csv' -NoTypeInformation
good day to all.
I've been trying to get information about groups and subgroups in Active Directory
I've tried many variants like the one below,
What I essentially need is, to get a CSV of all the groups in AD that contain "infolink" in their name, and the columns I need are:
GiveName
SN
Username
Mail
Group
ManagedBy
But no matter how I put it I only get some of the things I need.
Does someone already have a bit of code that could make my life a bit easier? If so, I'd be immensely grateful.
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter * | Where {$_.name -like "*Infolink*"} | select name -ExpandProperty name)
$Table = #()
$Record = #{
"Group Name" = ""
"Name" = ""
"Username" = ""
"mail" = ""
}
Foreach ($Group in $Groups) {
$Arrayofmembers = Get-ADGroupMember -identity $Group -recursive | select name,samaccountname
foreach ($Member in $Arrayofmembers) {
$Record."Group Name" = $Group
$Record."Name" = $Member.name
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objrecord
}
}
$Table | export-csv "D:\Infolink.csv" -NoTypeInformation
Try this,
Import-Module ActiveDirectory
$groups = Get-ADGroup -Filter "name -like '*Infolink*'" -Properties ManagedBy
$table = foreach ($group in $groups) {
$Arrayofmembers = Get-ADGroupMember -Identity $group -Recursive
$ArrayofmembersUsers = $Arrayofmembers | Get-ADUser -Properties Mail
$ArrayofmembersUsers | Add-Member -Name GroupInfoLinkName -MemberType NoteProperty -Value $group.Name -Force
$ArrayofmembersUsers | Add-Member -Name GroupInfoLinkManageBy -MemberType NoteProperty -Value $group.ManagedBy -Force
$ArrayofmembersUsers
}
$table | Select-Object -Property GivenName, SurName, SamAccountName, Mail, GroupInfoLinkName, GroupInfoLinkManageBy | Export-Csv "D:\Infolink.csv" -NoTypeInformation
Some Pointers..
Use the Filter on Get-ADGroup else you're getting all groups in AD and then filtering.
PSObject are great but if your Object already has the majority of the properties you require then Add-Member is helpful to add 1 or 2 more.
Many cmdlets have a Properties parameter, you'll see I've used this to include properties that were not included by default. Unfortunately Get-ADGroupMember is not one of those cmdlets so piping to Get-ADUser helps provide a workaround.
I want to read users from different Active Directory groups and then sort and group the results.
From a list like
UserName UserGroup
UZZ GAA
UKK GAA
UZZ GBB
ULL GBB
I want to get that:
Username UserGroup
UKK GAA
ULL GBB
UZZ GAA
So, from User UZZ I want to get only one entry in the list with the first value of UserGroup (first in the alphanumeric sort).
Till now I have the following code:
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter * | Where {$_.name -like "G-Q-T*"} | select name -expandproperty name)
$Table = #()
$Record = #{"GroupName" = """Username" = ""}
Foreach ($Group in $Groups) {
$Arrayofmembers = Get-ADGroupMember -identity $Group | select name, samaccountname
foreach ($Member in $Arrayofmembers) {
$Record."GroupName" = $Group
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objRecord
}
}
$Table | Sort-object -property Username | Group-object -property Username | export-csv "U:\members.csv" -NoTypeInformation**
The part making the list works fine. But not the sort and group part.
Thank you a lot for an answer and help.
Meanwhile I found out, that I have also to add the SID into the .csv File.
The SID is also in the Get-AdGroupMember. But then I try to implement is as the following, the output in case of SID stays empty. What did I wrong where? Thank you in advance for an answer:
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter "name -like 'G-Q-T*'" | select name -expandproperty name)
$Table = #()
$Record = #{
"GroupName" = ""
"Username" = ""
"SID" = ""
}
Foreach ($Group in $Groups)
{
$Arrayofmembers = Get-ADGroupMember -identity $Group | select name,samaccountname,SID
foreach ($Member in $Arrayofmembers)
{
$Record."GroupName" = $Group
$Record."UserName" = $Member.samaccountname
$Record."SID" = $Member.SID
$objRecord = New-Object PSObject -property $Record
$Table += $objRecord
}
}
$Table | Group-Object -Property Username |
Select-Object #{n="UserName";e={$_.Name}} , #{n="GroupName";e={$_.Group | Sort-Object GroupName | Select-Object -First 1 -ExpandProperty GroupName}} , #{n="SID";e={$_.SID | Sort-Object SID | Select-Object -First 1 -ExpandProperty SID}}| Export-Csv "U:\member.csv" -NoTypeInformation
I would group on username and use calculated properties to create the desired result. Sort the groupnames in the group and pick out the first value. Try to replace your last line with:
$Table | Group-Object -Property Username |
Select-Object #{n="UserName";e={$_.Name}}, #{n="GroupName";e={$_.Group | Sort-Object GroupName | Select-Object -First 1 -ExpandProperty GroupName}} |
Export-Csv "U:\members.csv" -NoTypeInformation
Avoid -Filter * as it retrieves every group. Use it to get only the groups you need
$Groups = Get-ADGroup -Filter "name -like 'G-Q-T*'"
Alternative using the famous pipeline:
Get-ADGroup -Filter "name -like 'G-Q-T*'" | ForEach-Object {
$groupname = $_.Name
$_ | Get-ADGroupMember | ForEach-Object {
New-Object -TypeName psobject -Property #{
UserName = $_.SamAccountName
SID = $_.SID
GroupName = $groupname
}
}
} | Group-Object -Property UserName |
Select-Object #{n="UserName";e={$_.Name}}, #{n="SID";e={$_.Group[0].SID}}, #{n="GroupName";e={$_.Group | Sort-Object GroupName | Select-Object -First 1 -ExpandProperty GroupName}} |
Export-Csv "U:\members.csv" -NoTypeInformation
I have a script that gives me all members of a group with certain desired information. I want this same format but for all groups that a specified username belongs to. I want information about each group, such as group type (ie security, distribution list). How would I do this? I want a different row for each group, with information about each group in the columns.
Add-PSSnapin Quest.ActiveRoles.ADManagement
$myCol = #()
ForEach ($Group in (Get-QADGroup "CN=research,OU=Security,OU=Groups,DC=xxx,DC=com" -GroupType Security))
{
ForEach ($Member in (Get-QADGroupMember $Group -SizeLimit 0))
{
$myObj = "" | Select Group, Type, Member, Email, Username, Department
$myObj.Group = $Group.Name
$myObj.Type = $Group.groupType
$myObj.Member = $Member.Name
$myObj.Email = $Member.Email
$myObj.Department = $Member.Department
$myObj.Username = $Member.sAMAccountName
$myCol += $myObj
}
}
$myCol | Export-Csv -Path "C:\Users\sdevito\Desktop\test.csv" -NoTypeInformation
or. there is this code that i found that does something similar, but each group is in the same row, different column. i cannot figure out how to edit this code to make each group on a new row.
$alist = "Name`tAccountName`tDescription`tEmailAddress`tLastLogonDate`tManager`tTitle`tDepartment`tCompany`twhenCreated`tAcctEnabled`tGroups`n"
$userlist = Get-ADUser sdevito -Properties * | Select-Object -Property Name,SamAccountName,Description,EmailAddress,LastLogonDate,Manager,Title,Department,Company,whenCreated,Enabled,MemberOf | Sort-Object -Property Name
$userlist | ForEach-Object {
$grps = $_.MemberOf | Get-ADGroup | ForEach-Object {$_.Name} | Sort-Object
$arec = $_.Name,$_.SamAccountName,$_.Description,$_.EmailAddress,$_LastLogonDate,$_.Manager,$_.Title,$_.Department,$_.Company,$_.whenCreated,$_.Enabled
$aline = ($arec -join "`t") + "`t" + ($grps -join "`t") + "`n"
$alist += $aline
}
$alist | Out-File C:\Users\sdevito\Desktop\testt.csv
How about something like:
#Requires -Version 3.0
Add-PSSnapin Quest.ActiveRoles.ADManagement
function Get-UsersGroups {
[cmdletbinding()]
param (
[Parameter(Position=0,Mandatory)][string]$Identity,
[Parameter(Position=1)][ValidateSet('all','nested','normal')][string]$MemberType
)
$user = Get-QADUser -Identity $Identity
switch ( $MemberType ) {
'all' { $groups = $user.AllMemberOf }
'nested' { $groups = $user.NestedMemberOf }
default { $groups = $user.MemberOf }
}
foreach ( $group in $groups ) {
$groupinfo = Get-QADGroup -Identity $group
$props = [ordered]#{
Group = $groupinfo.Name
Type = $groupinfo.GroupType
Member = $user.Name
Email = $user.Email
Department = $user.Department
Username = $user.sAMAccountName
}
$obj = New-Object -TypeName PSObject -Property $props
$obj
}
}
Get-UsersGroups -Identity bob | Export-Csv -Path "C:\Users\sdevito\Desktop\test.csv" -NoTypeInformation