如何使用 Microsoft Graph 获取 Microsoft 365 Planner 'All Plans for all users'

How to get Microsoft 365 Planner 'All Plans for all users' using Microsoft Graph

我们需要列出组织中所有用户的所有计划及其各自的存储桶

我尝试使用 OAuth 授权服务(AAD > 应用程序注册)访问规划器 APIs/resources 使用 Graph API 端点但是我的访问被拒绝 - 重要的是要在这里提到该应用程序已获得所有权限。

Microsoft 是否允许读取所有 Planners 数据?如果该帐户具有所有必需的权限 - 如果是,那么我在这里缺少什么?

public static string GetAccessToken_Delegate()
    {
        try
        {
            AuthenticationContext authContext = new AuthenticationContext(Globals.AuthorityUrl, true);
            AuthenticationResult authResult = authContext.AcquireTokenAsync(Globals.GraphResourceUrl, Globals.AppId, new Uri(Globals.RedirectUri), new PlatformParameters(PromptBehavior.Auto)).Result;
            return authResult.AccessToken;
        }
        catch (Exception ex)
        {
            WriteLogEvents.WriteException(ex);
        }
        return null;
    }

    public static GraphServiceClient GetGraphClient(string graphToken)
    {
        try
        {
            DelegateAuthenticationProvider authenticationProvider = new DelegateAuthenticationProvider(
            (requestMessage) =>
            {
                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", graphToken);
                return Task.FromResult(0);
            });
            return new GraphServiceClient(authenticationProvider);
        }
        catch (Exception ex)
        {
            WriteLogEvents.WriteException(ex);
        }
        return null;
    }

    public async static Task<List<PlansData>> GetPlans()
    {
        List<PlansData> plansData = new List<PlansData>();
        try
        {
            String accessToken = GetAccessToken_Delegate();
            GraphServiceClient graphClient = GetGraphClient(accessToken);
            if (graphClient != null)
            {
                message += string.Format("GraphClient Base Url: {0}", graphClient.BaseUrl) + Environment.NewLine;

                plansData = await GetGroup(graphClient, plansData);
            }
            else
                throw new Exception("GraphServiceClient is null");
        }
        catch (Exception ex)
        {
            WriteLogEvents.WriteException(ex);
        }
        finally
        {
        }
        return plansData;
    }

    public async static Task<List<PlansData>> GetGroup(GraphServiceClient graphClient, List<PlansData> plansData)
    {
        try
        {
            IGraphServiceGroupsCollectionPage groupCollection = await graphClient.Groups.Request().GetAsync();

            if (groupCollection?.Count > 0)
            {
                message += string.Format("Group Count: {0}", groupCollection.Count) + Environment.NewLine;

                foreach (Microsoft.Graph.Group group in groupCollection)
                {
                    if (group is Microsoft.Graph.Group)
                    {
                        if (group != null && group.GroupTypes != null && group.GroupTypes.Count() > 0)
                        {
                            plansData = await GetPlanData(graphClient, plansData, group);
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            WriteLogEvents.WriteException(ex);
        }
        return plansData;
    }

    public async static Task<List<PlansData>> GetPlanData(GraphServiceClient graphClient, List<PlansData> plansData, Microsoft.Graph.Group group)
    {
        try
        {
            //https://graph.microsoft.com/v1.0/groups/a047a2b3-3687-4464-bbdb-084f675c7528/planner/plans

            //Get Plans Information based on the group id
            IPlannerGroupPlansCollectionPage plansCollection = await graphClient.Groups[group.Id].Planner.Plans.Request().GetAsync();
            if (plansCollection?.Count > 0)
            {
                message += string.Format("Plans Count: {0}", plansCollection.Count) + Environment.NewLine;

                foreach (PlannerPlan record in plansCollection)
                {
                    List<Bucket> bucketsList = await GetBuckets(graphClient, record.Id);
                    Groups groupData = new Groups(group.Id, group.DisplayName);
                    string siteUrl = string.Format("https://myOrg.sharepoint.com/teams/{0}/", group.MailNickname);
                    plansData.Add(new PlansData(record.Id, record.Title, siteUrl, groupData, bucketsList));
                }
            }
        }
        catch (Exception ex)
        {
            WriteLogEvents.WriteException(ex);
        }
        return plansData;
    }

    public async static Task<List<Bucket>> GetBuckets(GraphServiceClient graphClient, string planId)
    {
        List<Bucket> bucketsList = new List<Bucket>();

        try
        {
            //https://graph.microsoft.com/v1.0/planner/plans/CONGZUWfGUu4msTgNP66e2UAAySi/buckets

            //Get Plans Information based on the group id
            IPlannerPlanBucketsCollectionPage bucketCollection = await graphClient.Planner.Plans[planId].Buckets.Request().GetAsync();
            if (bucketCollection?.Count > 0)
            {
                message += string.Format("Buckets Count: {0}", bucketCollection.Count) + Environment.NewLine;

                foreach (PlannerBucket bucket in bucketCollection)
                {
                    Bucket b = new Bucket(bucket.Id, bucket.Name);
                    bucketsList.Add(b);
                }
            }
        }
        catch (Exception ex)
        {
            WriteLogEvents.WriteException(ex);
        }
        return bucketsList;
    }

提前致谢。

Planner 尚不支持应用程序权限。使用非图形 API 可以导出所有计划数据,并且需要租户管理员的委托访问令牌。我们正在为此编写文档,并使其也可以从图表中获取。