用于删除过时设备的自动化帐户脚本

问题描述 投票:0回答:1

我正在尝试在我的自动化帐户中创建一个操作手册,该操作手册会从 Entra 中删除所有陈旧设备(非活动时间 >= 180 天)。

我已经创建了具有正确 API 权限的应用程序注册,并将证书上传到我的自动化帐户,我还安装了所需的模块。

API权限:

enter image description here

尽管我添加了很多调试步骤,但我仍然遇到一些问题,当前版本的脚本仅显示欢迎使用图形消息,然后显然退出脚本:

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."

脚本的最后一部分被注释掉,因为我不想在测试过程中删除任何内容。也许我处理这件事的方式也是完全错误的。我很高兴得到所有的帮助!

谢谢!

azure powershell azure-automation microsoft-entra-id
1个回答
0
投票

您的代码存在一些问题,您可以进行改进。

  1. 首先,主机输出(由

    Write-Host
    生成)在自动化帐户作业输出中不可见。 AA 知道的唯一输出是成功、错误和警告。

  2. 第二期在这里:

    $DevicesToDelete = $AllDevices.value | Where-Object {
    

    .value
    的对象中没有
    $AllDevices
    ,那些已经是
    device
    类型
    对象。

  3. 一个改进,你不需要在客户端进行过滤

    approximateLastSignInDateTime
    ,Graph API 知道如何通过此属性进行过滤:

    approximateLastSignInDateTime details

    本质上你可以做:

    # `o` format is `yyyy-MM-ddTHH:mm:ss.fffffffZ`, Graph accepts it no problem :)
    $dt = [datetime]::UtcNow.AddDays(-180).ToString('o')
    $uri = "v1.0/devices?`$filter=approximateLastSignInDateTime le $dt"
    
  4. $AllDevices = @()
    $AllDevices += $response.value
    效率低下,应该避免。您可以简单地将循环表达式的结果分配给一个变量,即:
    $AllDevices = do { ..... $response.value }
    。有关详细信息,请参阅 为什么我应该避免使用增加赋值运算符 (+=) 来创建集合

总之,您的代码可以是:

# Authenticate to Microsoft Graph using the certificate
$connectMgGraphSplat = @{
    ClientId              = 'clientID'
    TenantId              = 'tenantID'
    CertificateThumbprint = 'certificateThumbprint'
    NoWelcome             = $true
    Scopes                = 'Device.ReadWrite.All' # this should be enough to run your code
}
Connect-MgGraph @connectMgGraphSplat

# Number of days a device must be inactive before deletion (180 days in this case)
$dt = [datetime]::UtcNow.AddDays(-180).ToString('o')

# Fetch devices from Microsoft Graph with pagination where
# `approximateLastSignInDateTime` is lower than or equal to `$dt`
$uri = "v1.0/devices?`$filter=approximateLastSignInDateTime le $dt"
$DevicesToDelete = do {
    $response = Invoke-MgGraphRequest GET $uri
    if ($response.value) {
        $response.value
    }
    $uri = $response.'@odata.nextLink'
} while ($uri)

# Debugging: Output the total number of devices TO DELETE fetched
# NOTE: `Write-Host` was removing here, same as below with `"Deleted device:...`
"Total devices to delete fetched: $($DevicesToDelete.Count)"

foreach ($Device in $DevicesToDelete) {
    Invoke-MgGraphRequest -Method DELETE -Uri "v1.0/devices/$($Device.id)"
    "Deleted device: $($Device.displayName)"
}
© www.soinside.com 2019 - 2024. All rights reserved.