用于列出直接分配未返回预期结果的 Azure DevOps 用户的 PowerShell 脚本

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

我正在尝试编写一个 PowerShell 脚本来列出在 Azure DevOps 中直接分配的所有用户,不包括某些技术帐户。该脚本还应从 Azure AD 检索其经理的电子邮件地址。但是,该脚本没有返回预期结果。

我想要实现的目标:

  1. 在 Azure DevOps 中获取具有直接分配的用户(分配源等于“直接”)。
  2. 从列表中排除特定用户(技术帐户)。
  3. 从 Azure AD 检索每个用户的经理的电子邮件地址。
  4. 输出用户电子邮件地址列表并 他们的经理。

我当前的脚本:

# Variables
$organization = "org-name"
$azureDevOpsPat = "your-azure-devops-pat"  # PAT with full access
$tenantId = "your-tenant-id"
$clientId = "your-client-id"
$excludedUsers = @(
    "[email protected]",
    "[email protected]",
    "[email protected]"

)

# Scopes for Microsoft Graph
$scopes = @("User.Read.All", "Directory.Read.All")

# Connect to Microsoft Graph
Connect-MgGraph -ClientId $clientId -TenantId $tenantId -Scopes $scopes -DeviceCode

# Azure DevOps API Endpoint
$devOpsApiUrl = "https://vsaex.dev.azure.com/$organization/_apis/userentitlements?api-version=7.0"

# Prepare Azure DevOps API Headers
$devOpsHeaders = @{
    Authorization = ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$azureDevOpsPat")))
    "Content-Type" = "application/json"
}

# Fetch user entitlements from Azure DevOps
$devOpsResponse = Invoke-RestMethod -Uri $devOpsApiUrl -Headers $devOpsHeaders -Method Get

# Check if the response contains any users
if ($devOpsResponse.count -gt 0) {
    # Include all users with direct assignments
    $directUsers = $devOpsResponse.value | Where-Object {
        $_.accessLevel.assignmentSource -eq "direct"
    }

    foreach ($user in $directUsers) {
        $userEmail = $user.user.mailAddress
        $userPrincipalName = $user.user.principalName

        # Get user identifier for exclusion check (UPN or Email)
        $userIdentifier = if ($userPrincipalName) { $userPrincipalName } else { $userEmail }

        # Check if the user is in the exclusion list
        if ($excludedUsers -contains $userIdentifier) {
            continue
        }

        # Get user details from Microsoft Graph API
        try {
            $userGraphResponse = Get-MgUser -UserId $userIdentifier -ErrorAction Stop
            $userEmail = $userGraphResponse.Mail

            # Get manager's information
            try {
                $managerResponse = Get-MgUserManager -UserId $userIdentifier -ErrorAction Stop
                $managerUpn = $managerResponse.UserPrincipalName
            } catch {
                $managerUpn = $null
            }
        } catch {
            continue
        }

        # Collect email addresses
        if ($userEmail) {
            $userEmailAddresses += $userEmail
        }

        if ($managerUpn) {
            $managerEmailAddresses += $managerUpn
        }
    }

    # Output the lists
    $userEmailsString = $userEmailAddresses -join "; "
    $managerEmailsString = $managerEmailAddresses -join "; "

    Write-Host "User Emails (To): $userEmailsString"
    Write-Host "Manager Emails (CC): $managerEmailsString"
} else {
    Write-Host "No user entitlements found in Azure DevOps."
}

# Disconnect from Microsoft Graph
Disconnect-MgGraph

问题:

当我运行该脚本时,它会返回“找到 0 个具有直接分配的用户”,即使我知道在 Azure DevOps 中存在具有直接分配的用户。 手动调用 Azure DevOps API 仅返回我自己的用户权限,并且 $directUsers.Count 为 0。

附加信息:

我在 macOS 上运行 PowerShell。 使用最新版本的 Microsoft.Graph 模块。 在 Azure AD(租户所有者)中拥有读取用户信息所需的权限。

azure powershell azure-devops
1个回答
0
投票

您的脚本中有几个错误。

  1. 根据 REST API 用户权利 - 列表
  • AssignmentSource
    支持的值为
    groupRule
    none
    unknown
    。要获取分配源为直接的用户,您应该使用
    $_.accessLevel.assignmentSource -eq "unknown"
  • REST API 的响应如下所示。因此,您应该将
    if ($devOpsResponse.count -gt 0)
    更改为
    if ($devOpsResponse.members.Count -gt 0)
    ,将
    $directUsers = $devOpsResponse.value
    更改为
    $directUsers = $devOpsResponse.members
{
  "members": [
    {
      "user": {
       ...
    },
  1. 根据Get-MgUser
  • UserId
    是AAD中用户的对象ID,不能使用UPN或电子邮件作为输入。请改用 UPN 作为过滤器。例如,
    $userGraphResponse = Get-MgUser -Filter "userPrincipalName eq '$userIdentifier'" -ErrorAction Stop
  • 通过
    $userId = $userGraphResponse.Id
    获取用户的id,稍后会用到。
  1. 根据Get-MgUserManager
  • UserId
    是对象id,使用
    $userId
    作为输入来获取有关该用户的经理的信息。
  • $managerResponse.UserPrincipalName
    的响应中没有这样的参数
    Get-MgUserManager
    。先运行
    Get-MgUserManager
    获取管理员的 id,然后运行
    Get-MgUser
    获取该管理员的邮件。

以下是修改后的脚本供您参考。

# Variables
$organization = "{DevOps Org}"
$azureDevOpsPat = "{PAT}"  # PAT with full access
$tenantId = "{tenant id}"
$clientId = "{client id}"
$clientSecret = "{client secret}"
$secureClientSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($clientId, $secureClientSecret)

$excludedUsers = @(
    "[email protected]",
    "[email protected]",
    "[email protected]"
)

# Scopes for Microsoft Graph
$scopes = @("User.Read.All", "Directory.Read.All")

# Connect to Microsoft Graph
Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential

# Azure DevOps API Endpoint
$devOpsApiUrl = "https://vsaex.dev.azure.com/$organization/_apis/userentitlements?top=2000&api-version=7.0"

# Prepare Azure DevOps API Headers
$devOpsHeaders = @{
    Authorization = ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$azureDevOpsPat")))
    "Content-Type" = "application/json"
}

# Fetch user entitlements from Azure DevOps
$devOpsResponse = Invoke-RestMethod -Uri $devOpsApiUrl -Headers $devOpsHeaders -Method Get
# Write-Host "Fetched user entitlements: $($devOpsResponse | ConvertTo-Json -Depth 3)"

# Check if the response contains any users
if ($devOpsResponse.members.Count -gt 0) {
    # Include all users with direct assignments
    $directUsers = $devOpsResponse.members | Where-Object {
        $_.accessLevel.assignmentSource -eq "unknown"
    }

    foreach ($user in $directUsers) {
        # Write-Host "user: $($user | ConvertTo-Json -Depth 3)"
        $userEmail = $user.user.mailAddress
        $userPrincipalName = $user.user.principalName


        # Get user identifier for exclusion check (UPN or Email)
        $userIdentifier = if ($userPrincipalName) { $userPrincipalName } else { $userEmail }
        # Write-Host $userIdentifier

        # Check if the user is in the exclusion list
        if ($excludedUsers -contains $userIdentifier) {
            continue
        }

        # Get user details from Microsoft Graph API
        try {
            $userGraphResponse = Get-MgUser -Filter "userPrincipalName eq '$userIdentifier'" -ErrorAction Stop
            $userId = $userGraphResponse.Id
            $userEmail = $userGraphResponse.Mail

            # Get manager's information
            try {
                $managerResponse = Get-MgUserManager -UserId $userId -ErrorAction Stop
                # Write-Host "managerResponse: $($managerResponse | ConvertTo-Json -Depth 3)"
                $managerId= $managerResponse.Id
                $manager = Get-MgUser -UserId $managerId
                $managerMail = $manager.Mail
            } catch {
                $managerMail = $null
            }
        } catch {
            continue
        }

        # Collect email addresses
        if ($userEmail) {
            $userEmailsString += $userEmail + ";"
        }

        if ($managerMail) {
            $managerEmailsString += $managerMail + ";"
        }
    }

    # Output the lists
    Write-Host "User Emails (To): $userEmailsString"
    Write-Host "Manager Emails (CC): $managerEmailsString"

} else {
    Write-Host "No user entitlements found in Azure DevOps."
}

# Disconnect from Microsoft Graph
Disconnect-MgGraph

结果:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.