Category Archives: Microsoft 365

Update Room and Equipment Mailboxes features using the Resource Schema

When creating room mailboxes, it is good to show features of room mailbox to end users for easy identification.

By default in GAL description will only show “Room” which may not be sufficient to identify capabilities of Room while booking.

For example, we can update details like TVScreen, whiteboard, Smartboard with room.

Using resouce schema we can update all features of a room mailbox.

#To check current resource config

We can add resource schema using below commands.

Set-ResourceConfig -ResourcePropertySchema @{add="Room/WithTVScreen"}
Set-ResourceConfig -ResourcePropertySchema @{add="Room/Whiteboards"}

Adding resource config value will not update any mailbox, but we will have to set these configs on room mailboxes.

If a item is not there in resource config, you can’t add that item on room mailbox.

Also, only a alphanumeric value is allowed and space is not allowed.

Set-Mailbox R_BoardRoom -ResourceCustom   @{add= "WithTVScreen"}
Set-Mailbox R_PinkRoom -ResourceCustom  @{add= "WithTVScreen", "Whiteboards"}
Set-Mailbox R_SmartRoom -ResourceCustom  @{add= "WithTVScreen", "Whiteboards", "VideoConf" }

Once you update and download the GAL, you will see below results.

Add members to Azure AD/Microsoft 365 Groups in bulk

We can bulk update Microsoft 365/Azure AD Groups using PowerShell. We just need a list of users UPN or primary SMTP Addresses.

Get the group’s object ID.

You can copy the group’s object ID from Azure AD console from properties tab or use below command.

#Connect Azure AD
(Get-AzureADGroup -SearchString Test-Group).ObjectId

If you want to add a mailbox to the group, use below command, it will add to Test-Group

#Connect Azure AD and Exchange online if not connected already. 
Connect-ExchangeOnline -UserPrincipalName <Your O365 Admin ID>

Add-AzureADGroupMember -ObjectId <Group's Object ID> -RefObjectId (Get-Mailbox

If you want to add a set of Azure AD users, for example all users start with TestUser, below command will add all the users start with TestUser to TestGroup

Get-AzureADUser -SearchString TestUser | foreach {Add-AzureADGroupMember -ObjectId <Gorup's ObjectID> -RefObjectId $_.ObjectID}

If you have a list of users, create a file Userlist.txt [One UPN or email per line] and save in C:\Temp folder. Below command will add all the users mentioned in Userlist.txt to the Test-Group

#Connect Azure AD and Exchange online if not connected already.
Connect-ExchangeOnline -UserPrincipalName <Your Microsoft 365 Admin ID>
Get-Content C:\Temp\UserList.txt | foreach {Add-AzureADGroupMember -ObjectId <Group's Object ID> -RefObjectId (Get-Mailbox $_).ExternalDirectoryObjectId}

Add Microsoft 365 licenses in bulk

We can add bulk license to Microsoft 365 users using Microsoft 365 PowerShell, though it is always good to create a Dynamic group for license assignment. But, we can have situation when we want to add licenses to some users who already have other license assigned and doesn’t have any common attribute to create and add new license.

For Example, you have new “Phone System” license and want to add that license to selected users for testing or for UAT.

If user doesn’t have any license and we are adding license for first time, then we will have to set location first.

Step 1 –

Get list of users and save in a file “UserList.txt”, one UPN per line and place in C:\Temp folder on your computer.

The below command will set location on all users mentioned in “UserList.txt” to US.


#When prompted enter your Microsoft 365 Admins accounts UPN and password.

Get-Content C:\Temp\UserList.txt | foreach {Get-MsolUser -UserPrincipalName $_ | Set-MsolUser -UsageLocation US}

If users are being synced from On-prem AD, you can set msExchUsageLocation on on-prem AD users and wait for the Sync to complete.

Run below command on your On-Prem AD server.

Get-Content C:\Temp\UserList.txt | foreach {Get-ADUser -Filter {UserPrincipalName -eq $_ | Set-ADUser -Add @{msExchUsageLocation = "US" }

Step 2 –

Get the SkuPartNumber of the license you want to add to users.


#When prompted enter your Microsoft 365 Admins accounts UPN and password.

Get-AzureADSubscribedSku | Select Sku*, ConsumedUnits

Note down the license Sku number to use in next command. For example for “Phone System” SkuPartNumber is MCOEV.

Step 3 –

The below command will add “PhoneSystem” license to all users and there would not be any change in existing license.

Get-Content C:\Temp\UserList.txt  | foreach { Write-Host "Processing $_";  Set-MsolUserLicense -UserPrincipalName $_  -AddLicenses "YourTenantname:MCOEV" }

Remove Reoccuring meeting invite

There are situations when an organizer wants to cancel a meeting invite, but not able to delete and invite re-appears in attendees calendars, and we may need to remove the invite from backend.

It becomes extremely important to examine the results before deleting them to make sure you have targeted the correct meeting invite or email.

If you want to search all the mailboxes for specific meeting, use below command. This command will give you estimated results only and will not delete anything from the mailboxes.

Get-Mailbox | Search-Mailbox -SearchQuery "kind:meetings AND Subject:'Bi Weekly IT Review Meeting' AND" -EstimateResultOnly

If you want to search a set of mailboxes, you can copy the PrimarySMTP addresses in a list and use the command like below.

The below command will export all the specified meeting invite from all mentioned mailboxes to a target folder in a target mailbox.

This command will also not delete anything from mailbox, once results are exported you can review the results and make sure you are targeting the correct meeting invite or email.

Get-Content C:\Temp\List.txt | Get-Mailbox | Search-Mailbox -SearchQuery "kind:meetings AND Subject:'Bi Weekly IT Review Meeting' AND" -TargetMailbox -TargetFolder "ExportResult"

Once you are sure that correct meeting invite or email will be deleted, you can run the delete command to remove the meeting.

Search-Mailbox -SearchQuery '(subject:"Bi Weekly IT Review Meeting") AND (kind:meetings) and' -DeleteContent -Loglevel Full  -TargetMailbox -TargetFolder "ExportResult"

On the target mailbox, you can download the logs to see all the actions.

Your flow needs attention…

When you have a flow running with your account and have MFA enabled, you often receive an error email about your flow connection, which states “YOUR FLOW NEEDS ATTENTION….”

This notification was sent as the flow had failure runs due to invalid flow connection.

We can fix this by just reauthenticating the flow connection but if this comes too frequent then it may require some back end fix.

  • Get rid of “Remember Multi-factor authentication”
    • If you are using “Remember Multi-factor authentication” option from
    • AAD Console –> Users –> All Users –> Multi-Factor Authentication -> Service Settings.
  • We should move away from this setting and configure the same using Conditional Access policy.
  • This setting overrides the default behavior for modern authentication clients (like Microsoft Outlook) who only prompt every 90 days, by default.
  • We can configure the same setting using Conditional Access Policies –
  • AAD Console -> Security -> Conditional Access -> Access Controls -> Sessions –> Sign-in Frequency.
  • Exclude selected users from MFA
    • The one solution is to exclude the user from MFA, but this may not be possible in all cases, especially when we have MFA enabled for all the accounts.
    • If you apply MFA using conditional access policies, then excluding some users is simple, just create one group and then all such users to that group and exclude the group in the policy.
    • Open Azure AD console and select Security and click Conditional Access.
    • If you already have a policy, open the policy and in Assignment section -> Users and groups – Exclude – Add the group.
  • Exclude Flow location IPs from MFA.
    • The another solutions can be to exclude the Flow location services IP from MFA.
    • For this create a “New Network” location, like “IP range for Flow in APAC”.
    • Azure AD Console -> Security -> Named Locations.
  • Add IPs of Flow of your tenant location, you can find IPs using below link.

  • Now in the Conditional Access Policy, Assignments -> Conditions  -> Locations – Exclude the Name location you have created.

allow or suppress the auto replies when sending emails to groups.

Recently one of our users reported an issue that when he sent an email to a large distribution list, he did not receive any Auto Reply, OOF from any user. Though, there were many users had Auto Reply configured at that time.

There are few group properties which can cause this –

ReportToManagerEnabled –  The ReportToManagerEnabled parameter specifies whether delivery status notifications (also known as DSNs, non-delivery reports, NDRs, or bounce messages) are sent to the owners of the group (defined by the ManagedBy property). Valid values are

  • $true: Delivery status notifications are sent to the owners of the group.
  • $false: Delivery status notifications aren’t sent to the owners of the group. This is the default value.

ReportToOriginatorEnabled –  The ReportToOriginatorEnabled parameter specifies whether delivery status notifications (also known as DSNs, non-delivery reports, NDRs, or bounce messages) are sent to senders who send messages to this group. Valid values are:

  • $true: Delivery status notifications are sent to the message senders. This is the default value.
  • $false: Delivery status notifications aren’t sent to the message senders.

The ReportToManagerEnabled and ReportToOriginatorEnabled parameters affect the return path for messages sent to the group. Some email servers reject messages that don’t have a return path. Therefore, you should set one parameter to $false and one to $true, but not both to $false or both to $true.

SendOofMessageToOriginatorEnabled –  The SendOofMessageToOriginatorEnabled parameter specifies how to handle out of office (OOF) messages for members of the group. Valid values are:

  • $true: When messages are sent to the group, OOF messages for any of the group members are sent to the message sender.
  • $false: When messages are sent to the group, OOF messages for any of the group members aren’t sent to the message sender. This is the default value.

Based on the above values, Exchange Online adds a header “X-Auto-Response-Suppress” to message to suppress or allow the Auto Replies or OOF.

Like in my example – SendOofMessageToOriginatorEnabled was False and I can see header “X-Auto-Response-Suppress” with value “DR, OOF, AutoReply” in the message properties.

We can adjust these values to allow or suppress the Auto Replies, OOF from groups.

Get Multi-factor authentication details for Microsoft 365 Users.

Multi-factor authentication is a process where a user is prompted during the sign-in process for an additional form of identification, such as to enter a code on their cellphone or to provide a fingerprint scan.

In Azure AD, user can register for MFA using below link. We can also use conditional access policy to force users to register for MFA, before we implement MFA to avoid any inconvenience.

Using the below scripts, we can get details of MFA registered users and methods they are using for MFA.

The script takes three parameters.

-UPN – You can pass any single user’s UPN and will get details of MFA for user.

-UserList – You can pass a list of users as a txt file. One UPN per line.

-All – You can pass All switch if you want to get details of all users in your Microsoft 365 environment.

EXAMPLE 1 – This example will give MFA details of supplied UPN “”

Get-MFAUserDetails -UPN

EXAMPLE 2 – This example will give MFA details of users supplied in “MFAUPN.txt” file, one UPN per line, without any header.

Get-MFAUserDetails -UserList C:\temp\MFAUPN.txt

EXAMPLE 3 – This example will give MFA details of ALL Users enabled for MFA in your Microsoft 365 environment.

Get-MFAUserDetails -All

Download the script from here.

  Script to get details of MFA enabled users.

 This script can be used to get details of MFA enabled users

   Author Subodh Uniyal <>

. Disclaimer: Author holds no responsibility to damages caused due to incorrect use of this script.
  It is recommended that you run this script in  your lab before using in production.

This example will give MFA details of supplied UPN ""

   Get-MFAUserDetails -UPN

This example will give MFA details of users supplied in "MFAUPN.txt" file, one UPN per line, without any header. 

 Get-MFAUserDetails -UserList C:\temp\MFAUPN.txt

This example will give MFA details of ALL Users enabled for MFA in your Microsoft 365 environment. 

 Get-MFAUserDetails -All



#Connect to MSOL
Write-Host "Checking Current MsolService Session"
try {
    Get-MsolDomain -ErrorAction Stop | Out-Null
} catch {
Write-Host "No current session detected. Please supply credentials to connect to Microsoft Online Service"

$Result = @()
$Results = @()
$reportPath = ".\"
$ReportName = "MFAReport_$(get-date -format dd-MM-yyyy_hh-mm-ss).CSV"
$MFAReport = $reportPath + $reportName

Function Get-MFAUserDetails
$Result = @()
$Results = @()
Foreach ($User in $List)

Write-Host "Processing user "$User.DisplayName""
    $StrongAuthenticationRequirements = $User | Select-Object -ExpandProperty StrongAuthenticationRequirements
    $StrongAuthenticationUserDetails = $User | Select-Object -ExpandProperty StrongAuthenticationUserDetails
    $StrongAuthenticationMethods = $User | Select-Object -ExpandProperty StrongAuthenticationMethods

$Result = [PSCustomObject]@{
DisplayName = $User.DisplayName
UPN = $User.UserPrincipalName
IsLicensed = $User.IsLicensed
RememberDevicesNotIssuedBefore = $StrongAuthenticationRequirements.RememberDevicesNotIssuedBefore
StrongAuthenticationUserDetailsPhoneNumber = $StrongAuthenticationUserDetails.PhoneNumber
StrongAuthenticationUserDetailsEmail = $StrongAuthenticationUserDetails.Email
DefaultStrongAuthenticationMethodType = ($StrongAuthenticationMethods | Where {$_.IsDefault -eq $True}).MethodType
$Results +=$Result
$Results | ft
$Results | Export-Csv $MFAReport -NoTypeInformation
$Location = (Get-Location).path + "\" + "$ReportName"
Write-Host "Results are saved in File $Location" -ForegroundColor Yellow

 IF ($UserList) 
    $List = Get-Content -Path $UserList | foreach {Get-MsolUser -UserPrincipalName $_}
    Write-Host "Processing with UserList provided, there are "($List).count" users to process."
     ElseIf ($UPN)
       $List = Get-MsolUser -UserPrincipalName $UPN
        ElseIF ($All)
         $List = Get-Msoluser -all | Where-Object {$_.StrongAuthenticationMethods -like "*"}
         Write-Host "Processing with all users enabled for MFA"
           Write-Host "Please input at least one parameter, check help for details."

Recover Deleted Emails in Microsoft 365

In The Previous article we have learnt, how we can find the cause of deleted emails from users’ mailbox.

In similar way, we can also recover selected deleted emails back to the user’s mailbox original folder, without any import of export process.

Search items for particular time frame :-

Get-RecoverableItems -Identity -SourceFolder RecoverableItems -FilterStartTime "12/04/2020 00:00:00" -FilterEndTime "12/05/2020 23:00:00"

To restore these items, we can simply pipe this to Restore RecoverableItems and save results. Once the command is complete, you can examine file RestoreLogs.csv for items restored.

Get-RecoverableItems -Identity -SourceFolder RecoverableItems -FilterStartTime "12/04/2020 00:00:00" -FilterEndTime "12/05/2020 23:00:00"  | Restore-RecoverableItems | Export-Csv C:\Temp\RestoreLogs.csv -Append -NoType

If we want to restore only actual email items, we can use FilterItemType

Get-RecoverableItems -Identity -SourceFolder RecoverableItems -FilterStartTime "12/04/2020 00:00:00" -FilterEndTime "12/05/2020 23:00:00"  -FilterItemType Ipm.Note | Restore-RecoverableItems | Export-Csv C:\Temp\RestoreLogs.csv -Append -NoType

In case we want to restore emails deleted from “Sent Items” only, we can use this.

Get-RecoverableItems -Identity -FilterItemType Ipm.Note -SourceFolder RecoverableItems | where {$_.LastParentPath -eq "Sent Items"} | Restore-RecoverableItems | Export-Csv C:\Temp\RestoreLogfile.csv -Append -NoType

You cannot search folders in the archive mailbox. To search for deleted items across all locations, don’t pass a SourceFolder parameter to Get-RecoverableItems. For example, this search finds all deleted items for the specified mailbox:

$Items = Get-RecoverableItems -Identity

We can then filter the $items variable and restore the selected emails.

Location of Deleted Items –

  • DeletedItems: The Deleted Items folder in the user’s mailbox.
  • RecoverableItems: The Deletions sub-folder in the Recoverable Items folder of the user’s mailbox. This is where items go after they are removed from the Deleted Items folder. Exchange’s Single Item Recovery (SIR) feature holds items deleted from the Deleted Items folder in the Deletions folder until the deleted items retention period defined for the mailbox expires (typically 14 days with a maximum of 30 days). SIR exists to ensure that users have a reasonable chance of recovering deleted items if they make a mistake.
  • PurgedItems: The Purges sub-folder in the Recoverable Items folder. Deleted items kept due to a retention policy are stored here until the retention period set in the policy expires.

Searching for Specific Types of Deleted Items:-

• IPM.Note: A standard email message item.

• IPM.Appointment: A calendar meeting or appointment.

• IPM.Task: A task.

• IPM.Contact: A contact.

• IPM.File: A file stored in the mailbox. These include files created by Office 365 as the result of some processing.

Search Mailbox Audit Logs in Office 365

There may be situations when end user(s) report missing emails from their mailbox. It may be possible that they have inadvertently deleted the emails, but want to know the cause.

If we have mailbox auditing enabled, we can find out the cause. The auditing should be enabled by default in Microsoft 365.

The first step is to track the emails and see, if there were emails delivered/Sent to/from user’s mailbox. We can use tracking logs for this.

To check the emails received –

Get-MessageTrace -RecipientAddress -StartDate 12/10/2020 -EndDate 12/18/2020 -Status Delivered

To check the email received –

Get-MessageTrace -RecipientAddress -StartDate 12/10/2020 -EndDate 12/18/2020

If we got the emails in result and these emails are not in user’s mailbox, then we need to investigate further.

Check if the mailbox Audit logs are enabled for user.

Get-Mailbox | ft PrimarySMTPAddress, AuditEnabled

Get the Mailbox Folder Statics to check if there are emails in Deleted items.

Get-MailboxFolderStatistics "" -FolderScope RecoverableItems -IncludeOldestAndNewestItems | Format-List Name,FolderAndSubfolderSize

If auditing is enabled, we can check the mailbox audit logs and find the delete cause.

Search the Audit Logs for the user:-

Search-MailboxAuditLog -ShowDetails -StartDate 12/10/2020 -EndDate 12/18/2020 -ResultSize 250000 | Export-Csv -Path C:\Temp\Mailbox_Audit_Logs.csv -Notype

Open the audit logs in excel and then filter the Operation column to filter for deleted events.

Here, we can see that the mailbox owner have deleted the emails from “Sent Items” folder.

We can also run the below script to find the Audit Logs –

In next article, we will learn how to restore deleted emails back to user’s mailbox.

Bypassing Focused Inbox

In Microsoft 365 and, Focused Inbox separates your inbox into two tabs – Focused and Other.

All the important emails are on Focused tab and other promotional/bulk/auto generated emails are on Other tab.

Outlook uses Artificial Intelligence to separate emails into Focused and Other tab.

We can control this setting from “Outlook on Web” or using “Microsoft 365” PowerShell.

  1. Disable Focused Inbox on Outlook on Web :-

Login Outlook on Web -> Mail -> Layout -> Don’t sort my messages.

2. Disable Focused Inbox on Outlook :-

Users’ can also move and adjust the Focused Inbox settings using Outlook.

In the View tab -> Click on “Show Focused Inbox”

3. To change settings for some emails :-

From your inbox, select the Focused or Other tab, and then right-click the message you want to move.

Move to Focused – If you want only the selected message moved.

Always Move to Focused – If you want all future messages from the sender to be delivered to the Focused tab.

4. To disable Focused Inbox using Microsoft 365 PowerShell :-

Connect Microsoft 365 PowerShell.

To view Focused Inbox Setting –

Get-FocusedInbox -Identity

To disable focused Inbox –

Set-FocusedInbox -Identity -FocusedInboxOn $false

To enable focused Inbox –

Set-FocusedInbox -Identity -FocusedInboxOn $true

5. Disable/Enable Focused Inbox at the organization level :-

To view the settings –

Get-OrganizationConfig | fl Focused*

To disable the Focused Inbox at organization level –

Set-OrganizationConfig -FocusedInboxOn $false

To enable the Focused Inbox at Organization level –

Set-OrganizationConfig -FocusedInboxOn $true

6. Force a email to show in Focused Inbox –

There may be a requirement sometime to show an important email in users’ Focused Inbox, like a HR, Payroll communication.

We can create a transport rule and force this using a header “X-MS-Exchange-Organization-BypassFocusedInbox”

Create using UI :-

Create using PowerShell –

New-TransportRule -Name "Bypass Focused Inbox" -From "" -SetHeaderName "X-MS-Exchange-Organization-BypassFocusedInbox" -SetHeaderValue "true"

« Older Entries