Export TrustedSendersAndDomains to csv using powershell - powershell

Hi Stackoverflow community, this is my first time posting a question.
I'm also new to powershell but I was able to put together a small script based on other scripts I found and it kind of works.
My goal is to query all mailboxes and output a column with the user and one with the entry for their trustedsendersanddomains.
I would like it to repeat the user when the user has multiple entries and display none in case they don't have any. It would look something like this:
csv
This is what I have. (for testing purposes I'm setting 3 actual users but the commented part works)
$Users = ("user1", "user2", "user3")
#$Users = Get-Mailbox | select -ExpandProperty Alias
$objfull = #()
Foreach ($User in $Users)
{
$Junk = Get-MailboxJunkEmailConfiguration $User
$Emails = Get-MailboxJunkEmailConfiguration $User | select -ExpandProperty TrustedSendersAndDomains
$obj = New-Object System.Object
Foreach ($Email in $Emails)
{
$obj | Add-Member NoteProperty User $User
$obj | Add-Member NoteProperty Trusted_Senders $Junk.TrustedSendersAndDomains
$objfull += $obj
}
}
$objfull | Export-Csv C:\Users\Leo\export.csv -NoTypeInformation
While it will throw error for users without entries this works in repeating the user, but the trusted sender output is the whole array and it's space separated, not comma.
This other one I was testing with will write to terminal the way I want the csv to be.
$Users = ("user1", "user2", "user3")
#$Users = Get-Mailbox | select -ExpandProperty Alias
$objfull = #()
Foreach ($User in $Users)
{
$Junk = Get-MailboxJunkEmailConfiguration $User
$Emails = Get-MailboxJunkEmailConfiguration $User | select -ExpandProperty TrustedSendersAndDomains
$obj = New-Object System.Object
Foreach ($Email in $Emails)
{
Write-Host $Email, $User
}
}
#$objfull | Export-Csv C:\Users\Leo\export.csv -NoTypeInformation
I appreciate the help in advance!

Related

Convert Array value as object property dynamically

I have list of users and i am trying to see if they belong to specific Azure AD group. At the end i want the result to be something like this.
EmailAddress Group1 Group2
User1#email.com Y N
User2#email.com N Y
User3#email.com Y Y
Here is what i got so far:
#authenticate
Connect-MsolService
$users = "User1#email.com", "User2#email.com", "User3#email.com"
$groupLists = "Group1", "Group2"
#create the object with Email, and group name as property name
$output = New-Object -TypeName psobject
$output | Add-Member -MemberType NoteProperty -Name Email -Value ""
$groupLists | ForEach-Object{
$output | Add-Member -MemberType NoteProperty -Name $_ -Value ""
}
#go through each group and user and update the output array
$userExistsInGroup;
foreach ($groupName in $groupLists) {
#get group info
$group = Get-Msolgroup -All | Where-Object {$_.DisplayName -eq $groupName}
#get all members of the group
$members = Get-MsolGroupMember -GroupObjectId $group.ObjectId | Select-Object -ExpandProperty EmailAddress
foreach ($user in $users) {
If ($members -contains $user) {
$userExistsInGroup; = "Y"
} Else {
$userExistsInGroup = "N"
}
# update Email and group property in $output object
......
}
}
Need help updating $output object so that i can display the result the way i want it on the top?
since the same user might show up in different group during loop, if there is existing user in the object, then it will need to update property of the same user that matches with the group so that at the end each row output belongs to one user similar to what i have on the top.
To accommodate a dynamic list of groups, you can use this approach.
$userlist = "User1#email.com", "User2#email.com", "User3#email.com"
$grouplist = "Managers","Directors","Information Technology"
$grouphash = #{}
foreach($group in $grouplist)
{
$grouphash[$group] = Get-MsolGroupMember -GroupObjectId (Get-Msolgroup | Where-Object {$_.DisplayName -eq $group}).objectid
}
foreach($user in $userlist)
{
$userhash = [ordered]#{
EmailAddress = $user
}
$grouplist | ForEach-Object {
$userhash.add($_,($user -in $grouphash[$_].emailaddress))
}
[PSCustomObject]$userhash
}
Each group name will be the property for that group containing true/false if the user is a member.
To collect all the output in a variable simply put $variable = in front of the user foreach loop.
Here is what the output looks like in this example

Powershell script pulling AD Users Group Memberships but CSV formatting a mess

I am trying to create a csv file which contains the username and the group memberships from a list of usernames to a CSV file.
But the CSV file is formatted as below
******;"CN=Cal_ACABLHolidayCalendar_Editor
Username and group in 1 cell
$list = Get-Content c:\Tools\Powershell\ACA\userlist.txt
$list | `
%{
$user = $_;
get-aduser $user -Properties memberof | `
select -expand memberof | `
%{new-object PSObject -property #{User=$user;Group=$_;}} `
} |
export-csv –Path "C:\Tools\Powershell\ADUsers.csv" -Delimiter ‘;’ –NoTypeInformation -Encoding UTF8
How can I have the formatting as the first cell with the username and the below cells with the groups
Export-CSV is the wrong way to achieve your desired solution.
You should be better with something like this:
$excelfile = "C:\Daten\test.xlsx"
###Excel Parameter###
$excel = New-Object -COM "Excel.Application"
$excel.displayalerts = $false
$excel.visible = $false
$excel.usercontrol = $false
$Workbook=$excel.Workbooks.open($excelfile)
$Worksheet=$Workbook.Worksheets.Item(1)
$Worksheet.Activate() | Out-null
$x = 1
$y = 1
$list = get-content c:\daten\list.txt
foreach ($user in $list){
$groups = (get-aduser $user -Properties memberof | select -expand memberof | %{new-object PSObject -property #{User=$user;Group=$_;}} | select -ExpandProperty Group)
$z = $groups.count
$excel.cells.item($y,$x) = $user
for ($i = 2; $i -le $groups.count+1; $i++)
{
$excel.cells.item($i,$x) = $groups[$i]
}
$x=$x+1
}
$Workbook.Save()
$Workbook.Close()
get-process *excel* | kill -Force
Its not 100% correct. Something is wrong with the counter of the username. First user works good though.

Powershell - build a custom object with an unknown number of columns

I need to create a CSV that contains all possible emails addresses that an Active Directory user has. The CSV must be in the following format (very rigid API for where their going to be imported to):
Username | EmailAddress1 | EmailAddress2 | EmailAddressN
My script so far looks like this:
$Group = "GroupNAme
$usersObj = #()
$countMax = 0
$GetAdGroup = Get-AdGroup -Identity $Group -Properties *
[array]$members = $GetAdGroup.Members
ForEach ($member in $members) {
$currentUser = get-aduser -Identity $member `
-Properties EmailAddress, ProxyAddresses |
Where {$_.Enabled -eq "True"}
$countTemp = ($currentUser.ProxyAddresses).count
if ($countTemp -gt $countMax){ $countMax = $countTemp}
foreach ($mailAdd in $currentUser.ProxyAddresses) {
$usersOBJ += [pscustomobject]#{
'Username' = $currentUser.SamAccountName;`
'ProxyAddresses' = $mailAdd.SubString(5)
}
}
$usersOBJ | Export-CSV -NoTypeInformation C:\Export.csv
Now my existing Object spits out the Users as follows:
UserName | Emailaddress1
Username | Emailaddress2
Username | EmailsaddressN
I can't seem to make the leap into working out how to create a better object. I can get the max number of ProxyAddresses that occur but I'm not sure how to figure that into building my object and then populating the values of the $currentUser.ProxyAddresses into those columns.
I've read about Hash tables but they don't seem to fit my requirements, usually taking the form:
Username1 | Username2
Emailaddress1 | Emailaddress1
Emailaddress2 | Emailaddress2
Can anyone please point me in the right direction?
Cheers!
You just need to separate the values you're adding a bit. Add the username to a single object before the loop, then add additional properties on an as-needed basis. Finally, add the object to your array to be exported.
Try this:
...
$x = New-Object System.Object
$x | Add-Member –type NoteProperty –Name UserName –Value $currentUser.SamAccountName
$i=0
foreach ($mailAdd in $currentUser.ProxyAddresses) {
$i++
$x | Add-Member –type NoteProperty –Name "Emailaddress$i" –Value $mailAdd.SubString(5)
}
$usersOBJ += $x
Assuming you add all the users to $usersOBJ before exporting the csv, the columns should work perfectly for any number of proxy addresses.

How to get list of selected AD Groups, that a large list of users are members of?

I have the below working script that checks if a large list of users in a CSV file are a member of an AD group and writes the results to results.csv.
Not sure how to convert the script so I can change $group = "InfraLite" to $group = DC .\List_Of_AD_Groups.CSV.
So the script doesn't just return matches for one AD group but so it returns matches for the 80 AD groups contained in the List_of_AD_groups.csv also. Writing a YES/NO for each AD group in a new column in the CSV (or if that's not possible creating a seperate .csv file for each group with results would do also.
I could do this manually by changing the value of $group and export file name, and re-running the script 80 times but must be a quick was with PS to do this?
e.g. results.csv:
NAME AD_GROUP1 AD_GROUP2 AD_GROUP80 etc etc.
user1 yes no yes
user2 no no yes
user3 no yes no
echo "UserName`InfraLite" >> results.csv
$users = GC .\user_list.csv
$group = "InfraLite"
$members = Get-ADGroupMember -Identity $group -Recursive |
Select -ExpandProperty SAMAccountName
foreach ($user in $users) {
if ($members -contains $user) {
echo "$user $group`tYes" >> results.csv
} else {
echo "$user`tNo" >> results.csv
}
}
I played with this for a while, and I think I found a way to get you exactly what you were after.
I think Ansgar was on the right path, but I couldn't quite get it to do what you were after. He mentioned that he didn't access to an AD environment at the time of writing.
Here is what I came up with:
$UserArray = Get-Content 'C:\Temp\Users.txt'
$GroupArray = Get-Content 'C:\Temp\Groups.txt'
$OutputFile = 'C:\Temp\Something.csv'
# Setting up a hashtable for later use
$UserHash = New-Object -TypeName System.Collections.Hashtable
# Outer loop to add users and membership to UserHash
$UserArray | ForEach-Object{
$UserInfo = Get-ADUser $_ -Properties MemberOf
# Strips the LPAP syntax to just the SAMAccountName of the group
$Memberships = $UserInfo.MemberOf | ForEach-Object{
($_.Split(',')[0]).replace('CN=','')
}
#Adding the User=Membership pair to the Hash
$UserHash.Add($_,$Memberships)
}
# Outer loop to create an object per user
$Results = $UserArray | ForEach-Object{
# First create a simple object
$User = New-Object -TypeName PSCustomObject -Property #{
Name = $_
}
# Dynamically add members to the object, based on the $GroupArray
$GroupArray | ForEach-Object {
#Checking $UserHash to see if group shows up in user's membership list
$UserIsMember = $UserHash.($User.Name) -contains $_
#Adding property to object, and value
$User | Add-Member -MemberType NoteProperty -Name $_ -Value $UserIsMember
}
#Returning the object to the variable
Return $User
}
#Convert the objects to a CSV, then output them
$Results | ConvertTo-CSV -NoTypeInformation | Out-File $OutputFile
Hopefully that all makes sense. I commented as much of it as I could. It would be very simple to convert to using ADSI if you didn't have RSAT installed on whatever machine you're running this on. If you need that let me know, and I'll make some quick modifications.
I've also tossed a slightly modified version of this in a Gist for later reference.
The trivial solution to your problem would be to wrap your existing code in another loop and create an output file for each group:
$groups = Get-Content 'C:\groups.txt'
foreach ($group in $groups) {
$members = Get-ADGroupMember ...
...
}
A more elegant approach would be to create a group mapping template, clone it for each user, and fill the copy with the user's group memberships. Something like this should work:
$template = #{}
Get-Content 'C:\groups.txt' | ForEach-Object {
$template[$_] = $false
}
$groups = #{}
Get-ADGroup -Filter * | ForEach-Object {
$groups[$_.DistinguishedName] = $_.Name
}
Get-ADUser -Filter * -Properties MemberOf | ForEach-Object {
$groupmap = $template.Clone()
$_.MemberOf |
ForEach-Object { $groups[$_] } |
Where-Object { $groupmap.ContainsKey($_) } |
ForEach-Object { $groupmap[$_] = $true }
New-Object -Type PSObject -Property $groupmap
} | Export-Csv 'C:\user_group_mapping.csv' -NoType

Powershell to get user attributes given samaaccount

I have a notepad list of 100 users. Normally I use the below script to get all the users within one OU but this time I have users from different OU and I have to search using Samaccountname.
clear
$UserInfoFile = New-Item -type file -force "C:\Scripts\UserInfo.txt"
"Login`tGivenname`tEmail" | Out-File $UserInfoFile -encoding ASCII
Import-CSV "C:\Scripts\OU.txt" | ForEach-Object {
$dn = $_.dn
$ObjFilter = "(&(objectCategory=User)(objectCategory=Person))"
$objSearch = New-Object System.DirectoryServices.DirectorySearcher
$objSearch.PageSize = 15000
$objSearch.Filter = $ObjFilter
$objSearch.SearchRoot = "LDAP://$dn"
$AllObj = $objSearch.FindAll()
foreach ($Obj in $AllObj)
{ $objItemS = $Obj.Properties
$Ssamaccountname = $objItemS.samaccountname
$SsamaccountnameGN = $objItemS.givenname
$SsamaccountnameSN = $objItemS.sn
$SsamaccountnameEN = $objItemS.mail
"$Ssamaccountname`t$SsamaccountnameGN`t$SsamaccountnameSN`t$SsamaccountnameEN" | Out-File $UserInfoFile -encoding ASCII -append
} # End of foreach
} # End of ForEach-Object
I am trying to use the list of samaccountname to get the name and email of those users. I am new to Powershell so the above script itself was a bit difficult for me to grasp and now I am on an even more difficult task.
Not sure if I understand your question correctly, but if you want to filter the user list by account names you could do something like this:
$accounts = Get-Content userlist.txt
...
$objSearch.FindAll() | ? {
$accounts -contains $_.Properties.sAMAccountName
} | % {
"{0}`t{1}`t{2}" -f ($_.Properties.givenname, $_.Properties.sn, $_.Properties.mail)
}
BTW, I'd recommend using the ActiveDirectory PowerShell module if possible. That will allow you to retrieve user accounts with a simple Get-ADUser, thus simplifying your code. The OU can be extracted from the user's distinguished name by splitting the dn at the first comma. Something like this:
$accounts = Get-Content userlist.txt
Get-ADUser * -Properties * | ? {
$accounts -contains $_.Properties.sAMAccountName
} | select #{n="ou";e={($_.distinguishedName -split ",", 2)[1]}}, mail, givenName, sn, homeDirectory
or like this:
Get-Content userlist.txt | Get-ADUser -Properties * |
select #{n="ou";e={($_.distinguishedName -split ",", 2)[1]}}, mail, givenName, sn, homeDirectory
Untested, though, since I don't have an AD at hand here.
I can't test it now but give this a try. You don't need to search AD if you know the user's DN. You can bind to it directly using the DN.
Import-CSV "C:\Scripts\OU.txt" | ForEach-Object {
$dn = $_.dn
$user = [adsi]"LDAP://$dn"
New-Object PSObject -Propertry #{
samaccountname = $user.Properties['samaccountname']
givenname = $user.Properties['givenname']
sn = $user.Properties['sn']
mail = $user.Properties['mail']
}
} | Export-Csv $UserInfoFile