使用Get-MgUserCalendarView遇权限拒绝错误,求解决
权限问题排查:Get-MgUserCalendarView 访问被拒绝
问题描述
需创建每日更新脚本,收集所有启用账号的员工日历条目并发送给管理层,执行PowerShell脚本时持续报错:
Get-MgUserCalendarView : Access is denied. Check credentials and try again.
脚本代码如下:
Connect-MgGraph -Scopes "Calendars.Read", "Calendars.ReadWrite.Shared" $timeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById("New Zealand Standard Time") $startDate = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId((Get-Date), $timeZone.Id).Date $endDate = $startDate.AddDays(1) $users = Get-MgUser -Filter "accountEnabled eq true" -All $emailBody = "" foreach ($user in $users) { $userId = $user.Id $calendarEntries = Get-MgUserCalendarView -UserId $userId -StartDateTime $startDate -EndDateTime $endDate if ($calendarEntries) { $emailBody += "Calendar Entries for $($user.UserPrincipalName):`n" foreach ($entry in $calendarEntries) { $emailBody += "`t- Subject: $($entry.Subject)`n" } $emailBody += "`n" } } if ($emailBody) { Write-Output "Email body constructed successfully" Write-Output $emailBody $Outlook = New-Object -ComObject Outlook.Application $Mail = $Outlook.CreateItem(0) $Mail.Subject = "Today's Calendar Entries" $Mail.Body = $emailBody $Mail.Display() } else { Write-Output "No calendar entries found for any user" } Disconnect-MgGraph
解决方案
1. 切换到Application类型权限
当前使用的Delegated(委托)权限仅允许访问当前登录用户有权查看的日历,无法遍历所有用户日历。要实现批量访问,需使用Application类型的Calendars.Read权限:
- 在Azure AD门户注册应用程序(或使用现有应用)
- 进入应用「API权限」页面,添加Microsoft Graph的
Calendars.Read权限,选择「Application」类型 - 点击「授予管理员同意」,确保权限生效
2. 使用应用身份验证登录Graph
不能再用交互式Connect-MgGraph登录,需改用应用凭据验证:
# 替换为你的应用信息 $clientId = "你的应用客户端ID" $tenantId = "你的租户ID" $clientSecret = ConvertTo-SecureString "你的应用客户端密钥" -AsPlainText -Force Connect-MgGraph -ClientId $clientId -TenantId $tenantId -ClientSecret $clientSecret
3. 修正时间格式参数
Graph API要求StartDateTime和EndDateTime为ISO 8601格式(如2024-05-20T00:00:00Z),修改时间处理代码:
$startDate = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId((Get-Date), $timeZone.Id).Date.ToString("yyyy-MM-ddTHH:mm:ssZ") $endDate = ([DateTime]$startDate).AddDays(1).ToString("yyyy-MM-ddTHH:mm:ssZ")
4. 替换Outlook COM对象的邮件发送方式
Outlook COM对象依赖本地客户端,自动化环境易出问题,建议改用Microsoft Graph接口发送:
# 替换为管理层邮箱 $recipientEmail = "management@company.com" $mailParams = @{ Message = @{ Subject = "Today's Calendar Entries" Body = @{ ContentType = "Text" Content = $emailBody } ToRecipients = @( @{ EmailAddress = @{ Address = $recipientEmail } } ) } SaveToSentItems = $false } Send-MgUserMail -UserId "你的服务账号邮箱或me" @mailParams
内容的提问来源于stack exchange,提问作者ITW Git
相关产品推荐
相关产品推荐

