How to sync any folder to OneDrive?

Do you want to sync/backup directories that out side of OneDrive sync’ed directory? For example, you have a directory at “D:\SDCard\PortableApps\PNotesPortable” and you want take a backup to OneDrive.

You have come to right place. This works for OneDrive (consumer) as well as OneDrive for Business. Here is how you do it.

Creating a junction for the directory D:\SDCard\PortableApps\PNotesPortable under OneDrive sync’ed location. That’s it.

  1. Open Command Prompt.
  2. Type this:
MKLink /J <OneDrive-Folder-Path> <Full path of the folder you want to sync>


C:\Users\Awesome>mklink /j "C:\Users\Awesome\OneDrive\Software\PNotes" "D:\SDCard\PortableApps\PNotesPortable"
Junction created for C:\Users\Awesome\OneDrive\Software\PNotes <<===>> D:\SDCard\PortableApps\PNotesPortable

Now you will see a Directory junction show up under C:\users\Awesome\OneDrive\Software. That’s all. Now OneDrive will sync this folder content to the cloud.

Nice Trick, hope you can use it yourself. Enjoy!

Exchange Online: Calendar Permissions – “Some Permissions cannot be displayed”

I needed remove few disabled users from the permission set in the Calendar. I got this error: “The security principal specified is already on the permission set”. To fix this error, I was using my other blog post:

Here is the wrinke. If you have Full Access permission to a mailbox, when you open the Calendar Properties dialog box and select Permissions in Outlook, you will see a message Some permissions cannot be displayed.


Fortunately This is documented in

The new Office software updates changed UI look ‘n feel of Sharing Calendar and managing permissions dialog box. They call it “much simpler user experience when sharing a calendar”. The side burn for this new UI update is that there are two sharing scenarios that are no longer supported.

  • Sharing a calendar if you have Full Access permission to your mailbox
  • Sharing a calendar if you have Author permission to a mailbox

Sure Microsoft. You had to make our life little harder and call it “much simpler user experience”.

The solution is:

1. Close Outlook

2. Add this Registry Key:

Registry key:


Value: 1

3. Open Outlook and try managing the Calendar permissions now.

Hope this helped you. Enjoy.

Exchange (OnPrem): How to make Emails from Internal Application servers are trusted/internal emails?

Usually Emails originated within Exchange Organization are considered “Internal” trusted emails. All other emails coming outside of Exchange organization are “External” emails and usually considered less trustworthy.

How to make the emails coming from internal application servers are trusted emails in On-Prem Exchange environment? Answer is understanding of how to setup the Exchange Receive Connector(s).

I would recommend you have separate receive connector with its own IP Address. What I mean is you assign additional IP address to the NIC on the Exchange Transport servers, specify this additional IP address in the Receive Connector to receive emails from Intranet servers and devices.

Open the Receive Connector properties window, go to Security. Enable Externally secured (for example, with IPsec) under Authentication settings, and enable Exchange Servers under Permission Groups as below.

Now for the keen people, the explanation for why we have to choose the above settings.

Externally Secured setting says the emails received to the connector are “External Authoritative” servers, so trust these emails. This is assuming the external servers are in physically controlled network and you know and trust the sources.

The ExternalAuthoritative authentication method requires the ExchangeServers permission group. This combination of authentication method and security group permits the resolution of anonymous sender email addresses for messages that are received through this connector. So this anonymous sender email address can have the domain names (e.g., and Exchange will accept these emails.

Hope you had a clear idea after reading this blog. Leave me a “Hello” below.


Move Mailbox to OnPrem: “MigrationPermanentException: Cannot find a recipient that has mailbox GUID “

You are trying to move a mailbox from Exchange Online to Exchange OnPrem, and you get this error message:

“MigrationPermanentException: Cannot find a recipient that has mailbox GUID <GUID>”

MSKB Article explains why it happens and how to solve it. It involves note down the mailbox GUID from Exchange Online and modifying the mailbox GUID in OnPrem to the Remote Malibox. That is two different PowerShell sessions (one to Exchange online and another one to Exchagne OnPrem).

If you use my script to connect both Exchange Environments on the same PowerShell Window, you can fix the GUID in single command.

So here it is:

Set-OPRemoteMailbox -Identity <MailboxName> -ExchangeGuid (Get-EOMailbox -Identity <MailboxName>).ExchangeGuid.guid

How to Connect Exchange Online & On-Premises Exchange server on a single PowerShell Window

Are you connecting to Exchange Online and On-premises Exchange server in two different PowerShell windows? Are you struggling to script to do things with two different Exchange environments?

Say No More to that struggling. Say HELLO to “PREFIX” when connecting to Exchange server in PowerShell. This blog post will show you how to connect both Exchange environments (cloud and on-prem) on same PowerShell Window and use both Exchange servers on a single script.

Before we go further: I am using Exchange Online PowerShell V2 Module that supports modern authentication (Okta, AzureAD, OneLogin, etc.,). Install it from here:

Now the little script to connect to both Exchange environments. You may download the script from >>> HERE <<<.

 * * * * Connect-ExchangeEnvironments.ps1 * * * *
 Connects Exchange Online and Exchange OnPrem with "Prefix" option.

 Prefix: EO for Exchange Online and OP for OnPrem.

 Written by: Anand, The Awesome

# ACTION REQUIRD: Enter the Admin Username, email address, and  OnPrem Exchange Server Name below
$OnPremUser = "Domain\AdminUserName"
$CloudUser = ""
$OnPremExchangeServer = ""

# Connection URI to connect to OnPrem Exchange PowerShell Web Session
$ConnectionURI = "http://$OnPremExchangeServer/PowerShell/"

# Get credentials for Exchange Online and Exchange OnPrem Admin account
$OnPremcredential = Get-Credential -UserName $OnPremUser -Message "Enter Password for Exchange On-Prem Admin"
$O365credential = Get-Credential -UserName $CloudUser -Message "Enter Password for Exchange Online Admin"

# Connect to Exchange Online V2
Connect-ExchangeOnline -UserPrincipalName $CloudUser `
                       -Prefix 'EO' `
                       -Credential $O365credential 

# Connect to Exchange OnPremises
$Session = New-PSSession -ConfigurationName Microsoft.Exchange `
                         -ConnectionUri $ConnectionURI `
                         -Authentication Kerberos `
                         -Credential $OnPremcredential
Import-PSSession $Session -Prefix OP

 * * * * End of the Script * * * *
 When you are done with Exchange Work:
 You may kill the Exchange sessions when you are done with following Command.
 Get-PSSession | Remove-PSSession

Alright, it’s time to explain how this works.
Notice the Prefix option on these both commands in the script:

Connect-ExchangeOnline -UserPrincipalName $CloudUser `
                       -Prefix ‘EO’ `
                       -Credential $O365credential 

Import-PSSession $Session -Prefix OP

I chose EO for Exchange Online and OP for On Premises for the tag. You MAY choose to have your own Tag here. Once you run this script, it will connect to Exchange Online and Exchange OnPrem on the PowerShell Window.

To use the Exchange command, you use the tag with the usual Exchange commands. See examples below:

On-Prem Exchange – Get-Mailbox:
Get-OPMailbox -Identity

Exchange Online – Get-Mailbox:
Get-EOMailbox -Identity

Hope this helps you all Exchange Admins. Enjoy.

PowerShell: List all DL Members recursively

I had a situation to list all members of distribution group (DL) or security group to validate the members. Problem was the DL had other DLs as members. I had to write a quick script to list all members recursively.

If you have the same requirement of listing all members of a DL, feel free to use my script. It create a CSV file of the member list.

Make sure you connect to you Exchange environment first in PowerShell. It works Exchange Online and On-Prem Exchange servers.

    This script lists all members of a distribution list including all 
    child groups members recursively. It create a CSV file with all
    groups of the given distribution group.

    Parameter: Distribution group Alias or Name or Email Address

    .\List-DLMembers.ps1 -DLName "NA-Sales"


Function    : Expand-Group
Parameter   : Distribution Group Name
Description : This function populates all the members of the
given distribution group to a global variable named $Global:Users 

Function Expand-Group ($GroupName)
    $members = Get-DistributionGroupMember -Identity $GroupName

    foreach($member in $members)
        $RecipientType = (Get-Recipient $member.Alias).RecipientType
        $member.Name + "`t`t`t" + $RecipientType
        if ($RecipientType -like "*DistributionGroup*")
            # Found an child group - calling myself to expand the group
            Expand-Group -GroupName $member.Alias

        # Create a PSCustomObject of the current member
        $MemberObject = [PSCustomObject] @{
            Name = "$($member.Name)" 
            Title = "$($member.Title)" 
            Department = "$($member.Department)" 
            Email = "$($member.PrimarySMTPAddress)" 
            Memberof = "$GroupName"

        # Store the member object to Users array
        $global:users += $MemberObject
    End of the Function

 °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸ °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸

                THE SCRIPT STARTS HERE

 °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸ °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸

# Create a Global Array Variable to store all DL member objects
$global:users = @()

# Call the Expand-Group function to populate the all DL members
Expand-Group -GroupName $DLname

#Store the member objects to a CSV file
$filename = ".\$DLName-Members.csv"
$global:users | ConvertTo-Csv | Out-File -FilePath $filename

 °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸ °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸

                END OF THE SCRIPT

 °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸ °º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸


PowerShell Tip: How to remove items from an Array? Yes, it is possible.

Are you trying to figure out how to remove array items from an Array? Were you end up coding a foreach loop & create a new array?

I have an easy way without using new array or foreach loop. Here it is:

$ArrayVar = $ArrayVar | Where-Object{-not($_ -eq 'ItemValue')}

Now to describe how it been used in a code…I created a quick sample code. Note that I was removing two items at once at line number 9.

$SuperHeros = @("Thor","IronMan","AntMan","Hulk","Clint Barton","DeadPool","Captain Marvel","Black Widow")
"Here are the Super Heros:"

"`n`nOops..Black Widow and Clint Barton are not really super heros..Remove them at once."
"Yes Sir."

#Remove Black Widow and Clint Barton...Are they Superheros? or side kicks?
$SuperHeros = $SuperHeros | Where-Object {-not(($_ -eq 'Black Widow') -or ($_ -eq 'Clint Barton'))}

"`n`nNew List of SuperHeros:"

I ran this code and here is the result:

Here are the Super Heros:
Clint Barton
Captain Marvel
Black Widow

Oops..Black Widow and Clint Barton are not really super heros..Remove them at once.
Yes Sir.

New List of SuperHeros:
Captain Marvel

Hope you like this trick. 😉 Leave me a reply!

PowerShell: Combine CSV files into a single CSV file

I had a need to combine multiple CSV files. And worked for few minutes and came up with this PowerShell method.

Get-ChildItem -Filter *.csv -Path C:\Scripts\CSVFiles | Select-Object -ExpandProperty FullName | Import-Csv | Export-Csv C:\Scripts\CSVFiles\CombinedFile.csv -NoTypeInformation -Append

Idea of this method is

  1. Get the filenames with full path of the CSV files
  2. Import them all
  3. Pipe the import the CSV files to Export-CSV to a file. Note the “-Append” parameter.

Hope this help you too.

CSV Viewer – an awesome Powershell solution

When working with some CSV files in my Windows Servers, I was wondering how can I view the CSV file without installing any third-party viewers.

Here is my one-liner PowerShell solution. I am using Out-GridView with “-Wait” option. Make sure PowerShell Execution Policy is set to run local scripts.

Here is how you do it

Log onto to your Windows Server (or on your local computer).
Open Notepad.

Copy and Paste this code into Notepad:

REM ...:::>  Anand, the Awesome  <:::...
Start /Wait Powershell -Command "Import-Csv -Path %1 | Out-GridView -Title %1 -Wait"

Save this file as CSV-Viewer.bat in your favorite location.

Now find a CSV file on your disk, right-click and go to Properties. Change Open With to the CSV-Viewer.bat file that you created in above step.

That’s all. Now try double-clicking on any CSV file. It will open GridView. You can search things in the CSV file, or sort any column or Filter the data.

Exchange: Calendar Folder Permissions and Delegates

There are two kinds of permission for Calendar in Mailbox. A user can have

  • Folder permission to calendar
  • Delegate permissions

Folder permission is used by another user to access the calendar and Delegate permission is given to a user to manage the calendar behalf of the giving user. Both kinds of permission can be given to user from Outlook or by Exchange PowerShell.

How to do it in Outlook?

Folder permission: In Outlook Go to Calendar section, right click on the calendar on the left pane, Choose properties/Permissions.

Delegate permission: In Outlook, click File / Account Settings / Delegate Access.

Detailed Help:

How to do it in Exchange Admin Shell?

Open PowerShell and connect to Exchange (or Exchange Online).

Folder Permission:

Give Reviewer access to’s calendar.

Add-MailboxFolderPermission -Identity\Calendar -User -AccessRights Reviwer

Delegate Access:

Make as Delegate with Editor access to’s calendar.

Add-MailboxFolderPermission -Identity\Calendar -User -AccessRights Editor -SharingPermissionFlags Delegate 

Detailed Help: