How to automate OneDrive shortcuts with code

How to automate OneDrive shortcuts with code header image

OneDrive is a great tool for personal productivity! And with the advent of shortcuts you can find your way around Teams or SharePoint folders pretty quick 📂. Yet it it can be time-consuming to manually create shortcuts to Teams and SharePoint folders for each user. Fortunately, it’s now possible to automate this process using the Microsoft Graph. In this blog post, we’ll explain how to create OneDrive shortcuts to Teams and SharePoint folders quickly and easily using the Microsoft Graph 🦒.

Why automate OneDrive shortcuts for Teams and SharePoint?

Shortcuts are a handy feature in OneDrive that allows you to access your favorite folders and files quicker. When it comes to working with Teams and SharePoint, it becomes increasingly important to have shortcuts readily available for users to quickly access and store content in the right location. Especially when you create multiple teams or sites that users have access to. For example, your organization may have created Teams for specific customers or projects, and it’s essential to ensure that users can thus access the associated SharePoint sites or folders. Manually creating shortcuts for each team or site can be time-consuming and prone to human error, especially for larger organizations with multiple teams and SharePoint sites. Or your organization might have a folder that contains all the templates for your organization, and you just want to make sure all users have these templates synced on their OneDrive.

By automating the creation of OneDrive shortcuts for Teams and SharePoint using the Microsoft Graph, you can easily provision these shortcuts for your users. This approach saves time, reduces human error, and ensures that all users have access to the required folders and sites quickly and efficiently. So, let’s dive in and learn how to automate OneDrive shortcuts for Teams and SharePoint with your favorite tool!

Pre-requisites for creating shortcuts

You can create the shortcuts using the Microsoft Graph. To do so you have two options:

  • Create the shortcuts for a single user; all you need is a user access token that has access to the user’s OneDrive (Files.ReadWrite).
  • Create the shortcuts for all users; you need an App token that has access to all users’ OneDrive (Files.ReadWrite.All).

In our sample we assume that you want to create a shortcut to a single folder for all users, so we need an access token that has Files.ReadWrite.All.

You can use m365 util accesstoken get --resource https://graph.microsoft.com to quickly get an access token to be used in other scripts.

You can handout permissions you can use m365 aad approleassignment add --displayName "dgw-cli" --resource "Microsoft Graph" --scope "Files.ReadWrite.All" to make sure the managed identity has the correct permissions.

Creating the shortcut

To create the shortcut you can inspect what happens int he browser when creating a shortcut through the use of the UI. It gives a good indication of the endpoints that are being called. However it does use the SharePoint MySite URL to create the shortcut. You can also use the Microsoft Graph and that does feel a bit better. As this is undocumented you there is a slight risk that it will change in the future ⚠️.

What happens is a single POST request to the users OneDrive URL: https://graph.microsoft.com/v1.0/users/[email protected]/drive/root/children

With a post body that contains the required information for the shortcut. This information consists of a name that can be changed to whatever you fancy. And a set of ID’s to link to the correct SharePoint (or Teams) site and folder.

{
    "name": "Shortcut Demo",
    "remoteItem": {
        "sharepointIds": {
            "listId": "5d2792fd-4153-4745-b552-2d4737317566",
            "listItemUniqueId": "root",
            "siteId": "97a32e0d-386a-4315-ae5f-4388e2188089",
            "siteUrl": "https://contoso.sharepoint.com/sites/m365cli",
            "webId": "b151672d-318c-47a5-a5f4-18534055fce5"
        }
    },
    "@microsoft.graph.conflictBehavior": "rename"
}

If you are connecting a specific folder the listItemUniqueId will be the ID of the folder. If you are connecting a SharePoint site the listItemUniqueId will be root.

If everything succeeds the response will contain the details of the newly created shortcut and looks something like the following:

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('user%40contoso.com')/drive/root/children/$entity",
    "@odata.etag": "\"{6EA833FC-9E4C-4D0D-8537-C88A9591D90B},1\"",
    "createdDateTime": "2023-07-17T12:53:17Z",
    "eTag": "\"{6EA833FC-9E4C-4D0D-8537-C88A9591D90B},1\"",
    "id": "01LXRESRH4GOUG4TE6BVGYKN6IRKKZDWIL",
    "lastModifiedDateTime": "2023-07-17T12:53:17Z",
    "name": "Shortcut Demo - m365cli",
    "cTag": "\"c:{6EA833FC-9E4C-4D0D-8537-C88A9591D90B},1\"",
    "createdBy": {
        "application": {
            "displayName": "dgw-cli",
            "id": "949dfc69-21cd-4d39-9146-812895ab9f06"
        },
        "user": {
            "displayName": "SharePoint App"
        }
    }, ...
    "fileSystemInfo": {
        "createdDateTime": "2023-07-17T12:53:17Z",
        "lastModifiedDateTime": "2023-07-17T12:53:17Z"
    },
    "remoteItem": {
        "id": "01Q2VZR456Y2GOVW7725BZO354PWSELRRZ",
        "size": 89113966,
        "folder": {
            "childCount": 3
        },
        "parentReference": {
            "driveId": "b!DS6jl2o4FUOuX0OI4hiAiC1nUbGMMaVHpfQYU0BV_OT9kiddU0FFR7VSLUc3MXVl",
            "driveType": "documentLibrary"
        },
        "sharepointIds": {
            "listId": "5d2792fd-4153-4745-b552-2d4737317566",
            "listItemUniqueId": "223c1a39-66ed-41dc-93c4-42c91779baf6",
            "siteId": "97a32e0d-386a-4315-ae5f-4388e2188089",
            "siteUrl": "https://contoso.sharepoint.com/sites/m365cli",
            "webId": "b151672d-318c-47a5-a5f4-18534055fce5"
        }
    }
}

A full sample script I used for testing:

$token = m365 util accesstoken get --resource "https://graph.microsoft.com"

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$headers.Add("Authorization", "Bearer $token")

$body = @"
{
    `"name`": `"Shortcut Demo`",
    `"remoteItem`": {
        `"sharepointIds`": {
            `"listId`": `"5d2792fd-4153-4745-b552-2d4737317566`",
            `"listItemUniqueId`": `"root`",
            `"siteId`": `"97a32e0d-386a-4315-ae5f-4388e2188089`",
            `"siteUrl`": `"https://digiwijs.sharepoint.com/sites/m365cli`",
            `"webId`": `"b151672d-318c-47a5-a5f4-18534055fce5`"
        }
    },
    `"@microsoft.graph.conflictBehavior`": `"rename`"
}
"@

$response = Invoke-RestMethod "https://graph.microsoft.com/v1.0/users/[email protected]/drive/root/children" -Method "POST" -Headers $headers -Body $body
$response | ConvertTo-Json

Or if you rather want to use bash:

token=$(m365 util accesstoken get --resource "https://graph.microsoft.com")

headers=(
  "Content-Type: application/json"
  "Authorization: Bearer $token"
)

body='
{
    "name": "Shortcut Demo",
    "remoteItem": {
        "sharepointIds": {
            "listId": "5d2792fd-4153-4745-b552-2d4737317566",
            "listItemUniqueId": "root",
            "siteId": "97a32e0d-386a-4315-ae5f-4388e2188089",
            "siteUrl": "https://digiwijs.sharepoint.com/sites/m365cli",
            "webId": "b151672d-318c-47a5-a5f4-18534055fce5"
        }
    },
    "@microsoft.graph.conflictBehavior": "rename"
}
'

response=$(curl -X POST -H "${headers[@]}" -d "$body" "https://graph.microsoft.com/v1.0/users/[email protected]/drive/root/children")

echo "$response" | jq

Change the shortcut name

The response in the UI will contain the SharePoint Site Title as a suffix (even when using Teams), regardless of the provided name. Something you cannot change in the initial request.

OneDrive UI

However you could use the Microsoft Graph to rename the folder. Since the response when creating an item contains the item ID you can use a PATCH to the following endpoint: /{username}/drive/items/{item-id} and provide the new name in the body.

{
  "name": "new-short-cutname"
}

By doing so after you have created the shortcut the folder name will be updated. I would recommend however to be bit considerate with removing the site title. If you rename all those new shortcuts to ‘Documents’ users still will get lost…

Loading comments…