你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

获取资源更改

在日常使用、重新配置甚至是重新部署的过程中,资源都会发生更改。 大部分更改是依设计做出的,但有时并非如此。 可以:

  • 查找在 Azure 资源管理器属性上检测到更改的时间。
  • 查看属性更改详细信息。
  • 大规模查询订阅、管理组或租户中的变更。

本文内容:

  • 有效负载 JSON 的样子。
  • 如何使用 CLI、PowerShell 或 Azure 门户通过 Resource Graph 查询资源更改。
  • 查询资源更改的查询示例和最佳做法。

先决条件

  • 要使 Azure PowerShell 能够查询 Azure Resource Graph,则添加模块
  • 若要使 Azure CLI 能够查询 Azure Resource Graph,则添加扩展

了解更改事件属性

创建、更新或删除资源时,将创建一个新的变更资源 (Microsoft.Resources/changes) 来扩展修改的资源并表示已更改的属性。 更改记录应在五分钟内提供。 以下 JSON 有效负载示例演示了更改资源属性:

{
  "targetResourceId": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/microsoft.compute/virtualmachines/myVM",
  "targetResourceType": "microsoft.compute/virtualmachines",
  "changeType": "Update",
  "changeAttributes": {
    "previousResourceSnapshotId": "08584889383111245807_37592049-3996-ece7-c583-3008aef9e0e1_4043682982_1712668574",
    "newResourceSnapshotId": "08584889377081305807_38788020-eeee-ffff-028f-6121bdac9cfe_4213468768_1712669177",
    "correlationId": "04ff69b3-e162-4583-9cd7-1a14a1ec2c61",
    "changedByType": "User",
    "changesCount": 2,
    "clientType": "ARM Template",
    "changedBy": "john@contoso.com",
    "operation": "microsoft.compute/virtualmachines/write",
    "timestamp": "2024-04-09T13:26:17.347+00:00"
  },
  "changes": {
    "properties.provisioningState": {
      "newValue": "Succeeded",
      "previousValue": "Updating",
      "changeCategory": "System",
      "propertyChangeType": "Update",
      "isTruncated": "true"
    },
    "tags.key1": {
      "newValue": "NewTagValue",
      "previousValue": "null",
      "changeCategory": "User",
      "propertyChangeType": "Insert"
    }
  }
}

请参阅更改资源属性的完整参考指南。

运行查询

尝试对 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,可以查询 resourcechangesresourcecontainerchangeshealthresourcechanges 表,以按任何更改资源属性进行筛选或排序。 以下示例查询 resourcechanges 表,但也可以应用于 resourcecontainerchangeshealthresourcechanges 表。

注意

详细了解 Project Flash 文档中 healthresourcechanges 数据。

示例

在查询和分析资源中的更改之前,请查看以下最佳做法。

  • 查询特定时段内的更改事件,并评估更改详细信息。
    • 此查询在事件管理期间用于了解可能相关的更改时效果最佳。
  • 保持最新的配置管理数据库 (CMDB)。
    • 不会按计划的频率刷新所有资源及其完整属性集,而只会收到其更改。
  • 了解当某个资源更改了“符合性状态”时可能已更改的其他属性。
    • 评估这些额外属性可以洞察可能需要通过 Azure Policy 定义进行管理的其他属性。
  • 查询命令的顺序非常重要。 在以下示例中,order by 必须位于 limit 命令之前。
    • order by 命令按更改时间对查询结果进行排序。
    • 然后,limit 命令会限制有序结果,以确保获得五个最新的结果。

过去 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 targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType), changeTime = todatetime(properties.changeAttributes.timestamp)
| where changeTime > ago(7d) and changeType == "Create"
| project  targetResourceId, changeType, changeTime
| join ( Resources | extend targetResourceId=id) on targetResourceId
| order by changeTime desc
| project changeTime, changeType, id, resourceGroup, type, properties

虚拟机大小的更改

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

后续步骤