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."
问题排查与修复步骤
添加
-NoWelcome参数避免输出阻塞
自动化环境中,Microsoft Graph的欢迎信息可能触发输出缓冲问题,阻止后续代码执行。修改Connect-MgGraph命令:Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumbprint $thumbprint -NoWelcome修正设备筛选的语法错误
脚本中$AllDevices.value是错误写法,$AllDevices本身就是收集到的设备数组,不需要额外调用.value,修正为:$DevicesToDelete = $AllDevices | Where-Object { $_.approximateLastSignInDateTime -le $dt }使用Graph PowerShell Cmdlet替代手动API调用
直接使用Get-MgDevice内置Cmdlet,它会自动处理分页逻辑,避免手动处理@odata.nextLink的潜在问题:$AllDevices = Get-MgDevice -All -Property DisplayName, Id, ApproximateLastSignInDateTime添加错误捕获与日志输出
在Runbook中加入异常捕获,确保能定位执行中的错误点:try { Connect-MgGraph -ClientId $clientId -TenantId $tenantId -CertificateThumbprint $thumbprint -NoWelcome Write-Output "成功连接到Microsoft Graph" } catch { Write-Error "连接失败: $_" throw }验证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
相关产品推荐
相关产品推荐

