export object using Export-Csv doesn't work - powershell

I'm trying to export the username and the user's group membership (of specifc groups) to a CSV file using Export-Csv. However, I couldn't accomplish this using several approaches.
My current script works fine but the output is shown on the PowerShell console alone:
$accounts = Get-Content "C:\Scripts\getUserGroups\users.txt"
foreach ($account in $accounts) {
"$account member of:"
Get-ADPrincipalGroupMembership -Identity $account |
select Name |
Where-Object { $_.name -like 'Browsing_Group*' } |
Sort Name
}
I want to export it to a file in an ordered manner:
UserName1
group membership
UserName2
group membership
etc...
I've tried to add to a variable but probably didn't do that correctly:
$ArrList = [System.Collections.ArrayList]#()
$accounts = Get-Content "C:\Scripts\getUserGroups\users.txt"
foreach ($account in $accounts) {
$ArrList.Add($account)
$groups = Get-ADPrincipalGroupMembership -Identity $account |
select Name |
Where-Object {$_.name -like 'Browsing_group*' } |
Sort Name
$ArrList.Add($grops)
}
Might be a different approach.

You need to build custom objects in order to export the data to a CSV via Export-Csv. The 2 main ways of doing that are:
using calculated properties:
$accounts |
Select-Object #{n='Username';e={$_}}, #{n='Groups';e={
(Get-ADPrincipalGroupMembership -Identity $_ |
Select-Object -Expand Name |
Where-Object {$_ -like 'Browsing_group*' } |
Sort-Object) -join ';'
}} |
Export-Csv 'C:\path\to\output.csv' -NoType
building custom objects directly:
$accounts | ForEach-Object {
$groups = Get-ADPrincipalGroupMembership -Identity $_ |
Select-Object -Expand Name |
Where-Object {$_ -like 'Browsing_group*' } |
Sort-Object
New-Object -Type PSObject -Property #{
'Username' = $_
'Groups' = $groups -join ';'
}
} | Export-Csv 'C:\path\to\output.csv' -NoType
With PowerShell version 3 or newer you can replace New-Object with the [PSCustomObject] type accelerator:
[PSCustomObject]#{
'Username' = $_
'Groups' = $groups -join ';'
}

Related

Powershell to create list of duplicated proxyaddresses as .CSV file?

I need some way to report which users in our AD are having duplicated ProxyAddresses or aliases.
Get-ADUser -filter * -properties proxyaddresses |
Select-Object Name,
#{ L = "proxyAddresses"; E = { ($_.ProxyAddresses -like 'smtp:*') -join ";" } } |
export-csv -Path C:\proxyaddresses.csv -NoTypeInformation
I need only the duplicated AD user, not the whole lot, how can I get that report to . CSV file?
You need to wait before concatening your proxy addresses until you are done working with them.
You can get the duplicates by comparing the count of proxy addresses with the count of unique proxy addresses (Select-Object -Unique). If the count mismatch, then you have some dupe in there. If it is the same, then no duplicates.
Here is an example:
$Users = Get-ADUser -filter * -properties proxyaddresses |
Select-Object Name,
#{ L = "proxyAddresses"; E = { $_.ProxyAddresses -like 'smtp:*' } }
$Dupes = $Users | Where-Object -FilterScript { $_.proxyaddresses.Count -ne ($_.ProxyAddresses | Select-Object -Unique).Count }
$Dupes | Select Name, #{'Name' = 'ProxyAddresses' ; 'Expression' = { $_.proxyAddresses -join ';' } } | export-csv -Path C:\proxyaddresses.csv -NoTypeInformation
Reference dataset used
$Users = #(
[PSCustomObject]#{Name = 'Value'; proxyaddresses = #('SMTP:a#a.com', 'SMTP:a#a.com' ) }
[PSCustomObject]#{Name = 'Bob Value'; proxyaddresses = #('SMTP:a#a.com', 'b#a.com') }
)
Not sure if you want:
Users that have a duplicated address in their proxy list (see answer #SagePourpre), or
All users that have the same proxy addresses in their list as another user (this answer)
Create an index (hashtable) where each proxy address refers to a list of users that own that specific proxy address:
$ADUserByProxy = #{}
Get-ADUser -filter * -properties proxyaddresses |
ForEach-Object {
ForEach ($Proxy in $_.ProxyAddresses) {
if (!$ADUserByProxy.Contains($Proxy)) {
$ADUserByProxy[$Proxy] = [Collections.Generic.List[Object]]::new()
}
$ADUserByProxy[$Proxy].Add($_)
}
}
Than list all the values that contain more then 1 user:
$ADUserByProxy.GetEnumerator() |
Where-Object { $_.Value.Count -gt 1 } |
ForEach-Object { $_.Value } |
Export-csv -Path C:\proxyaddresses.csv -NoTypeInformation
Perhaps not the fastest method, but here's an alternative:
Get-ADUser -Filter * -Properties proxyaddresses | Foreach-Object {
$unique = $_.ProxyAddresses | Select-Object -Unique
$dupes = Compare-object -ReferenceObject $unique -DifferenceObject $_.ProxyAddresses -PassThru
if (#($dupes).Count) {
$_ | Select-Object Name, #{Name = 'DuplicateAddresses'; Expression = {$dupes -join ';'}}
}
} | Export-Csv -Path 'C:\proxyaddresses.csv' -NoTypeInformation

how to list users and the groups they are part of in office 365 powershell

i need a script please to export users in office 365 and the groups they are part of and not the other way around. can anyone help please. all answers i found were to export distribution groups and their members.
i tried using the below but i dont know how to select group names.
get-mailbox | ? {$_.PrimarySMTPAddress -like "*domain.com"} | Select DisplayName,Alias,PrimarySMTPAddress'
and i tried this too
get-mailbox | ? {$_.PrimarySMTPAddress -like "*domain.com"} | Sort Name | % { $MbxDirData = $_ ; Get-MailboxStatistics $_ } | Select DisplayName, #{E={ $MbxDirData.Alias };L='Alias'}, #{E={ $MbxDirData.PrimarySMTPAddress };L='PrimarySMTPAddress'}, #{E={ $_.TotalItemSize.Value + $_.TotalDeletedItemSize.Value };L="TotalMailboxSize"}
any help is appreciated.
This is untested, but I think you can use cmdlets Get-User and then Get-Group to retrieve the groups a user is a member of like this:
Get-Mailbox | Where-Object {$_.PrimarySMTPAddress -like "*domain.com"} | ForEach-Object {
$user = Get-User -Identity $_.DistinguishedName
$groups = Get-Group | Where-Object {$_.Members -contains $User}
$_ | Select-Object DisplayName, Alias, PrimarySMTPAddress,
#{Name = 'Groups' ; Expression = {$groups.Name -join '; '}}
} | Export-Csv -Path 'X:\O365UserGroups.csv' -NoTypeInformation
The above concatenates the groups with a semi-colon in one single field of the CSV, but if you would rather have output where there is one line for each group, you can do:
Get-Mailbox | Where-Object {$_.PrimarySMTPAddress -like "*domain.com"} | ForEach-Object {
$user = Get-User -Identity $_.DistinguishedName
$groups = Get-Group | Where-Object {$_.Members -contains $User}
# output a data row for each group in the collection
foreach ($group in $groups) {
$_ | Select-Object DisplayName, Alias, PrimarySMTPAddress,
#{Name = 'Groups' ; Expression = {$group.Name}}
}
} | Export-Csv -Path 'X:\O365UserGroups.csv' -NoTypeInformation
We can list all the office 365 groups by using the PowerShell cmdlet Get-UnifiedGroup and its group members by Get-UnifiedGroupLinks cmdlet .
You can use the below PowerShell script ,which will Export All Office 365 Group Members to csv. We have tested this in our local environment which is working fine.
$Groups = Get-UnifiedGroup -ResultSize Unlimited
$Groups | ForEach-Object {
$group = $_
Get-UnifiedGroupLinks -Identity $group.Name -LinkType Members -ResultSize Unlimited | ForEach-Object {
New-Object -TypeName PSObject -Property #{
Group = $group.DisplayName
Member = $_.Name
EmailAddress = $_.PrimarySMTPAddress
RecipientType= $_.RecipientType
}}} | Export-CSV "C:\Office365GroupMembers.csv" -NoTypeInformation -Encoding UTF8
Here is the sample output screenshot for reference :
Note:
Get-UnifiedGroup cmdlet is available only in the cloud-based service.
For more Information you refer this blog post & also if you faces any issues while executing Get-unifiedGroup cmdlet you refer this .

PowerShell Get-ACL with SamAccountName values

I'm trying to collect folder permissions to a csv file with Powershell. My problem is that I'd need the results to contain both the SamAccountName and FileSystemRights.
I tried two different method. The first I came up with was a simple approach that gave me IdentityReference and FileSystemRights, but I couldn't find any working method that can get SamAccountName from IdentityReference.
The second one I found on the internet was much more sophisticated. It collects all the accounts that has access to the folder, but it doesn't show FileSystemRights and I couldn't figure out how to change it to do so.
My own solution
(Get-Acl "FolderPath").Access | Select-Object IdentityReference, FileSystemRights
The solution I found
Get-Acl $UncPath | Select-Object -ExpandProperty Access | Where-Object { (-not $_.IsInherited) -and ('NT AUTHORITY\SYSTEM','BUILTIN\Administrators','CREATOR OWNER' -notcontains $_.IdentityReference) } | Select-Object -ExpandProperty IdentityReference | ForEach-Object { $_.Translate('System.Security.Principal.SecurityIdentifier').Value } | Get-ADGroup -ErrorAction SilentlyContinue | get-adgroupmember | select-object SamAccountName | Format-Table | Out-String
Is there any working method that can get me a result where I can see SamAccountName and FileSystemRights?
Thank you in advance.
$UncPath = 'E:\temp\test'
$all = Get-Acl $UncPath |
Select -ExpandProperty Access |
Where-Object { (-not $_.IsInherited) -and ('NT AUTHORITY\SYSTEM','BUILTIN\Administrators','CREATOR OWNER' -notcontains $_.IdentityReference) } |
Select-Object #{ Name = 'Identity'; Expression = { $_.IdentityReference -replace "\w+\\(.+)", '$1' } }, FileSystemRights
# Here you can get Users ACL
$distinct_users = $all |
Select-Object Identity, #{ Name = 'sAMAccountName'; Expression = { (Get-ADUser -Identity $_.Identity -ErrorAction SilentlyContinue).sAMAccountName }}, FileSystemRights |
Where-Object sAMAccountName -ne $null
# Here we will expand group acls
$groups = $all |
Select-Object Identity, #{ Name = 'sAMAccountName'; Expression = { (Get-ADGroup -Identity $_.Identity -ErrorAction SilentlyContinue).sAMAccountName }}, FileSystemRights |
Where-Object sAMAccountName -ne $null
# now we will get groups membership
$group_users = #()
Foreach($group in $groups){
Get-ADGroupMember -Identity $group.Identity | ForEach-Object { $group_users += [PSCustomObject]#{
'Identity' = $group.Identity
'sAMAccountName' = $_.sAMAccountName
'FileSystemRights' = $group.FileSystemRights
} }
}
$everyone = $distinct_users + $group_users
$everyone | Export-Csv -Path D:\example.csv
Check $everyone variable it will contain 3 columns: Identity as it was in the ACL, sAMAccountName and FileSystem Rights.

Powershell Read Users from ActiveDirectory , sort and group the result

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

Powershell - User group membership from text file

I have a list of users and I want to export their group names, sorted A-Z. The following script is not working in the inner ForEach-Object loop.
Get-Content users.txt | ForEach-Object {
$user = $_;
Get-ADUser –Identity $user –Properties MemberOf | Select-Object -ExpandProperty MemberOf | sort
ForEach-Object {
New-Object PSObject -property #{User=$user;Group=$_;}
}
} | Export-Csv -Path 'your_file_path.csv' -NoTypeInformation
The ForEach-Object is just sitting out there alone--you have to either pipe an object to it, or assign the object to a variable and use foreach to loop through the object instead. I took the second approach below as excessive piping makes scripts difficult to read (for me).
Get-Content c:\temp\users.txt | ForEach-Object {
$user = $_;
$AdUser = Get-ADUser –Identity $user –Properties MemberOf | Select-Object -ExpandProperty MemberOf | get-adgroup | select -ExpandProperty Name | sort
foreach($group in $AdUser) {
New-Object PSObject -property #{User=$user;Group=$group;} | Export-Csv -Path 'c:\temp\out.csv' -NoTypeInformation -Append
}
}
...and if you want to pipe it and use ForEach-Object, you just need to put a pipe after the sort and move the Export-Csvso that it exports the new object that was created:
Get-Content c:\temp\users.txt | ForEach-Object {
$user = $_;
Get-ADUser –Identity $user –Properties MemberOf | Select-Object -ExpandProperty MemberOf | get-adgroup | select -ExpandProperty Name | sort |
ForEach-Object {
New-Object PSObject -property #{User=$user;Group=$_;} | Export-Csv -Path 'c:\temp\out.csv' -NoTypeInformation -Append
}
}