I thought I'd post this here just in case I'm barking up the wrong tree. I'm looking to put together a Powershell script that can list all of the members of a shared mailbox and their respective permissions (Limited to "UserName", "Name", "Mailbox", "Full Access", "Send As", "SOBO"). My plan is for the script to ask for an email address and output to look something like this:
User Name Mailbox Full Access Send As SOBO Success
---- ---- ------- ----------- ------- ----- --------
ACB123 Smith, James Examplebox Yes Yes No Success
ABC213 Smith, Pete Examplebox Yes No Yes Success
I was surprised when I couldn't find anything online that is even similar to this.
My script, so far, grabs a list of users that have Full Access (well, it's supposed to, it seems to grab the lesser permissions too, but this actually serves my purpose). The script then strips the collected info down to usernames, then runs a for each
to gather information to complete the table above. It runs an AD query for the display names as running Get-ADPermission
is not an option.
I haven't got as far as to do the Send As and SoBo parts of the table because I can't get the table to be bigger than 4 columns before it turns into a list, instead of a table. I know there's the Format-Table
command but I can't seem to integrate it into my current pscustomobject setup - which is currently set up to split successful queries from failed ones.
This is what I have so far, it's pretty dirty, but this is just my best guess to how something like this should work:
import-moduleactivedirectory
Install-ModuleExchangeOnlineManagement
Connect-ExchangeOnline-ShowBanner:$false
Clear-Host
$ErrorActionPreference='Stop'
$status=[System.Collections.Generic.List[pscustomobject]]::new()
$Entered_email = Read-host"Enter a mailbox address"
$Collect_users = Get-Mailbox-Identity$Entered_email-ResultSize:Unlimited|Get-MailboxPermission|?{($_.IsInherited -eq$False) -and-not ($_.User -match"NT AUTHORITY")} |select-expandpropertyuser
foreach($userin$Collect_users)
{
try
{
$User= ($User.Split("@")[0])
$Access=Get-MailboxPermission-Identity$Entered_email-User$User|select-PropertyAccessRights|select-ExpandPropertyAccessRights
if ($Access-like"*FullAccess*") {$Access_Result="yes"
}else{$Access_Result="No"}
$User_name = Get-ADUser-identity$User-propertiesDisplayName|select-expandpropertyDisplayName
$status.Add(
[pscustomobject]@{
User = $user
Name = $user_name
Mailbox = $Entered_email.Split("@")[0]
'Full Access'= $Access_Result
Status ='SUCCESS'
})
}
catch
{
$status.Add(
[pscustomobject]@{
User = $user
Status ='FAILED'
Message = $_.Exception.Message
})
}
}
$success,$failed=$status.Where({$_.Status -eq'SUCCESS'},'Split')
$success|Out-String|Write-Host-ForegroundColorGreen
$failed |Out-String|Write-Host-ForegroundColorRed
Pause
Any advice would be appreciated at this stage, I definitely could use help with the table, I could probably figure out how to add the Send As and SoBo searches, but if anyone knows some really efficient ones please let me know.
Thanks in advance.
CodePudding user response:
You are duplicating efforts a LOT with this. Line 9 would return you all the users that have access and the access they have, but you discard everything but the user's account name, and then later loop through those users and get their access one at a time. Here I keep that info, then use it inside the loop to reduce calls to Exchange to get perms again and again. I also changed a variable name since you re-used $User
for different things which can be very confusing.
import-module activedirectory
Install-Module ExchangeOnlineManagement
Connect-ExchangeOnline -ShowBanner:$false
Clear-Host
$ErrorActionPreference='Stop'
$status=[System.Collections.Generic.List[pscustomobject]]::new()
$Entered_email = Read-host "Enter a mailbox address"
$Collect_users = Get-Mailbox -Identity $Entered_email -ResultSize:Unlimited|Get-MailboxPermission|?{($_.IsInherited -eq $False) -and -not ($_.User -match"NT AUTHORITY")} #|select -ExpandProperty user
$status=foreach($Alias in $Collect_users)
{
try
{
$User= ($Alias.User.Split("@")[0])
$Access=$Alias.AccessRights
if ($Access -like "*FullAccess*") {$Access_Result="yes"
}else{$Access_Result="No"}
$User_name = Get-ADUser -identity $User -properties DisplayName|select -expandproperty DisplayName
[pscustomobject]@{
User = $user
Name = $user_name
Mailbox = $Entered_email.Split("@")[0]
'Full Access'= $Access_Result
Status ='SUCCESS'
}
}
catch
{
[pscustomobject]@{
User = $user.user
Status ='FAILED'
Message = $_.Exception.Message
}
}
}
$success,$failed=$status.Where({$_.Status -eq'SUCCESS'},'Split')
$success|Out-String|Write-Host-ForegroundColorGreen
$failed |Out-String|Write-Host-ForegroundColorRed
Pause
CodePudding user response:
I started making a "mailbox manager" gui last year and never got around to finishing it, but maybe there's some useful stuff you could pull from it. The last thing I was trying to add was who has access/sendas TO the selected account (bottom part of the gui), which isn't quite working...but the first part (see what accounts/sendas an account has permission for) is working.
The eventual idea was to add a "save" button in so you could check/uncheck the tickboxes as you'd like in the gui and it'd adjust the permissions.
#Init
$logpath = "C:\Scripts\Logs\MailboxPermissions.log"
#Create session on 365 Exchange server
if ((Get-PSSession).Computername -notmatch "outlook.office365.com"){Connect-365}#or: Connect-ExchangeOnline -ShowBanner:$false
$UPNs = Get-Mailbox -Identity * | select -ExpandProperty UserPrincipalName
$AccToDatasource = [System.Collections.ArrayList]::new()
$BS1 = [System.Windows.Forms.BindingSource]::new()
$BS1.DataSource = $AccToDatasource
$AccByDatasource = [System.Collections.ArrayList]::new()
$BS2 = [System.Windows.Forms.BindingSource]::new()
$BS2.DataSource = $AccByDatasource
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$get_permissions={
$AccToDatasource.Clear()
$AccByDatasource.Clear()
$user = $ComboBox1.Text
write-host "Checking $($user)"
Get-EXOMailboxPermission -Identity $user | ?{$_.User -ne "NT AUTHORITY\SELF"} | %{
$tablerow = New-Object psobject
$data = @{Email="$($_.User)";Inbox=1;SendAs=0}
$tablerow | Add-Member -NotePropertyMembers $data -TypeName tablerow
$AccToDatasource.Add($tablerow)
}
Get-EXORecipientPermission -Identity $user | ?{$_.Trustee -ne "NT AUTHORITY\SELF"} | %{
$indx = [array]::IndexOf($AccToDatasource.Email,$_.Trustee)
if($indx -ne -1){
$AccToDatasource[$indx].SendAs = 1
}else{
$tablerow = New-Object psobject
$data = @{Email="$($_.Trustee)";SendAs=1}
$tablerow | Add-Member -NotePropertyMembers $data -TypeName tablerow
$AccToDatasource.Add($tablerow)
}
}
$BS1.ResetBindings($true)
<##Attempt 1
Get-EXOMailbox -MailboxPlan "ExchangeOnlineEnterprise" -Properties UserPrincipalName | select -ExpandProperty UserPrincipalName | %{
Start-ThreadJob {
Get-EXOMailboxPermission -Identity $using:_ -User $using:user -ErrorAction SilentlyContinue
} | Wait-Job | Receive-Job | %{
$tablerow = New-Object psobject
$data = @{Email="$($_.Trustee)";Inbox=1;SendAs=0}
$tablerow | Add-Member -NotePropertyMembers $data -TypeName tablerow
$AccByDatasource.Add($tablerow)
}
}
$BS2.ResetBindings($true)
#>
#Attempt 2
Get-EXOMailbox -MailboxPlan "ExchangeOnlineEnterprise" -Properties UserPrincipalName | select -ExpandProperty UserPrincipalName | %{Start-ThreadJob {Get-EXOMailboxPermission -Identity $using:_ -User $using:user -ErrorAction SilentlyContinue}} | Wait-Job | Receive-Job | %{
$tablerow = New-Object psobject
$data = @{Email="$($_.Trustee)";Inbox=1;SendAs=0}
$tablerow | Add-Member -NotePropertyMembers $data -TypeName tablerow
$AccByDatasource.Add($tablerow)
}
$BS2.ResetBindings($true)
}
#Form Init
$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = New-Object System.Drawing.Point(600,650)
$Form.text = "Mailbox Manager"
$Form.TopMost = $false
$ComboBox1 = New-Object system.Windows.Forms.ComboBox
$ComboBox1.width = 370
$ComboBox1.height = 30
$ComboBox1.location = New-Object System.Drawing.Point(137,25)
$ComboBox1.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
$ComboBox1.Items.AddRange($UPNs)
$ComboBox1.AutoCompleteSource = "ListItems"
$ComboBox1.AutoCompleteMode = "SuggestAppend"
#$ComboBox1.add_SelectedIndexChanged({
# if ($ComboBox1.Text.Length -gt 10){
# get-permissions -user $ComboBox1.Text
# }
#})
$Label1 = New-Object system.Windows.Forms.Label
$Label1.text = "Select 365 User:"
$Label1.AutoSize = $true
$Label1.width = 25
$Label1.height = 30
$Label1.location = New-Object System.Drawing.Point(14,25)
$Label1.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
$Label2 = New-Object system.Windows.Forms.Label
$Label2.text = "Has access to:"
$Label2.AutoSize = $true
$Label2.width = 25
$Label2.height = 30
$Label2.location = New-Object System.Drawing.Point(14,55)
$Label2.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
$Label3 = New-Object system.Windows.Forms.Label
$Label3.text = "Accessible by:"
$Label3.AutoSize = $true
$Label3.width = 25
$Label3.height = 30
$Label3.location = New-Object System.Drawing.Point(14,358)
$Label3.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
$DataGridView1 = New-Object system.Windows.Forms.DataGridView
$DataGridView1.text = "Emails"
$DataGridView1.width = 560
$DataGridView1.height = 250
$DataGridView1.AutoGenerateColumns = $false
$DataGridView1.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewTextBoxColumn -Property @{"Name"="Email"})) | Out-Null
$DataGridView1.Columns['Email'].DataPropertyName = "Email"
$DataGridView1.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewCheckBoxColumn -Property @{"Name"="Inbox"})) | Out-Null
$DataGridView1.Columns['Inbox'].DataPropertyName = "Inbox"
$DataGridView1.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewCheckBoxColumn -Property @{"Name"="SendAs"})) | Out-Null
$DataGridView1.Columns['SendAs'].DataPropertyName = "SendAs"
$DataGridView1.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewTextBoxColumn -Property @{"Name"="Start"})) | Out-Null
$DataGridView1.Columns['Start'].DataPropertyName = "Start"
$DataGridView1.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewTextBoxColumn -Property @{"Name"="End"})) | Out-Null
$DataGridView1.Columns['End'].DataPropertyName = "End"
$DataGridView1.ColumnHeadersVisible = $true
$DataGridView1.AutoSizeColumnsMode = 10
$DataGridView1.DataSource = $BS1
$DataGridView1.location = New-Object System.Drawing.Point(11,82)
$DataGridView1.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#e0dede")
$DataGridView1.add_DataError({write-host "hit error"})
$DataGridView2 = New-Object system.Windows.Forms.DataGridView
$DataGridView2.width = 560
$DataGridView2.height = 250
$DataGridView2.location = New-Object System.Drawing.Point(9,383)
$DataGridView2.AutoGenerateColumns = $false
$DataGridView2.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewTextBoxColumn -Property @{"Name"="Email"})) | Out-Null
$DataGridView2.Columns['Email'].DataPropertyName = "Email"
$DataGridView2.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewCheckBoxColumn -Property @{"Name"="Inbox"})) | Out-Null
$DataGridView2.Columns['Inbox'].DataPropertyName = "Inbox"
$DataGridView2.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewCheckBoxColumn -Property @{"Name"="SendAs"})) | Out-Null
$DataGridView2.Columns['SendAs'].DataPropertyName = "SendAs"
$DataGridView2.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewTextBoxColumn -Property @{"Name"="Start"})) | Out-Null
$DataGridView2.Columns['Start'].DataPropertyName = "Start"
$DataGridView2.Columns.Add((new-object -TypeName System.Windows.Forms.DataGridViewTextBoxColumn -Property @{"Name"="End"})) | Out-Null
$DataGridView2.Columns['End'].DataPropertyName = "End"
$DataGridView2.ColumnHeadersVisible = $true
$DataGridView2.AutoSizeColumnsMode = 10
$DataGridView2.DataSource = $BS2
$DataGridView2.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#e0dede")
$loadButton = New-Object system.Windows.Forms.Button
$loadButton.text = "Load"
$loadButton.width = 60
$loadButton.height = 30
$loadButton.location = New-Object System.Drawing.Point(509,25)
$loadButton.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
$loadButton.Add_Click($get_permissions)
$saveButton = New-Object system.Windows.Forms.Button
$saveButton.text = "Save"
$saveButton.width = 60
$saveButton.height = 30
$saveButton.location = New-Object System.Drawing.Point(509,341)
$saveButton.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
$Form.controls.AddRange(@($Label1,$Label2,$Label3,$ComboBox1,$DataGridView1,$DataGridView2,$saveButton, $loadButton))
[void]$Form.ShowDialog()