你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
获取资源更改
在日常使用、重新配置甚至是重新部署的过程中,资源都会发生更改。 大部分更改是依设计做出的,但有时并非如此。 可以:
- 查找在 Azure 资源管理器属性上检测到更改的时间。
- 查看属性更改详细信息。
- 大规模查询订阅、管理组或租户中的变更。
本文内容:
- 有效负载 JSON 的样子。
- 如何使用 CLI、PowerShell 或 Azure 门户通过 Resource Graph 查询资源更改。
- 查询资源更改的查询示例和最佳做法。
- 更改分析使用“更改行动者”功能:
changedBy
:发起了资源更改的人员,例如应用 ID 或授权人员的电子邮件地址。clientType
:进行了更改的客户端,例如 Azure 门户。operation
:调用的操作,例如Microsoft.Compute/virtualmachines/write
。
先决条件
了解更改事件属性
创建、更新或删除资源时,会创建一个新的变更资源 (Microsoft.Resources/changes
) 来扩展已修改的资源并表示已更改的属性。 更改记录应在五分钟内提供。 以下 JSON 有效负载示例演示了更改资源属性:
{
"targetResourceId": "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/myResourceGroup/providers/microsoft.compute/virtualmachines/myVM",
"targetResourceType": "microsoft.compute/virtualmachines",
"changeType": "Update",
"changeAttributes": {
"previousResourceSnapshotId": "11111111111111111111_22222222-3333-aaaa-bbbb-444444444444_5555555555_6666666666",
"newResourceSnapshotId": "33333333333333333333_44444444-5555-ffff-gggg-666666666666_7777777777_8888888888",
"correlationId": "11111111-1111-1111-1111-111111111111",
"changedByType": "User",
"changesCount": 2,
"clientType": "Azure Portal",
"changedBy": "john@contoso.com",
"operation": "microsoft.compute/virtualmachines/write",
"timestamp": "2024-06-12T13:26:17.347+00:00"
},
"changes": {
"properties.provisioningState": {
"newValue": "Succeeded",
"previousValue": "Updating",
"isTruncated": "true"
},
"tags.key1": {
"newValue": "NewTagValue",
"previousValue": "null",
}
}
}
运行查询
尝试对 resourcechanges
表进行基于租户的 Resource Graph 查询。 该查询返回前五个最近的 Azure 资源更改,以及每个更改记录的更改时间、更改类型、目标资源 ID、目标资源类型和更改详细信息。
# Login first with az login if not using Cloud Shell
# Run Azure Resource Graph query
az graph query -q 'resourcechanges | project properties.changeAttributes.timestamp, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5'
可以更新查询,为 timestamp 属性指定一个更加用户友好的列名:
# Run Azure Resource Graph query with 'extend'
az graph query -q 'resourcechanges | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5'
若要将查询结果限制为最近的更改,请将查询更新为 order by
用户定义的 changeTime
属性。
# Run Azure Resource Graph query with 'order by'
az graph query -q 'resourcechanges | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | order by changeTime desc | limit 5'
你还可以分别使用 -ManagementGroup
或 参数按管理组-Subscription
或订阅进行查询。
注意
如果查询未从你已有权访问的订阅返回结果,则 Search-AzGraph
PowerShell cmdlet 默认为默认上下文中的订阅。
Resource Graph Explorer 还提供一个整洁的界面用于将某些查询的结果转换为可固定到 Azure 仪表板的图表。
查询资源更改
使用 Resource Graph,可以查询 resourcechanges
、resourcecontainerchanges
或 healthresourcechanges
表,以按任何更改资源属性进行筛选或排序。 以下示例查询 resourcechanges
表,但也可以应用于 resourcecontainerchanges
或 healthresourcechanges
表。
示例
在查询和分析资源中的更改之前,请查看以下最佳做法。
- 查询特定时段内的更改事件,并评估更改详细信息。
- 此查询在事件管理期间用于了解可能相关的更改时效果最佳。
- 保持最新的配置管理数据库 (CMDB)。
- 不会按计划的频率刷新所有资源及其完整属性集,而只会收到其更改。
- 了解当某个资源更改“符合性状态”时可能更改的其他属性。
- 评估这些额外属性可以洞察可能需要通过 Azure Policy 定义进行管理的其他属性。
- 查询命令的顺序非常重要。 在以下示例中,
order by
必须位于limit
命令之前。order by
命令按更改时间对查询结果进行排序。- 然后,
limit
命令会限制有序结果,以确保获得五个最新的结果。
- “未知”的含义是什么?
- 当更改发生在未识别的客户端上时,将显示“未知”。 根据与原始更改请求关联的用户代理和客户端应用程序 ID 来识别客户端。
- “系统”的含义是什么?
- 当发生与任何直接用户操作无关的后台更改时,系统将显示为
changedBy
值。
- 当发生与任何直接用户操作无关的后台更改时,系统将显示为
过去 24 小时内的所有更改
resourcechanges
| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),
changeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId,
changedProperties = properties.changes, changeCount = properties.changeAttributes.changesCount
| where changeTime > ago(1d)
| order by changeTime desc
| project changeTime, targetResourceId, changeType, correlationId, changeCount, changedProperties
特定资源组中已删除的资源
resourcechanges
| where resourceGroup == "myResourceGroup"
| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),
changeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId
| where changeType == "Delete"
| order by changeTime desc
| project changeTime, resourceGroup, targetResourceId, changeType, correlationId
对特定属性值的变更
resourcechanges
| extend provisioningStateChange = properties.changes["properties.provisioningState"], changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType)
| where isnotempty(provisioningStateChange)and provisioningStateChange.newValue == "Succeeded"
| order by changeTime desc
| project changeTime, targetResourceId, changeType, provisioningStateChange.previousValue, provisioningStateChange.newValue
过去七天的更改,按更改人员和客户端分列,并按计数排序
resourcechanges
| extend changeTime = todatetime(properties.changeAttributes.timestamp),
targetResourceId = tostring(properties.targetResourceId),
changeType = tostring(properties.changeType), changedBy = tostring(properties.changeAttributes.changedBy),
changedByType = properties.changeAttributes.changedByType,
clientType = tostring(properties.changeAttributes.clientType)
| where changeTime > ago(7d)
| project changeType, changedBy, changedByType, clientType
| summarize count() by changedBy, changeType, clientType
| order by count_ desc
虚拟机大小的更改
resourcechanges
| extend vmSize = properties.changes["properties.hardwareProfile.vmSize"], changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType)
| where isnotempty(vmSize)
| order by changeTime desc
| project changeTime, targetResourceId, changeType, properties.changes, previousSize = vmSize.previousValue, newSize = vmSize.newValue
按更改类型和订阅名称进行的更改计数
resourcechanges
| extend changeType = tostring(properties.changeType), changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceType=tostring(properties.targetResourceType)
| summarize count() by changeType, subscriptionId
| join (resourcecontainers | where type=='microsoft.resources/subscriptions' | project SubscriptionName=name, subscriptionId) on subscriptionId
| project-away subscriptionId, subscriptionId1
| order by count_ desc
使用某种标记创建的资源的最新资源更改
resourcechanges
|extend targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType), createTime = todatetime(properties.changeAttributes.timestamp)
| where createTime > ago(7d) and changeType == "Create" or changeType == "Update" or changeType == "Delete"
| project targetResourceId, changeType, createTime
| join ( resources | extend targetResourceId=id) on targetResourceId
| where tags ['Environment'] =~ 'prod'
| order by createTime desc
| project createTime, id, resourceGroup, type