Skip to content

Instantly share code, notes, and snippets.

@jamiechalmerzlp
Created March 14, 2025 20:00
Show Gist options
  • Select an option

  • Save jamiechalmerzlp/41804153f47405ec5c2292715a34cc83 to your computer and use it in GitHub Desktop.

Select an option

Save jamiechalmerzlp/41804153f47405ec5c2292715a34cc83 to your computer and use it in GitHub Desktop.

Revisions

  1. jamiechalmerzlp created this gist Mar 14, 2025.
    75 changes: 75 additions & 0 deletions BulkProvisionOneDrive.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    <#
    Author: Jamie Chalmers of Agilico - 3rd Line Tech & Telco Engineer
    Description: This script automates the provisioning of OneDrive for licensed users in a SharePoint Online environment.
    It connects to Microsoft Graph and SharePoint Online, retrieves licensed users, and provisions their OneDrive accounts in batches.
    #>

    Param(
    [Parameter(Mandatory = $True)]
    [String]
    $SharepointURL,

    [Parameter(Mandatory = $True)]
    [String]
    $tenantID
    )

    # Check if the Microsoft.Graph module is installed, and install it if necessary
    Write-Host "Checking if the Microsoft.Graph module is installed..."
    if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {
    Write-Host "Microsoft.Graph module is not installed. Installing now..."
    try {
    Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force -ErrorAction Stop
    Import-Module Microsoft.Graph -ErrorAction Stop
    Write-Host "Microsoft.Graph module installed and imported successfully."
    } catch {
    Write-Host "Failed to install or import the Microsoft.Graph module. Error: $_" -ForegroundColor Red
    exit 1
    }
    } else {
    Write-Host "Microsoft.Graph module is already installed."
    Import-Module Microsoft.Graph -ErrorAction Stop
    }

    # Define the required scope for Microsoft Graph API
    $scope = 'User.Read.All'

    # Connect to Microsoft Graph and SharePoint Online
    Connect-MgGraph -TenantId $tenantID -Scopes $scope
    Connect-SPOService -Url $SharepointURL

    # Initialize variables
    $userBatchList = @() # List to hold UPNs for batch processing
    $totalUsersProvisioned = 0 # Counter for total users processed

    # Retrieve all licensed users from Microsoft Graph
    Write-Host "Fetching licensed users..."
    $licensedUsers = Get-MgUser -Filter 'assignedLicenses/$count ne 0' -ConsistencyLevel eventual -CountVariable licensedUserCount -All -Select UserPrincipalName

    # Process each user and provision OneDrive in batches
    foreach ($user in $licensedUsers) {
    $totalUsersProvisioned++
    Write-Host "Processing user $totalUsersProvisioned of $($licensedUsers.Count): $($user.UserPrincipalName)"
    $userBatchList += $user.UserPrincipalName

    # Check if the batch limit is reached (199 users per batch)
    if ($userBatchList.Count -eq 199) {
    Write-Host "Batch limit reached. Requesting OneDrive provisioning for the current batch."
    Request-SPOPersonalSite -UserEmails $userBatchList -NoWait
    Start-Sleep -Milliseconds 655 # Add a short delay to avoid throttling
    $userBatchList = @() # Clear the batch list for the next set of users
    }
    }

    # Handle any remaining users in the final batch
    if ($userBatchList.Count -gt 0) {
    Write-Host "Requesting OneDrive provisioning for the remaining $($userBatchList.Count) users."
    Request-SPOPersonalSite -UserEmails $userBatchList -NoWait
    }

    # Disconnect from services
    Disconnect-SPOService
    Disconnect-MgGraph

    # Final output
    Write-Host "OneDrive provisioning completed successfully for $totalUsersProvisioned users." -Foreground Green