PrivateFunctions/Get-OneDriveDirectoryId.ps1

<#
.SYNOPSIS
    This function retrieves the ID for a directory on OneDrive.
#>

function Get-OneDriveDirectoryId {
    [CmdletBinding(PositionalBinding=$false)]
    [OutputType([String])]
    param (
        # The path of the directory on OneDrive.
        # Null input is allowed to indicate root directory
        [Parameter(Mandatory=$false)]
        [String]$directoryPath,

        # The User Principal Name of the OneDrive account's user.
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$userPrincipalName,

        # The Microsoft Graph authentication token.
        [Parameter(Mandatory=$true, ParameterSetName="token")]
        [ValidateNotNullOrEmpty()]
        [String]$token,

        # Select the stream where the messages will be directed.
        [Parameter(Mandatory=$false)]
        [ValidateSet("Information", "Warning", "Error")]
        [String]$outputStream = "Error"
    )

    # Set the protocol to TLS 1.2
    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12

    # Retrieve the ID of the root level of the OneDrive account
    try {
        $invokeRestMethodParams = @{
            Uri = "https://graph.microsoft.com/v1.0/users/$($userPrincipalName)/drive/root"
            Method = "GET"
            Headers = @{
                Accept = "application/json"
                Authorization = "bearer $($token)"
            }
        }
        $response = Invoke-RestMethod @invokeRestMethodParams
        if (!$response) {
            Write-OutputMessage "Failed to retrieve the ID of the root level of the OneDrive account" -OutputStream $outputStream
            return $false
        }
    }
    catch {
        Write-OutputMessage "Exception occurred while retrieving the ID of the root level of the OneDrive account.`r`n$($_.Exception.Message)" -OutputStream $outputStream
        return $false
    }

    # Recursively retrieve the children until we reach the destination directory
    $currentDirectoryId = $response.id
    $remainingPathToRecurse = $directoryPath
    try {
        $recursionLevel = 0
        while (![String]::IsNullOrWhiteSpace($remainingPathToRecurse)) {
            $recursionLevel += 1

            # Retrieve the children at the current directory
            $invokeRestMethodParams = @{
                Uri     = "https://graph.microsoft.com/v1.0/users/$($userPrincipalName)/drive/items/$($currentDirectoryId)/children"
                Method  = "GET"
                Headers = @{
                    Accept          = "application/json"
                    Authorization   = "bearer $($token)"
                }
            }
            $response = Invoke-RestMethod @invokeRestMethodParams
            if (!$response) {
                Write-OutputMessage "Failed to retrieve the children of the driveItem in the OneDrive account while retrieving the directory ID for '$($cachedDirectoryPath)' (recursion level $($recursionLevel))." -OutputStream $outputStream
                return $false
            }

            # Update the current directory ID for the next iteration
            $splitRemainingPathToRecurse = $remainingPathToRecurse.Split("\")
            $nextDirectory = $splitRemainingPathToRecurse[0]
            $currentDirectoryId = ($response.value | Where-Object { $_.name -eq $nextDirectory }).id
            if ([String]::IsNullOrWhiteSpace($currentDirectoryId)) {
                Write-OutputMessage "Directory '$($nextDirectory)' cannot be found in the OneDrive account." -OutputStream $outputStream
                return $false
            }

            # Remove one layer from the parent path
            if ($remainingPathToRecurse.IndexOf("\") -ne -1) {
                $splitRemainingPathToRecurse = $remainingPathToRecurse.Split("\")
                $remainingPathToRecurse = $splitRemainingPathToRecurse[1..($splitRemainingPathToRecurse.Length - 1)] -join "\"
            }
            else {
                $remainingPathToRecurse = ""
            }
        }
    }
    catch {
        Write-OutputMessage "Exception occurred while retrieving the directory ID for '$($directoryPath)'.`r`n$($_.Exception.Message)" -OutputStream $outputStream
        return $false
    }

    # Return the retrieved directory ID
    return $currentDirectoryId
}