Como Mapear Aniversários de utilizadores para um Atributo de Extensão no Entra ID com PowerShell

Na era digital de hoje, manter informações precisas e atualizadas sobre os utilizadores é crucial para experiências personalizadas e uma gestão eficiente. Um requisito comum é mapear os dados de aniversário dos utilizadores para atributos personalizados no Azure Active Directory (Entra ID). Este mapeamento permite um acesso mais rápido ao campo de aniversário, pois está diretamente disponível ao fazer uma chamada ao endpoint dos utilizadores da Microsoft Graph API.

Neste artigo, vamos orientá-lo pelo processo de mapeamento do campo de aniversário para um atributo de extensão no Entra ID, usando um script PowerShell.

Pré-Requisitos

Antes de executar o script, assegure-se de que possui os seguintes pré-requisitos:

  1. Azure AD Tenant: Necessita de acesso a uma tenant Azure Active Directory.
  2. Registo de Aplicação: Registe uma aplicação no Azure AD para obter o ID do Cliente e o Segredo do Cliente. Pode fazer isto seguindo o guia oficial da Microsoft.
  3. Permissões da Graph API: Atribua as permissões necessárias à sua aplicação para aceder aos dados dos utilizadores. A permissão User.Read é requerida. Para mais detalhes, visite a referência de permissões da Microsoft Graph API.
Script

O script PowerShell está dividido em várias funções, cada uma responsável por uma tarefa específica. Aqui está uma explicação detalhada de cada função:

Obter o Token de Acesso
function Get-AccessToken {
    Write-Host "Getting access token."
    $body = @{
        client_id     = $CLIENT_ID
        scope         = "https://graph.microsoft.com/.default"
        client_secret = $CLIENT_SECRET
        grant_type    = "client_credentials"
    }

    $response = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body $body

    if ($response.access_token) {
        Write-Host "Access token acquired."
        LogMessage "Access token acquired." $LOG_FILE_PATH
        return $response.access_token
    } else {
        $error_msg = "Could not acquire access token"
        Write-Error $error_msg
        LogMessage $error_msg $LOG_FILE_PATH
        throw $error_msg
    }
}

Solicita um token de acesso ao Azure AD para autenticar com a Microsoft Graph API.

Obter os Utilizadores utilizando a Graph API

function Get-Users {
    param (
        [string]$accessToken
    )
    
    Write-Host "Fetching users from Microsoft Graph."
    LogMessage "Fetching users from Microsoft Graph." $LOG_FILE_PATH
    $users = @()
    $url = "https://graph.microsoft.com/beta/users"
    $headers = @{
        "Authorization" = "Bearer $accessToken"
    }

    do {
        $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
        $users += $response.value
        $url = $response."@odata.nextLink"
        $usersFetchedCount = $response.value.Count
        Write-Host "Fetched $usersFetchedCount users."
        LogMessage "Fetched $usersFetchedCount users." $LOG_FILE_PATH
    } while ($url)

    Write-Host "Total users fetched: $($users.Count)"
    LogMessage "Total users fetched: $($users.Count)" $LOG_FILE_PATH
    return $users
}

Obtém uma lista de utilizadores da Microsoft Graph, gerindo a paginação para garantir que todos os utilizadores são obtidos.

Obter o Aniversário do Utilizador

function Get-UserBirthday {
    param (
        [string]$userId,
        [string]$accessToken
    )
    
    Write-Host "Fetching birthday for user $userId."
    LogMessage "Fetching birthday for user $userId." $LOG_FILE_PATH
    $url = "https://graph.microsoft.com/beta/users/$userId" + '?$select=birthday'
    $headers = @{
        "Authorization" = "Bearer $accessToken"
    }

    $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
    $birthday = $response.birthday
    Write-Host "User $userId birthday: $birthday"
    LogMessage "User $userId birthday: $birthday" $LOG_FILE_PATH
    return $birthday
}

Obtém o aniversário de um utilizador específico usando o seu ID.

Atualizar o Atributo de Extensão do Utilizador

function Update-UserExtensionAttribute {
    param (
        [string]$userId,
        [string]$birthday,
        [string]$accessToken
    )
    
    Write-Host "Updating user $userId with birthday $birthday."
    LogMessage "Updating user $userId with birthday $birthday." $LOG_FILE_PATH
    $url = "https://graph.microsoft.com/beta/users/$userId"
    $headers = @{
        "Authorization" = "Bearer $accessToken"
        "Content-Type"  = "application/json"
    }
    $data = @{
        "onPremisesExtensionAttributes" = @{
            $EXTENSION_ATTRIBUTE = $birthday
        }
    }
    $json_data = $data | ConvertTo-Json -Depth 3

    Invoke-RestMethod -Uri $url -Headers $headers -Method Patch -Body $json_data
    Write-Host "User $userId updated successfully."
    LogMessage "User $userId updated successfully." $LOG_FILE_PATH
}

Atualiza o atributo de extensão de um utilizador com o seu aniversário.

Função Principal

function Main {
    Write-Host "Processing a request to update user birthdays."
    LogMessage "Processing a request to update user birthdays." $LOG_FILE_PATH
    
    try {
        $requiredFields = @($TENANT_ID, $CLIENT_ID, $CLIENT_SECRET, $EXTENSION_ATTRIBUTE, $LOG_FILE_PATH)
        foreach ($field in $requiredFields) {
            if (-not $field) {
                $errorMsg = "Parameter '$field' is missing or empty."
                Write-Error $errorMsg
                LogMessage $errorMsg $LOG_FILE_PATH
                return $errorMsg
            }
        }

        if (-not (Test-Path $LOG_FILE_PATH)) {
            Write-Host "Creating log file at $LOG_FILE_PATH"
            New-Item -Path $LOG_FILE_PATH -ItemType File -Force | Out-Null
        }

        Write-Host "Logging results to $LOG_FILE_PATH"
        LogMessage "Starting script execution at $(Get-Date)" $LOG_FILE_PATH

        $accessToken = Get-AccessToken
        Write-Host "Access token acquired."
        
        $users = Get-Users -accessToken $accessToken

        foreach ($user in $users) {
            if ($user.userType -eq "Member") {
                $userId = $user.id
                Write-Host "Processing user $userId."
                LogMessage "Processing user $userId." $LOG_FILE_PATH

                $birthday = Get-UserBirthday -userId $userId -accessToken $accessToken
                if ($birthday) {
                    Update-UserExtensionAttribute -userId $userId -birthday $birthday -accessToken $accessToken
                } else {
                    Write-Host "Birthday not found for user $userId."
                    LogMessage "Birthday not found for user $userId." $LOG_FILE_PATH
                }
            }
        }
        
        Write-Host "Birthday update process completed successfully."
        LogMessage "Birthday update process completed at $(Get-Date)" $LOG_FILE_PATH
        return "Birthday update completed successfully."
    } catch {
        Write-Error "Error processing the request: $_"
        LogMessage "Error processing the request: $_" $LOG_FILE_PATH
        return "Error processing the request: $_"
    }
}

# Run the main function directly for testing purposes
$result = Main
Write-Host $result

Estrutura todo o processo de obtenção do aniversário e atualização do atributo de extensão.

Registo de Logs

function LogMessage {
    param (
        [string]$message,
        [string]$logFilePath
    )
    
    if (-not (Test-Path $logFilePath)) {
        New-Item -Path $logFilePath -ItemType File -Force | Out-Null
    }
    
    # Format message with timestamp and write to log file
    $formattedMessage = "$(Get-Date) - $message"
    Add-Content -Path $logFilePath -Value $formattedMessage
}

Regista logs para um dado ficheiro especificado, criando o ficheiro se o mesmo não existir. Inclui timestamps para melhor compreensão do seu conteúdo.

Executar o Script

Para executar o script, precisa de especificar os parâmetros necessários.

.Update-Birthdays.ps1 -TENANT_ID "your_tenant_id" -CLIENT_ID "your_client_id" -CLIENT_SECRET "your_client_secret" -EXTENSION_ATTRIBUTE "your_extension_attribute" -LOG_FILE_PATH "C:PathToLogFile.txt"

Subsitua os espaços reservados pela dados que deseja utilizar: tenant ID, client ID, client secret, extension attribute name e log file path.

Mapear o campo de aniversário para um atributo de extensão no Entra ID permite uma gestão de utilizadores mais eficiente ao proporcionar um acesso mais rápido à informação de aniversário através da Microsoft Graph API. Esta configuração simplifica o processo de recuperação e gestão de dados dos utilizadores, facilitando uma melhor personalização e experiência do utilizador dentro da sua organização.

Ao seguir os passos descritos neste artigo, pode garantir que a sua configuração do Azure AD está otimizada para gerir dados de aniversário de utilizadores de forma eficaz. Quer seja um administrador de TI a procurar melhorar o seu diretório de utilizadores ou um desenvolvedor a tentar integrar dados de aniversário nas suas aplicações, esta abordagem oferece uma solução robusta.

Sinta-se à vontade para personalizar o script fornecido conforme as suas necessidades específicas, como adicionar registos adicionais ou modificar os processos de recuperação de dados. Se encontrar algum problema ou tiver requisitos específicos, consulte a documentação da Microsoft Graph API ou entre em contacto com a nossa equipa para obter suporte.

Faça o download do script PowerShell completo aqui.

Interessado?

ContactosEntre em contacto connosco