A coworker made a working PowerShell script to retrieve Mailboxes and Groups from Office 365. We have both admin rights on Office 365 = I can get all of these information with a internet browser on EAC. When I'm executing the PowerShell script with my Office 365 credentials, I get the excepted results. It means that I have the rights access and permissions on Exchange.
My need is to create a Python script to do almost the same thing then to create a human-readable Excel Workbook (probably using openpyxl) and send email later. Many of you will ask to me why I don't complete the PowerShell script, the simple answer is that this script will be a little part of a biggest project, written in Python.
Here, the PowerShell script:
Install-Module -Name AzureAD
Install-Module -Name MSOnline
$CSV_Groups = "C:\tmp\Groups.csv"
#Get Credentials to connect
$Credential = Get-Credential
#Create the session
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Credential -Authentication Basic -AllowRedirection
#Import the session
Import-PSSession $Session -DisableNameChecking
$O365Groups = Get-UnifiedGroup
ForEach ($Group in $O365Groups) {
Get-UnifiedGroupLinks –Identity $Group.Id –LinkType Members | Select-Object @{Name="Group Name";Expression={$Group.DisplayName}}, @{Name="Group Address";Expression={$Group.PrimarySmtpAddress}}, @{Name="User Name";Expression={$_.DisplayName}}, PrimarySmtpAddress | Export-CSV $CSV_Groups -NoTypeInformation -Append -encoding UTF8
}
$O365Groups = Get-DistributionGroup
ForEach ($Group in $O365Groups) {
Get-DistributionGroupMember –Identity $Group.Id | Select-Object @{Name="Group Name";Expression={$Group.DisplayName}}, @{Name="Group Address";Expression={$Group.PrimarySmtpAddress}}, @{Name="User Name";Expression={$_.DisplayName}}, PrimarySmtpAddress | Export-CSV $CSV_Groups -NoTypeInformation -Append -encoding UTF8
}
$CSV_Mailboxes = "C:\tmp\Mailboxes.csv"
Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize:Unlimited | Get-MailboxPermission | Select-Object Identity,User,AccessRights | Export-Csv $CSV_Mailboxes -NoTypeInformation
Remove-PSSession $Session
I don't want an application to have access to Azure AD. The same way the Powershell script ask for user Credentials, I would like my python script to prompt for Office 365 credentials. I would like my python script to work this way to be sure only office 365 users with right rights can use this python script.
I have tested 4 python libraries, for all of them, I succeed the authentication but I don't find the right way to list all groups and mailboxes
Using ExchangeLib (https://github.com/ecederstrand/exchangelib):
import exchangelib
exchangelib_credentials = exchangelib.Credentials(
username=self.username,
password=self.password
)
exchangelib_account = exchangelib.Account(
primary_smtp_address="[email protected]",
credentials=exchangelib_credentials,
autodiscover=True
)
for mailbox in account.protocol.get_searchable_mailboxes(expand_group_membership=True):
print(mailbox)
# ==> exchangelib.errors.ErrorAccessDenied:
# The caller has not assigned any of the RBAC roles requested in the management role header.
I'm certainly not using this library correctly because I don't get why I need more permissions than the ones I already have? I've followed this page, but I've got the same error: https://documentation.arcserve.com/Arcserve-UDP/Available/V6.5/ENU/Bookshelf_Files/HTML/Solutions%20Guide/UDPSolnGuide/udp_add_role_group_exchgonline.htm
I tried Azure SDK for Python (https://github.com/Azure/azure-sdk-for-python), O365 (https://github.com/O365/python-o365) and Office365-REST-Python-Client (https://github.com/vgrem/Office365-REST-Python-Client). I succeed to (seems to) authenticate with all of them, but failed to list all mailboxes or groups.
Anyone could help?
I don't know about the Exchange Graph API, but EWS simply does not provide this information. Your best bet is the GetSearchableMailboxes service that you tried in exchangelib. EWS requires users to have the Discovery Management RBAC role for this to succeed.
Since you already have PowerShell commands that work for you, I would probably just call these commands from your Python script using a subprocess. Here's a blog post with some examples: https://www.phillipsj.net/posts/executing-powershell-from-python/