PowerShell脚本获取Outlook日历:修正Recurring Meeting调整后时长问题
解决Outlook重复会议实例实际时长获取问题
问题根源
Outlook对象模型中,重复会议的主条目仅保存原始计划时长,而被修改过的重复会议实例属于「例外项(Exception)」,需要单独提取这类例外项才能获取真实调整后的时长。
修改后的PowerShell脚本
# 初始化Outlook对象 $Outlook = New-Object -ComObject Outlook.Application $Namespace = $Outlook.GetNamespace("MAPI") $Calendar = $Namespace.GetDefaultFolder(9) # 9对应Outlook日历文件夹 # 设置目标日期范围 $startDate = Get-Date "2024-05-01" $endDate = Get-Date "2024-05-31" # 配置日历项获取规则 $allItems = $Calendar.Items $allItems.IncludeRecurrences = $true # 启用重复实例获取 $allItems.Sort("[Start]") # 按开始时间排序 # 初始化工时汇总哈希表 $timeSummary = @{} foreach ($item in $allItems) { # 筛选符合条件的会议项(Class=26为会议类,且在目标日期范围内) if ($item.Class -eq 26 -and $item.Start -ge $startDate -and $item.End -le $endDate) { if ($item.IsRecurring) { # 处理重复会议 $recurrencePattern = $item.GetRecurrencePattern() try { # 获取日期范围内的第一个重复实例 $occurrence = $recurrencePattern.GetOccurrence($startDate) while ($occurrence.Start -le $endDate) { $subject = $item.Subject # 默认使用原始计划时长(转换为小时) $duration = $recurrencePattern.Duration / 60 # 检查当前实例是否为修改过的例外项 $exception = $recurrencePattern.Exceptions | Where-Object { $_.OriginalDate.Date -eq $occurrence.Start.Date } if ($exception) { # 例外项使用实际调整后的时长 $duration = ($exception.End - $exception.Start).TotalHours } # 更新工时汇总 if ($timeSummary.ContainsKey($subject)) { $timeSummary[$subject] += $duration } else { $timeSummary[$subject] = $duration } # 获取下一个重复实例 $occurrence = $recurrencePattern.GetNextOccurrence($occurrence) } } catch { # 无后续实例时跳过循环 continue } } else { # 处理非重复会议 $subject = $item.Subject $duration = ($item.End - $item.Start).TotalHours if ($timeSummary.ContainsKey($subject)) { $timeSummary[$subject] += $duration } else { $timeSummary[$subject] = $duration } } } } # 输出工时汇总结果 Write-Host "工时汇总(日期范围: $($startDate.ToString('yyyy-MM-dd')) 至 $($endDate.ToString('yyyy-MM-dd')))" Write-Host "------------------------" foreach ($key in $timeSummary.Keys) { Write-Host "$key : $($timeSummary[$key].ToString('0.00')) 小时" } # 清理COM对象,避免内存泄漏 [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook) | Out-Null
关键修改点
- 启用
IncludeRecurrences = $true,确保脚本能获取重复会议的所有实例 - 通过
GetRecurrencePattern()获取重复规则,遍历Exceptions集合识别被修改的会议实例 - 例外项的真实时长通过
Exception.End - Exception.Start计算,替代主条目的原始Duration值 - 区分未修改的重复实例和例外实例,分别使用对应时长进行汇总
注意事项
- 运行脚本前需确保Outlook已启动,且当前用户有权限访问目标日历
- 若例外会议的标题被修改,可将
$subject = $item.Subject替换为$subject = $exception.Subject,使用修改后的标题汇总 - 可根据需求调整
$startDate和$endDate的格式及值
内容的提问来源于stack exchange,提问作者arker
相关产品推荐
相关产品推荐

