Friday, 15 November 2019

Export Office 365 Users using Graph API in Powershell

In Powershell, you can easily get Azure AD user details using the Azure AD Powershell command Get-AzureADUser. In some cases, we may be required to use Microsoft Graph API to query details from Azure AD or other Office 365 services. In this post, I am going to explain how to retrieve user details from Azure AD using Graph API and export details to CSV file in Powershell.

Based on your need, you have to acquire Graph Access token using Azure AD Application with below permission scopes.
  • User.ReadBasic.All - Read all users' basic profiles.
  • User.Read.All - Read all users' full profiles.
In this post, I am going to use PnP.PowerShell app to get access token. Install the PnP Online Powershell module and run the below commands to get graph access token with required permission scopes.
Connect-PnPOnline -Scopes "User.Read.All"
$AccessToken =Get-PnPAccessToken
You can refer Microsoft Graph Documentation to know more about required permissions for every end-point URL.

Call Microsoft Graph API and get users data:

Once you have acquired the required access token, you can easily query graph api using the Invoke-RestMethod cmdlet by passing the $AccessToken.
$ApiUrl = "https://graph.microsoft.com/v1.0/users"
$Response = Invoke-RestMethod -Headers @{Authorization = "Bearer $AccessToken"} -Uri $ApiUrl -Method Get
$Users = $Response.value
By default, the API call returns only 100 users and we have to set the $top parameter to get more users. Also in a single API call, we can get only 1000 users. If you have more than 1000 users, we have to make another request with nextLink token to get another 1000 users and we need to loop this process until we get the nextLink token as a null value.
$Result = @()
$ApiUrl = "https://graph.microsoft.com/V1.0/users?`$top=999"
$Response = Invoke-RestMethod -Headers @{Authorization = "Bearer $AccessToken"} -Uri $ApiUrl -Method Get
$Users = $Response.value
$Result = $Users

While ($Response.'@odata.nextLink' -ne $null) {
$Response = Invoke-RestMethod -Headers @{Authorization = "Bearer $AccessToken"} -Uri $Response.'@odata.nextLink' -Method Get
$Users = $Response.value
$Result += $Users
}
Note: In Powershell $ is the special character, so we need to put escape character ` (back-tick) before $ symbol in string (ex: `$).

Export Users to CSV file

You can export the result to CSV file using the Export-CSV cmdlet.
$Result | Export-CSV "C:\\O365Users.CSV" -NoTypeInformation -Encoding UTF8
Export only selected fields:
$Result | Select displayName,userPrincipalName, mail |
Export-CSV "C:\\O365Users.CSV" -NoTypeInformation -Encoding UTF8

Request users with selected properties

You can use the $select query parameter to retrieve only the required set of user properties. For example, to return displayName, jobTitle, and mail, you need to add the query $select=displayName,jobTitle,mail in your users endpoint api url.
$ApiUrl = "https://graph.microsoft.com/v1.0/users?`$select=displayName,jobTitle,mail"
Note: If you do not specify $select query, by default, only a limited set of properties are returned ( businessPhones, displayName, givenName, id, jobTitle, mail, mobilePhone, officeLocation, preferredLanguage, surname, userPrincipalName ). To return additional properties (ex: accountEnabled, assignedLicenses, assignedPlans, etc..), you must specify the desired set of user properties using the $select query.
$ApiUrl = "https://graph.microsoft.com/v1.0/users?`$select=displayName,assignedPlans,accountEnabled"
You can refer OData select parameter to know more about select query.

Request users with filter query parameter

You can limit the results by filtering users in the server-side by specifying the $filter query parameter. For example, if you want to limit users by their department, you can use the below query.
$ApiUrl = "https://graph.microsoft.com/v1.0/users?`$filter=Department eq 'Sales'"
You can refer OData filter parameter to know more about filter query.

Request users with select, filter and top parameters in a single query

You have to join multiple query parameters with AND ("&") symbol.
$ApiUrl = "https://graph.microsoft.com/v1.0/users?`$filter=Department eq 'Sales'&`$select=displayName,mail&`$top=999"

Monday, 11 November 2019

Remove Mailbox Permissions (Full Access or Send As) using Powershell

Removing existing mailbox permission is one of the important Exchange management task. We can use the Remove-MailboxPermission cmdlet to remove permissions from user mailbox or shared mailbox. This cmdlet is available for both Exchange On-Premises and Exchange Online environment. To perform this task, your account should already have the server roles Organization Management and Recipient Management.

Note: Before proceed, based on your environment connect Exchange Online Remote Powershell or Exchange Management Shell (On-Premises).

The following command removes the full access permission for the user "morgan@contoso.com" from the mailbox "alex@contoso.com".
Remove-MailboxPermission -Identity "alex@contoso.com" -User "morgan@contoso.com" -AccessRights FullAccess -InheritanceType All -Confirm:$false
Identity - The identity (ex: Name, UPN, etc.. ) of the mailbox where you are removing permissions.
User - This parameter specifies the user mailbox that will get permissions removed.
AccessRights - Required rights (ex: FullAccess, SendAs, etc..) to remove.

Remove full access permission from all shared mailboxes:

The below commands retrieve all shared mailboxes and remove full access permissions from all shared mailboxes for the single user mailbox "morgan@contoso.com".
$user = "morgan@contoso.com"
$sharedmbxs = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize:Unlimited | Select Identity,Alias,DisplayName
$i = 1
$totalmbxs = $sharedmbxs.Count
foreach ($mbx in $sharedmbxs) {
Write-Progress -activity "Processing user $($mbx.DisplayName)" -status "$i out of $totalmbxs completed"
Remove-MailboxPermission -Identity $mbx.Identity -User $user -AccessRights FullAccess -InheritanceType All -Confirm:$false
$i++
}

Remove permission from shared mailboxes for multiple users:

For bulk users removal, you can keep the user mailbox identities in CSV file. Consider the CSV file "O365Users.csv" which contains user name (or upn) of users with the column header UserName.
$users = Import-Csv 'C:\O365Users.csv'
$sharedmbxs = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize:Unlimited | Select Identity,Alias,DisplayName
foreach ($user in $users) {
foreach ($mbx in $sharedmbxs) {
Write-Progress -activity "Processing user $($user.UserName) - shared mailbox $($mbx.DisplayName)" -status "Processing....."
Remove-MailboxPermission -Identity $mbx.Identity -User $user.UserName -AccessRights FullAccess -InheritanceType All -Confirm:$false
}
}
Your csv content should be in below format :
UserName
"user1@contoso.com"
"user2@contoso.com"
"user3@contoso.com"

Remove permission for multiple users from multiple mailboxes:

In some cases, you may need to delete access for a set of users from multiple mailboxes. In this case, you can keep both the user and mailbox identities in CSV file. Consider the CSV file "remove-fullaccess.csv" which contains user and mailbox identities under the column header UserName and Mailbox.
Import-CSV 'C:\remove-fullaccess.csv'| ForEach {
Write-Progress -activity "Processing mailbox $($_.Mailbox) - user $($_.UserName)" -status "Processing..."
Remove-MailboxPermission -Identity $_.Mailbox -User $_.UserName -AccessRights FullAccess -InheritanceType All -Confirm:$false
}
Your csv content should be in below format :
Mailbox, UserName
"sharemailbox1@contoso.com", "user1@contoso.com"
"sharemailbox2@contoso.com", "user1@contoso.com"
"usermailbox1@contoso.com", "user1@contoso.com"
"usermailbox1@contoso.com", "user2@contoso.com"