求助:通过Function App将O365审计日志转发至Event Hub
问题背景
当前使用Azure Sentinel官方O365数据连接器收集Audit.General和DLP.ALL日志,默认流向Log Analytics/Sentinel;需要将日志重定向至Event Hub,但修改ARM模板未理清逻辑,从零创建时间触发PowerShell Function App后,Event Hub仅显示传入请求但无实际消息,Data Explorer无法生成Schema预览。最终目标是让O365日志成功写入Event Hub,并可通过Data Explorer验证数据抵达。
方案一:修改现有O365数据连接器ARM模板(推荐)
原模板默认配置Log Analytics输出,只需调整输出目标为Event Hub,步骤如下:
替换输出绑定配置
找到模板中Function App的function.json,将原Log Analytics输出段替换为Event Hub输出:{ "bindings": [ { "name": "eventHubMessage", "type": "eventHub", "direction": "out", "eventHubName": "<你的Event Hub名称>", "connection": "<Event Hub连接字符串的应用设置名>" } ] }调整Function推送逻辑
将原推送到Log Analytics的代码改为推送至Event Hub,核心代码:# $logs为从O365 API拉取的日志数组 foreach ($log in $logs) { $jsonLog = $log | ConvertTo-Json -Depth 10 Push-OutputBinding -Name eventHubMessage -Value $jsonLog }添加Event Hub连接配置
在ARM模板的siteConfig.appSettings中加入Event Hub连接字符串:{ "name": "<Event Hub连接字符串的应用设置名>", "value": "[concat('Endpoint=sb://', parameters('eventHubNamespaceName'), '.servicebus.windows.net/;SharedAccessKeyName=', parameters('eventHubSharedAccessKeyName'), ';SharedAccessKey=', parameters('eventHubSharedAccessKey'))]" }
方案二:从零构建PowerShell Function App
若从零创建,需重点解决权限、绑定配置和日志拉取逻辑问题:
Function App基础配置
- 选择PowerShell 7.x运行时
- 启用系统托管标识,给该标识分配两个关键权限:
- Azure AD中添加Office 365 Management API的
ActivityFeed.Read权限 - Event Hub命名空间IAM中添加Event Hub Data Sender角色
- Azure AD中添加Office 365 Management API的
触发器与输出绑定配置
时间触发器(每5分钟触发)的function.json示例:{ "bindings": [ { "name": "Timer", "type": "timerTrigger", "direction": "in", "schedule": "*/5 * * * *" }, { "name": "eventHubOutput", "type": "eventHub", "direction": "out", "eventHubName": "o365-logs-hub", "connection": "EventHubConnectionString" } ] }完整PowerShell业务代码
实现O365日志拉取与Event Hub推送:# 获取托管标识访问令牌 $tenantId = $env:TenantId $tokenUri = "https://login.microsoftonline.com/$tenantId/oauth2/token" $tokenParams = @{ resource = "https://manage.office.com" client_id = $env:IDENTITY_CLIENT_ID grant_type = "client_credentials" } $tokenResponse = Invoke-RestMethod -Uri $tokenUri -Method Post -Body $tokenParams $accessToken = $tokenResponse.access_token # 定义拉取的日志类型与时间范围 $contentTypes = @("Audit.General", "DLP.ALL") $startTime = (Get-Date).AddMinutes(-5).ToUniversalTime().ToString("o") foreach ($type in $contentTypes) { # 拉取O365日志 $logUri = "https://manage.office.com/api/v1.0/$tenantId/activity/feed/subscriptions/content?contentType=$type&startTime=$startTime" $logs = Invoke-RestMethod -Uri $logUri -Headers @{Authorization = "Bearer $accessToken"} -Method Get # 推送至Event Hub if ($logs.Count -gt 0) { foreach ($log in $logs) { Push-OutputBinding -Name eventHubOutput -Value ($log | ConvertTo-Json -Depth 10) } } }应用设置配置
在Function App的“配置”中添加:TenantId:你的Azure AD租户IDEventHubConnectionString:Event Hub命名空间的连接字符串
验证步骤
Event Hub消息检查
进入Event Hub实例,在“消息”选项卡选择“浏览消息”,查看是否有新日志消息;若为空,查看Function App的“监控”日志排查错误(如权限不足、API调用失败)。Data Explorer验证
- 创建Event Hub数据源,选择目标Event Hub
- 等待数分钟后刷新Schema标签页,确认日志JSON结构加载成功
- 运行测试查询:
O365Logs | take 10验证数据存在
内容的提问来源于stack exchange,提问作者hailey m

