Category Archives: Microsoft 365

How to recover data from a Deleted or Inactive mailbox in Exchange Online

The default mailbox retention in Microsoft 365 is 30 days, we can recover deleted/Inactive user’s mailbox to a new user or to a temporary user.

Please note that if you remove license form a user, mailbox will also be removed, once we reassign the license, mailbox will reconnect automatically.

To list all the deleted mailboxes

Get-Mailbox -SoftDeletedMailbox | select DisplayName, PrimarySmtpAddress, WhenSoftDeleted, RecipientTypeDetails, GUID, CustomAttribute6, DistinguishedName

#You can export this list in CSV.
Get-Mailbox -SoftDeletedMailbox | select DisplayName, PrimarySmtpAddress, WhenSoftDeleted, RecipientTypeDetails, GUID, CustomAttribute6, DistinguishedName | Export-Csv C:\Temp\Deletedmailboxes.csv -NoTypeInformation 

#In the output file we can find the mailbox information we want to recover.

We can also find just one mailbox from deleted mailboxes.

Get-Mailbox -SoftDeletedMailbox -Filter {name -like "*Mailbox Name*"} | fl Guid, DistinguishedName

Note down the mailbox GUID from above command and run below commands to restore the mailbox.

#Get details of inactive mailbox
$InactiveMailbox = Get-Mailbox -SoftDeletedMailbox -Identity 532f8e25-b435-4a17-b253-9097632680a1
#Run restore command
New-MailboxRestoreRequest -Name UserName-Restore -SourceMailbox $InactiveMailbox.DistinguishedName -TargetMailbox <DN of TargetMailbox> -TargetRootFolder Restore -AllowLegacyDNMismatch

Now, you can trace the restore using below command

#To get all the restore request.
Get-MailboxRestoreRequest  | Get-MailboxRestoreRequestStatistics

#To get just one restore request.
Get-MailboxRestoreRequestStatistics -Identity RestoreRequest

MFA Details of Microsoft 365 Admin Accounts

Protecting your Admin accounts in Microsoft 365 is a vital need, we should have MFA enabled for all Admin accounts in M365. Also, it is recommended that at least all privileged users use Microsoft Authenticator App for MFA.

We can have users added to multiple role groups and it is sometime hard to identify who is not complying with these policies.

Below script is available on TechNet to list users from all Role Groups, their MFA details and password age.

https://github.com/o365soa/scripts/blob/master/Get-365RoleReport.ps1

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
Get-ResourceConfig

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
Connect-AzureAD
(Get-AzureADGroup -SearchString Test-Group).ObjectId

If you want to add a mailbox to the group, use below command, it will add User@domain.com to Test-Group

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

Add-AzureADGroupMember -ObjectId <Group's Object ID> -RefObjectId (Get-Mailbox User@domain.com).ExternalDirectoryObjectId

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-AzureAD
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.

Connect-MsolService

#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.

Connect-AzureAD

#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 From:User@domain.com" -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 From:User@domain.com" -TargetMailbox ExportResult@Domian.com -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 from:User@domain.com' -DeleteContent -Loglevel Full  -TargetMailbox ExportResult@Domian.com -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.

https://docs.microsoft.com/en-us/power-automate/limits-and-config

  • 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.

https://aka.ms/mfasetup

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 “User@domain.com”

Get-MFAUserDetails -UPN User@domain.com

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.

<#
.Synopsis
  Script to get details of MFA enabled users.

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

. NOTES
   Author Subodh Uniyal <TechCognizance@outlook.com>

. 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.

.EXAMPLE
This example will give MFA details of supplied UPN "User@domain.com"

   Get-MFAUserDetails -UPN User@domain.com

.EXAMPLE
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
This example will give MFA details of ALL Users enabled for MFA in your Microsoft 365 environment. 

 Get-MFAUserDetails -All

#>

    Param
    (
        
        [Parameter(ValueFromPipeline=$true)]
                   [String[]]$UserList,
                   [String]$UPN,
                   [String[]]$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"
Connect-MsolService
}

$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."
    
    Get-MFAUserDetails($List)
    }
     ElseIf ($UPN)
       {
       $List = Get-MsolUser -UserPrincipalName $UPN
       Get-MFAUserDetails($List)
       }
        ElseIF ($All)
         {
         $List = Get-Msoluser -all | Where-Object {$_.StrongAuthenticationMethods -like "*"}
         Write-Host "Processing with all users enabled for MFA"
          Get-MFAUserDetails($List)
         }
           Else
           {
           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 User@domain.com -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 User@domain.com -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 User@domain.com -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 User@domain.com -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 User@domain.com

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.

« Older Entries