You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Automation Account脚本删除Entra陈旧设备遇执行异常求助

解决Azure自动化Runbook执行Microsoft Graph脚本仅显示欢迎信息后停止的问题

问题背景

我正在Azure自动化账户中创建Runbook,目标是删除Entra ID中超过180天未活跃的陈旧设备。已完成以下准备工作:

  • 创建了拥有正确Microsoft Graph API权限的应用注册
  • 将证书上传至自动化账户
  • 安装了所需的PowerShell模块

但脚本执行时仅输出Microsoft Graph欢迎信息后就停止,没有执行后续的设备获取、筛选等逻辑。欢迎信息如下:

Welcome to Microsoft Graph!

Connected via apponly access using 12345567-1213-2333-xxxxxxxx

Readme: https://aka.ms/graph/sdk/powershell

SDK Docs: https://aka.ms/graph/sdk/powershell/docs

API Docs: https://aka.ms/graph/docs

NOTE: You can use the -NoWelcome parameter to suppress this message.

使用的脚本如下:

# Set the tenant ID and App Registration details
$tenantId = "tenantID"
$clientId = "clientID"
$thumbprint = "certificateThumbprint"

# Authenticate to Microsoft Graph using the certificate
Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumbprint $thumbprint

# Number of days a device must be inactive before deletion (180 days in this case)
$dt = (Get-Date).AddDays(-180)

# Initialize an array to hold all devices
$AllDevices = @()

# Fetch devices from Microsoft Graph with pagination
$uri = "https://graph.microsoft.com/v1.0/devices"
do {
    Write-Host "Fetching devices from: $uri"
    $response = Invoke-MgGraphRequest -Method GET -Uri $uri
    if ($response -and $response.value) {
        $AllDevices += $response.value
        Write-Host "Fetched $($response.value.Count) devices"
    } else {
        Write-Host "No devices fetched or response is null"
    }
    $uri = $response.'@odata.nextLink'
} while ($uri -ne $null)

# Debugging: Output the total number of devices fetched
Write-Host "Total devices fetched: $($AllDevices.Count)"

# Filter devices that have not signed in for 180 days or more and are disabled
$DevicesToDelete = $AllDevices.value | Where-Object {
    ($_.approximateLastSignInDateTime -le $dt)
}

# Debugging: Output the number of devices identified for deletion
Write-Host "Devices identified for deletion: $($DevicesToDelete.Count)"

# Output devices for review (testing mode)
if ($DevicesToDelete.Count -gt 0) {
    Write-Host "Devices identified for deletion (not deleted in this run):"
    $DevicesToDelete | Select-Object displayName, id, approximateLastSignInDateTime
} else {
    Write-Host "No devices found that meet the criteria for deletion."
}

# Delete the devices that were inactive for 180 days or more
# foreach ($Device in $DevicesToDelete) {
#     Invoke-MgGraphRequest -Method DELETE -Uri "https://graph.microsoft.com/v1.0/devices/$($Device.id)"
#     Write-Host "Deleted device: $($Device.displayName)"
# }

#Write-Output "Device cleanup process completed."

问题排查与修复步骤

  1. 添加-NoWelcome参数避免输出阻塞
    自动化环境中,Microsoft Graph的欢迎信息可能触发输出缓冲问题,阻止后续代码执行。修改Connect-MgGraph命令:

    Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumbprint $thumbprint -NoWelcome
    
  2. 修正设备筛选的语法错误
    脚本中$AllDevices.value是错误写法,$AllDevices本身就是收集到的设备数组,不需要额外调用.value,修正为:

    $DevicesToDelete = $AllDevices | Where-Object {
        $_.approximateLastSignInDateTime -le $dt
    }
    
  3. 使用Graph PowerShell Cmdlet替代手动API调用
    直接使用Get-MgDevice内置Cmdlet,它会自动处理分页逻辑,避免手动处理@odata.nextLink的潜在问题:

    $AllDevices = Get-MgDevice -All -Property DisplayName, Id, ApproximateLastSignInDateTime
    
  4. 添加错误捕获与日志输出
    在Runbook中加入异常捕获,确保能定位执行中的错误点:

    try {
        Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumbprint $thumbprint -NoWelcome
        Write-Output "成功连接到Microsoft Graph"
    }
    catch {
        Write-Error "连接失败: $_"
        throw
    }
    
  5. 验证API权限范围
    确认应用注册已获得Device.Read.All和Device.ReadWrite.All权限并完成管理员同意,缺少权限会导致设备获取请求静默失败。

修正后的完整脚本

# Set the tenant ID and App Registration details
$tenantId = "tenantID"
$clientId = "clientID"
$thumbprint = "certificateThumbprint"

# Authenticate to Microsoft Graph with no welcome message
try {
    Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumbprint $thumbprint -NoWelcome
    Write-Output "已成功连接到Microsoft Graph"
}
catch {
    Write-Error "Graph连接失败: $_"
    throw
}

# Number of days a device must be inactive before deletion (180 days in this case)
$dt = (Get-Date).AddDays(-180)

# Fetch all devices with required properties
try {
    $AllDevices = Get-MgDevice -All -Property DisplayName, Id, ApproximateLastSignInDateTime
    Write-Output "共获取到 $($AllDevices.Count) 台设备"
}
catch {
    Write-Error "获取设备列表失败: $_"
    throw
}

# Filter inactive devices
$DevicesToDelete = $AllDevices | Where-Object {
    $_.ApproximateLastSignInDateTime -le $dt
}

Write-Output "符合删除条件的设备数量: $($DevicesToDelete.Count)"

# Output devices for review (testing mode)
if ($DevicesToDelete.Count -gt 0) {
    Write-Output "以下设备符合删除条件(本次运行未执行删除):"
    $DevicesToDelete | Select-Object DisplayName, Id, ApproximateLastSignInDateTime
} else {
    Write-Output "未找到符合删除条件的设备"
}

# Delete the devices (uncomment after testing)
# foreach ($Device in $DevicesToDelete) {
#     try {
#         Remove-MgDevice -DeviceId $Device.Id
#         Write-Output "已删除设备: $($Device.DisplayName)"
#     }
#     catch {
#         Write-Error "删除设备 $($Device.DisplayName) 失败: $_"
#     }
# }

Write-Output "设备清理流程执行完成"

内容的提问来源于stack exchange,提问作者Unbuckle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:51:02