Home > Mobile >  Powershell script to display a list of users and respective permissions of a shared mailbox
Powershell script to display a list of users and respective permissions of a shared mailbox

Time:02-15

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()
  • Related