Problem using select-object #{name="Name"; expression=$variable} - powershell

I tried something like this but it never gives the values, where my ifile.csv contains two columns displayname, grpmail
Import-Csv "E:\ifile.csv" | foreach {get-distributionGroupMember -Identity $_.displayname | select-Object #{Name= GroupName; Expression = {$_.grpmail}}, Recipienttype, Primarysmtpaddress} | Export-csv -no typeinformation "E:\Ofile.csv"
Can anyone advise me what I am doing wrong
I am expecting ofile.csv with 3 columns as GroupName, Recipienttype, Primarysmtpaddress
i get values for Recipienttype, Primarysmtpaddress columns but GroupName column is always empty.

It's because your $_ in the pipeline has changed to the result of your get-distributiongroupmember and is no longer your CSV file input.
Try this instead:
Import-Csv "E:\ifile.csv" | foreach {
$gname = $_.grpmail
Get-distributionGroupMember -Identity $_.displayname | Select #{Name= GroupName; Expression = {$gname}}, Recipienttype, Primarysmtpaddress} | Export-csv -no typeinformation "E:\Ofile.csv"
I've just split lines 2 and 3 to make it easier to read - you can put a semi-colon after $gname = $_.grpmail instead if you like.
As a general note, I like to assign specific variable names to pipeline objects to see what I'm actually working with, especially if they're being transformed on the way. Also, I like to use multiple lines to better see what's happening
foreach ($g in (Import-Csv "E:\ifile.csv")) {
Get-distributionGroupMember -Identity $g.displayname |
Select #{Name= GroupName; Expression = {$g.grpmail}},Recipienttype,Primarysmtpaddress
} | Export-csv -notypeinformation "E:\Ofile.csv"

EDIT
As per T-Me's suggestion, try this:
Import-Csv "E:\ifile.csv" | ForEach-Object {
$grpmail = $_.grpmail
get-distributionGroupMember -Identity $_.displayname | Select-Object #{ Name = 'GroupName'; `
Expression = "$grpmail" }, `
Recipienttype, Primarysmtpaddress
} | Export-csv -no typeinformation "E:\Ofile.csv"

Related

Exchange/Powershell - Add data to new column rather than joining

I am trying to export list of users in mail enabled security groups to csv but want to have each member in a separate column rather than joining the existing column.
$Csvfile = "C:\SPOgroupmembers.csv"
$Groups = Get-DistributionGroup -Filter "Alias -like '*.spo'" -ResultSize Unlimited
$Groups | ForEach-Object {
$GroupDN = $_.DistinguishedName
$DisplayName = $_.DisplayName
$PrimarySmtpAddress = $_.PrimarySmtpAddress
$Members = Get-DistributionGroupMember $GroupDN -ResultSize Unlimited
[PSCustomObject]#{
DisplayName = $DisplayName
PrimarySmtpAddress = $PrimarySmtpAddress
Members = ($Members.Name -join ',')
}
} | Sort-Object DisplayName | Export-CSV -Path $Csvfile -NoTypeInformation -Encoding UTF8 #-Delimiter ";"
This is how it currently outputs:
DisplayName
PrimarySmtpAddress
Member
Test.SPO
Test.SPO#test.com
User1,User2,User3
This is what I am trying to achieve:
DisplayName
PrimarySmtpAddress
Test.SPO
Test.SPO#test.com
User1
User2
I may be missing something simple but any help would be appreciated
If you want to export the data where each member has it's own row, which in my opinion, would be the proper way to do it, you can have an inner loop to create a new pscustomobject per member of the Group:
Get-DistributionGroup -Filter "Alias -like '*.spo'" -ResultSize Unlimited | ForEach-Object {
foreach($member in Get-DistributionGroupMember $_.DistinguishedName -ResultSize Unlimited) {
[PSCustomObject]#{
DisplayName = $_.DisplayName
PrimarySmtpAddress = $_.PrimarySmtpAddress
Member = $member
}
}
} | Sort-Object DisplayName | Export-CSV -Path ....
The simplest way to construct a [pscustomobject] dynamically is to construct an ordered hashtable first - which is easy to extend iteratively - and cast it to [pscustomobject] when done.
However, in the context of creating CSV output, you need to commit to a fixed number of properties (columns) ahead of time - if feasible[1]; e.g.:
$maxMembers = 10 # <- adjust this number to the max. count of members you expect
$Groups | ForEach-Object { ...
# ...
# Initialize an ordered hashtable with the static entries...
$oht = [ordered] #{
DisplayName = $DisplayName
PrimarySmtpAddress = $PrimarySmtpAddress
}
# ... then iteratively add the Member1, Member2, ... entries
foreach ($i in 1..$maxMembers) {
$oht["Member$i"] = $Members[$i-1]
}
# Convert to a [pscustomobject] and output
[pscustomobject] $oht
} | Sort-Object DisplayName | Export-CSV -Path $Csvfile -NoTypeInformation -Encoding UTF8
If no max. member count can / should be assumed, consider denormalizing the data by using a single member column combined with creating a separate row for each member, as shown in Santiago's helpful answer, which is unquestionably the better approach for subsequent programmatic processing of the data vs. the multi-column approach you're seeking, which may be simpler to grasp for the human observer.
[1] That is, you need to know how many members a group can have at most. You could even try to determine that count programmatically, ahead of time, but either way the resulting number may be too large to be practical.

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 .

Grouping data from Active Directory

wondering if i could get some help with my powershell script. I am halfway (or maybe even 3/4 of the way there) but im just struggling to get my groups grouped on one line per user....
Ill explain
Right now i'm able to get ALL users from Multiple AD groups, took a bit of playing around but i got there in the end...
However it displays CSV like this:
first_name,last_name,email,group_list
John,Smith,JSmith#email.com,Group1
John,Smith,JSmith#email.com,Group2
Emily,Rogers,ERogers#email.com,Group1
Emily,Rogers,ERogers#email.com,Group3
Whilst thats OK, i would really like to format the data like this:
first_name,last_name,email,group_list
John,Smith,JSmith#email.com,Group1~Group2
Emily,Rogers,ERogers#email.com,Group1~Group3
This is my code so far
## Define the groups, This includes a wildcard which gets all users in groups with that pattern
$Groups = (Get-AdGroup -filter * | Where {$_.name -like "GroupName*"} | select name -expandproperty name)
## Var for array, empty
$Array = #()
## Var for data
$Data = [ordered]#{
}
## For Each loop to get members of each group
Foreach ($Group in $Groups)
{
## Define the search criteria for AD Search
$Members = Get-ADGroupMember -identity $Group | Get-ADUser -Properties * | select givenName,sn,sAMAccountName,mail
foreach ($Member in $Members)
{
$Data."first_name" = $Member.givenName
$Data."last_name" = $Member.sn
$Data."email" = $Member.mail
$Data."group_list" = $Group
## Store in PSObject
$DataPSObject = New-Object PSObject -property $Data
## Add to array so it is no longer empty
$Array += $DataPSObject
}
}
## Export array into CSV
$Array | export-csv "C:\temp\DataFromArray.csv" -NoTypeInformation
As the email is the unique identifier, i tried to Group-Object on the email property but the output is not useful for me
## Export array into CSV
$Array | Group-Object -Property email | export-csv "C:\temp\DataFromArray.csv" -NoTypeInformation
Also i tried to join the groups using a defined separator -join '~' but this just seemed to create one long string of joined groups (makes sense when i put it that way)
Hoping anyone has some ideas?
Thanks
You need to do a little more processing on the output of Group-Object, but you're almost there!
$Array |Group-Object -Property email |ForEach-Object {
[pscustomobject]#{
first_name = $_.Group[0].first_name
last_name = $_.Group[0].last_name
email = $_.Group[0].email
groups = $_.Group.group_list -join '~' # join all the group names together
}
} |Export-Csv "C:\temp\DataFromArray.csv" -NoTypeInformation
Just a quick thingy to get what you want:
## Define the groups, This includes a wildcard which gets all users in groups with that pattern
$Groups = Get-AdGroup -Filter 'Name -like "GroupName*"' | Select-Object -ExpandProperty Name
## For Each loop to get members of each group
$Array = foreach ($Group in $Groups) {
## Define the search criteria for AD Search and capture in variable $Array
Get-ADGroupMember -Identity $Group |
Get-ADUser -Properties GivenName,Surname,SamAccountName,EmailAddress |
Select-Object #{Name = 'first_name'; Expression = {$_.GivenName}},
#{Name = 'last_name'; Expression = {$_.Surname}},
#{Name = 'email'; Expression = {$_.EmailAddress}},
#{Name = 'GroupName'; Expression = {$Group}}
}
$out = $Array | Group-Object email | ForEach-Object {
# join the GroupName property of this user to get a delimited string
$grouplist = $_.Group.GroupName -join '; '
# output a new object with the 'group_list' property
# this will create duplicates objects, so we need Select-Object * -Unique at the end
$_.Group | Select-Object first_name, last_name, email, #{Name = 'group_list'; Expression = {$grouplist}}
} | Select-Object * -Unique
$out | Export-Csv "C:\temp\DataFromArray.csv" -NoTypeInformation
Hope that helps

export object using Export-Csv doesn't work

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 ';'
}

Simple Script - Export Groups and nested Objects into file (dynamic)

I'm quite new to powershell and I'm trying to create a simple script, that exports groups and underlying objects to a csv file. It all works fine if I would access the data staticly, by for example indexing the values from the array but how can I change all that, to be dynamic?
$Groups = Get-QADGroup
$Result = #()
$Groups | ForEach-Object {
$Group = $_
$Members = Get-QADGroupMember $Group -Indirect
$Obj = '' | Select-Object -Property Name, Members #, members2
$Obj.Name = $Group.Name
#$Obj.Members = $Members[0].Name ----would work, but should be dynamic
#$Obj.members2 = $Members[1].Name ----would work, but should be dynamic
$Result += $Obj
}
$Result | Export-Csv -Path C:\Temp\groups.csv -NoTypeInformation -Encoding Unicode -Delimiter ";"
So that I just can write something like $Obj.Members = $Members but this doesn't work and gives me this output:
"Name";"Members"
"RootGroup01";"System.Object[]"
"RootGroup02";"System.Object[]"
"RootGroup03";"System.Object[]"
But I'd like something like this (example data):
"Name";"Members"
"RootGroup01";"Subuser01";"Subuser02";"SubGroup01"
"RootGroup02";"SubGroup02"
"RootGroup03";"SubGroup03";"Subuser02";"Subuser03";"Subuser04";
...
All the subgroups/subusers are in the $Members variable
You're nearly there actually. All you need is to iterate $Members and select the property you need and (as #TheMadTechinian suggested) join the array:
$Obj.Members = ($Members | Select-Object -ExpandProperty "Name") -join ';'