清理 Azure Entra 中的非活动服务原则

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

我正在尝试(如标题所示)根据合规性、azure Defender 和 Advisor 建议清理 Azure entra 中未使用的服务原则。

这是我为企业申请 ISO 合规认证的前兆。

从 Chat GPT 获得一些建议后,它给了我这个损坏的脚本......

Install-Module -Name AzureAD
Connect-AzureAD

# Export users with last sign-in date
Get-AzureADUser -All $true | ForEach-Object {
    $user = $_
    $lastSignIn = (Get-AzureADAuditSignInLogs -Filter "userPrincipalName eq '$($user.UserPrincipalName)'" | Sort-Object createdDateTime -Descending | Select-Object -First 1).createdDateTime
    [PSCustomObject]@{
        UserPrincipalName = $user.UserPrincipalName
        LastSignInDateTime = $lastSignIn
    }
} | Export-Csv -Path "C:\temp\InactiveUsers.csv" -NoTypeInformation

# Import the CSV file with inactive users
$inactiveUsers = Import-Csv -Path "C:\temp\InactiveUsers.csv"

# Disable users
foreach ($user in $inactiveUsers) {
    if ($user.LastSignInDateTime -lt (Get-Date).AddMonths(-6)) {
        Set-AzureADUser -ObjectId $user.UserPrincipalName -AccountEnabled $false
    }
} 

...我这里有几个问题/问题...

  • 这是个好主意吗?
  • 该脚本不起作用,所以我需要帮助修复它
  • 我很惊讶没有办法处理 UI 中看似例行的任务,我是否遗漏了什么?

我在想,如果我跳过将初始集删除到文件中,我可以在自动化帐户上将其作为计划任务重新运行,这是一个好主意还是坏主意?

azure standards-compliance microsoft-entra-id
1个回答
0
投票

在我的租户中,我几乎没有企业应用程序:

enter image description here

要获取 3 天内不活动的服务主体,我使用了以下脚本:

# Retrieve all service principals
$servicePrincipals = Get-AzureADServicePrincipal -All:$true | ? {$_.Tags -eq "WindowsAzureActiveDirectoryIntegratedApp"} 

# Define threshold for inactivity (e.g., 6 months)
$inactiveThreshold = (Get-Date).AddDays(-3)

# Array to store inactive service principals
$inactiveServicePrincipals = @()

# Check each service principal for activity
foreach ($sp in $servicePrincipals) {
    # Determine if the service principal has any recent activity
    $recentActivity = Get-AzureADAuditSignInLogs -Filter "appId eq '$($sp.AppId)'" | Sort-Object createdDateTime -Descending | Select-Object -First 1

    if ($recentActivity -eq $null) {
        # No recent activity found for the service principal
        $inactiveServicePrincipals += $sp
    }
}

# Output inactive service principals
$inactiveServicePrincipals | Select-Object DisplayName, AppId

enter image description here

名称为

Multi-tenant
的应用程序不会在响应中显示是否存在用户交互:

enter image description here

现在您也可以通过修改如下脚本来删除不活动的服务主体

# Retrieve all service principals tagged as WindowsAzureActiveDirectoryIntegratedApp
$servicePrincipals = Get-AzureADServicePrincipal -All:$true | Where-Object { $_.Tags -eq "WindowsAzureActiveDirectoryIntegratedApp" }

# Define threshold for inactivity (e.g., 6 months)
$inactiveThreshold = (Get-Date).AddDays(-3)  # Adjust as needed

# Array to store inactive service principals
$inactiveServicePrincipals = @()

# Check each service principal for activity
foreach ($sp in $servicePrincipals) {
    # Determine if the service principal has any recent activity
    $recentActivity = Get-AzureADAuditSignInLogs -Filter "appId eq '$($sp.AppId)'" | Sort-Object createdDateTime -Descending | Select-Object -First 1

    if ($recentActivity -eq $null) {
        # No recent activity found for the service principal
        $inactiveServicePrincipals += $sp
    }
}

# Output inactive service principals
$inactiveServicePrincipals | Select-Object DisplayName, AppId

# Delete inactive service principals
foreach ($inactiveSP in $inactiveServicePrincipals) {
    Write-Host "Deleting $($inactiveSP.DisplayName) with AppId $($inactiveSP.AppId)..."
    Remove-AzureADServicePrincipal -ObjectId $inactiveSP.ObjectId -Force
}

Write-Host "Deletion complete."

enter image description here

不活动的服务主体已成功删除

enter image description here

如果租户有许多服务主体,那么脚本可能会抛出限制错误,因此请尝试以下代码:

# Retrieve all service principals tagged as WindowsAzureActiveDirectoryIntegratedApp
$servicePrincipals = Get-AzureADServicePrincipal -All:$true | Where-Object { $_.Tags -eq "WindowsAzureActiveDirectoryIntegratedApp" }

# Define threshold for inactivity 
$inactiveThreshold = (Get-Date).AddDays(-7)  # Adjust as needed

# Array to store inactive service principals
$inactiveServicePrincipals = @()

# Function to handle retry logic
function Invoke-RetryableOperation {
    param (
        [ScriptBlock]$Operation,
        [int]$MaxRetries = 3
    )

    $retryCount = 0
    $retryAfter = 10  # Default retry time in seconds

    while ($retryCount -lt $MaxRetries) {
        try {
            & $Operation
            return $true
        } catch {
            if ($_.Exception.Message.Contains("throttled")) {
                Write-Host "Throttling encountered. Retrying after $retryAfter seconds..."
                Start-Sleep -Seconds $retryAfter
                $retryAfter = 2 * $retryAfter  # Exponential backoff strategy
                $retryCount++
            } else {
                Write-Error "Error: $($_.Exception.Message)"
                return $false
            }
        }
    }

    Write-Error "Operation failed after $MaxRetries retries."
    return $false
}

# Check each service principal for activity
foreach ($sp in $servicePrincipals) {
    $appId = $sp.AppId

    # Function to get recent activity for a service principal
    function Get-RecentActivity {
        $logs = Get-AzureADAuditSignInLogs -Filter "appId eq '$appId'" | Sort-Object createdDateTime -Descending
        return $logs | Select-Object -First 1
    }

    # Attempt to get recent activity, with retry logic
    $retryableOperation = {
        Get-RecentActivity
    }

    $recentActivity = Invoke-RetryableOperation -Operation $retryableOperation

    # Check if no recent activity found within threshold
    if ($recentActivity -eq $null -or $recentActivity.createdDateTime -lt $inactiveThreshold) {
        $inactiveServicePrincipals += $sp
    }
}

# Output inactive service principals
$inactiveServicePrincipals | Select-Object DisplayName, AppId

获取服务主体需要一些时间:

enter image description here

在我的环境中,共有 240 个应用程序,其中 215 个应用程序在 7 天内处于非活动状态:

enter image description here

$inactiveServicePrincipals | Measure-Object | Select-Object -ExpandProperty Count

enter image description here

我不会删除服务主体,要删除,您可以添加以下脚本

# Delete inactive service principals
foreach ($inactiveSP in $inactiveServicePrincipals) {
    Write-Host "Deleting $($inactiveSP.DisplayName) with AppId $($inactiveSP.AppId)..."
    Remove-AzureADServicePrincipal -ObjectId $inactiveSP.ObjectId -Force
}
Write-Host "Deletion complete."
© www.soinside.com 2019 - 2024. All rights reserved.