Posted in : Azure, Microsoft, Office 365, Powershell, Security

11 months ago

OneDrive for Business is great! The administration tools provided is not!
If you’re still reading you might agree with me when I say that Sharepoint Online admin center is far from the best experience when administrating anything related to OneDrive. Luckily we have access to everything we might need using the OneDrive REST API, a portion of the beloved Microsoft Graph API.
Whether migrating to Onedrive, applying new guidelines/compliance rulesor simply auditing the Onedrive permissions you will want to do it using Microsoft Graph. The functions mentioned here is available in the end of the post as well as a post with further reading about how to use the function.
So today we are going to have a detailed look on how to audit OneDrive sharing permission as well as cleaning up any unwanted configurations.
As we are using an Azure AD Application to audit and clean we are going to need the following Application permissions are required to inspect and remove unwanted sharing permissions.
 
With our Application configured we can query for a users files. However the API only lists files per folder and has at the time of this writing no recursive option. Thus we need to perform the enumeration recursively ourselves in the form of a function called ”Get-OneDriveItems”.

Function Get-OneDriveItems {
Param(
    $UserId,
    $token,
    $credential,
    $TenantID,
    $itemId
)
    $AllItems = @()
    If($ItemId){
        $AllItems += Invoke-MSGraphQuery -URI "https://graph.microsoft.com/v1.0/users/$UserId/drive/items/$itemId/children" -token $token -tokenrefresh -recursive -credential $credential -tenantID $TenantID | Select -ExpandProperty value
    }
    else{
        $AllItems += Invoke-MSGraphQuery -URI "https://graph.microsoft.com/v1.0/users/$UserId/drive/root/children" -token $token -tokenrefresh -recursive -credential $credential -tenantID $TenantID | Select -ExpandProperty value
    }
    $AllItems | Where-Object{$_.folder.childCount -ge 1} | ForEach-Object{
        $AllItems += Get-OneDriveItems -UserId $UserId -token $token -credential $credential -TenantID $TenantID -itemId $_.Id
    }
    Write-Verbose "Found $($AllItems.Count) files in folder $itemId"
    Return $AllItems
}

To list all files we run the function against a AzureAD UserID. We simply select a user and run the following line of code.

$AllItems = Get-OneDriveItems -UserId $User.id -token $token -credential $credential -TenantID $TenantID

Now when we have all the files we need to do a permission get request per item. Given that default storage size is up to one terabyte, this can take a LONG time and probably needs to be optimized using json batching and/or threading, examples are found in my other post at the end of the post. For simplicity I’m just going to demonstrate how to do this in a sequential fashion.

$AllPermissions = $AllItems | ForEach-Object{
    $uri = "https://graph.microsoft.com/v1.0/users/$($user.id)/drive/items/$($_.id)/permissions"
    Invoke-MSGraphQuery -URI $uri -token $token -tokenrefresh -credential $credential -tenantID $TenantID -method get
}

Now when we have the permissions for all files, we can inspect them. It’s important to undestand how a OneDrive permission object is constructed in order to later filter for them. Check out the documentation for more information.
https://docs.microsoft.com/en-us/graph/api/resources/permission?view=graph-rest-1.0

In the example below, we’re going to DELETE all anonymous sharing permissions, and we do this by listing all permissions on line 4.

$AllPermissions | ForEach-Object{
    $thisPermission = $_
    $fileId = $thisPermission.'@odata.context'.Split("'")[-2]
    [array]$permissionsToRemove = $thisPermission.value | Where-Object{$_.value.link.scope -eq 'anonymous'}
    $permissionsToRemove | ForEach-Object{
        Invoke-MSGraphQuery -URI "https://graph.microsoft.com/v1.0/users/$($User.id)/drive/items/$fileId/permissions/$($_.id)" -token $token -tokenrefresh -credential $credential -tenantID $TenantID -method DELETE
    }
}

If you want to add filters, for example remove all non-external permissions we can add the filter below as an -OR

$_.value.grantedTo.user.email -notlike "*@xenit.se"

And there we have it. The organization files are no longer in risk of external exposure!

If you’re interested in Microsoft GraphAPI don’t hesitate to send me an email at vikingur.saemundsson@xenit.se
Thanks for reading!
 
Github project:
https://github.com/Freakling/Powershell-MicrosoftGraphAPI
More Microsoft GraphAPI:
https://xenit.se/techblogg/querying-microsoft-graph-with-powershell-the-easy-way/
OneDrive/OneDrive for Business/Sharepoint Document Libraries REST API:
https://docs.microsoft.com/en-us/graph/api/resources/onedrive?view=graph-rest-1.0
Manage Sharing using SharePoint Online Admin Center:
https://docs.microsoft.com/en-us/onedrive/manage-sharing

Tags : Azure, Azure AD, Microsoft, OD4B, ODFB, Onedrive, OneDrive for business, PowerShell, Security, Sharing, Windows

Add comment

Your comment will be revised by the site if needed.