Pular para o conteúdo principal

Como Fazer Auditoria de Uso dos Projetos no Azure DevOps com PowerShell

Se você gerencia várias organizações e projetos no Azure DevOps, pode ser um desafio saber quais deles estão realmente ativos — seja com Boards (work items), commits em repositórios ou pipelines de CI/CD em uso.

Neste artigo, vou mostrar um método simples usando PowerShell para gerar um relatório CSV que ajuda a entender o uso real dos seus projetos, sem alterar nada no ambiente — só leitura.

O que vamos auditar?

  • Projetos existentes em várias organizações (organizações = assinaturas dentro do Azure DevOps).

  • Se os projetos têm Boards (work items) ativos.

  • Data do último commit nos repositórios.

  • Se existem pipelines com execuções recentes.

  • Uma aproximação da data de criação do projeto, baseada no primeiro commit encontrado.

Pré-requisitos

  • Permissão de acesso às organizações do Azure DevOps.

  • Um Personal Access Token (PAT) com permissões de leitura para:

    • Projetos e times

    • Work Items

    • Repositórios Git

    • Pipelines

  • PowerShell 7+ instalado na sua máquina.

Como gerar seu PAT

  1. Entre no Azure DevOps.

  2. Clique no seu avatar > Security > Personal Access Tokens > New Token.

  3. Configure com as permissões de leitura e validade desejadas.

  4. Copie o token gerado — ele aparecerá só uma vez.

Script PowerShell para auditoria

O script abaixo conecta nas suas organizações, lista os projetos e coleta as informações de uso, exportando para um arquivo CSV:


# Configurar suas organizações aqui

$organizations = @("sua-org-1", "sua-org-2")


# Solicita o PAT para autenticação segura

$pat = Read-Host -Prompt "Informe seu PAT do Azure DevOps" -AsSecureString

$ptraw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pat))

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$ptraw"))

$headers = @{Authorization = "Basic $base64AuthInfo"}


$resultados = @()


foreach ($org in $organizations) {

    Write-Host "Organização: $org"

    $projectsUrl = "https://dev.azure.com/$org/_apis/projects?api-version=7.0"

    $projects = (Invoke-RestMethod -Uri $projectsUrl -Headers $headers).value


    foreach ($project in $projects) {

        $projectName = $project.name

        Write-Host "Projeto: $projectName"


        # Verifica uso de Boards

        $wiql = @{ query = "SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = '$projectName'" } | ConvertTo-Json -Depth 3

        $workItemsUrl = "https://dev.azure.com/$org/$projectName/_apis/wit/wiql?api-version=7.0"

        $workItems = Invoke-RestMethod -Method Post -Uri $workItemsUrl -Headers $headers -Body $wiql -ContentType "application/json"

        $temBoards = if ($workItems.workItems.Count -gt 0) { "Sim" } else { "Não" }


        # Último commit (mais recente) em todos os repositórios do projeto

        $reposUrl = "https://dev.azure.com/$org/$projectName/_apis/git/repositories?api-version=7.0"

        $repos = (Invoke-RestMethod -Uri $reposUrl -Headers $headers).value

        $ultimoCommit = $null

        $primeiroCommit = $null


        foreach ($repo in $repos) {

            # Commit mais recente

            $commitsRecentesUrl = "https://dev.azure.com/$org/$projectName/_apis/git/repositories/$($repo.id)/commits?`$top=1"

            $commitsRecentes = (Invoke-RestMethod -Uri $commitsRecentesUrl -Headers $headers).value

            if ($commitsRecentes.Count -gt 0) {

                $dataRecente = $commitsRecentes[0].committer.date

                if (-not $ultimoCommit -or [datetime]$dataRecente -gt [datetime]$ultimoCommit) {

                    $ultimoCommit = $dataRecente

                }

            }


            # Commit mais antigo (para data aproximada da criação)

            $commitsAntigosUrl = "https://dev.azure.com/$org/$projectName/_apis/git/repositories/$($repo.id)/commits?`$top=1&`$orderby=authorDate asc"

            $commitsAntigos = (Invoke-RestMethod -Uri $commitsAntigosUrl -Headers $headers).value

            if ($commitsAntigos.Count -gt 0) {

                $dataAntiga = $commitsAntigos[0].committer.date

                if (-not $primeiroCommit -or [datetime]$dataAntiga -lt [datetime]$primeiroCommit) {

                    $primeiroCommit = $dataAntiga

                }

            }

        }


        if (-not $ultimoCommit) { $ultimoCommit = "Sem commit" }

        if (-not $primeiroCommit) { $primeiroCommit = "Indisponível" }


        # Verifica uso de pipelines

        $pipelinesUrl = "https://dev.azure.com/$org/$projectName/_apis/pipelines?api-version=7.0"

        $pipelines = (Invoke-RestMethod -Uri $pipelinesUrl -Headers $headers).value

        $usouPipeline = "Não"

        foreach ($pipeline in $pipelines) {

            $runsUrl = "https://dev.azure.com/$org/$projectName/_apis/pipelines/$($pipeline.id)/runs?`$top=1"

            $runs = (Invoke-RestMethod -Uri $runsUrl -Headers $headers).value

            if ($runs.Count -gt 0) {

                $usouPipeline = "Sim"

                break

            }

        }


        # Monta o objeto resultado

        $resultados += [PSCustomObject]@{

            Organizacao     = $org

            Projeto         = $projectName

            CriadoEm        = $primeiroCommit

            BoardsUsado     = $temBoards

            UltimoCommit    = $ultimoCommit

            PipelinesUsado  = $usouPipeline

        }

    }

}


# Exporta para CSV

$csvPath = ".\\auditoria-devops-multiorgs.csv"

$resultados | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8


Write-Host "Auditoria concluída! Arquivo salvo em $csvPath"

=====================================================================

Como usar

  1. Copie o script acima para um arquivo .ps1 (exemplo: auditoria-devops.ps1).

  2. Altere a variável $organizations para as suas organizações do Azure DevOps.

  3. Abra o PowerShell e execute o script.

  4. Informe seu PAT quando solicitado.

  5. Aguarde o término da execução e confira o arquivo .csv gerado.

Resultado esperado

O arquivo CSV terá as seguintes informações:


Por que vale a pena usar esse script de auditoria no Azure DevOps?

  1. Você ganha visibilidade real do ambiente
    Saber exatamente quais projetos estão ativos, abandonados ou apenas parcialmente utilizados evita desperdício de recursos e ajuda na organização.

  2. Ajuda no planejamento de governança
    Você pode identificar padrões: quais equipes usam mais Boards? Quais usam só o repositório? Isso ajuda a definir diretrizes e boas práticas internas.

  3. É ideal para ambientes com muitas organizações e projetos
    Em vez de fazer tudo manualmente, o script percorre todas as organizações de forma automatizada.

  4. Garante segurança e tranquilidade
    Como o script é somente leitura, ele não modifica nada — ou seja, você pode rodar sem medo em produção.

  5. Facilita relatórios e auditorias oficiais
    O CSV gerado pode ser facilmente enviado para times de governança, compliance, segurança ou gestão.

  6. É base para automações futuras
    Você pode adaptar esse script para criar painéis no Power BI, gerar alertas, ou até sugerir arquivamento automático no futuro (com cuidado, claro).

Se você trabalha com DevOps em uma organização que tem múltiplos times, projetos legados e ambientes complexos, esse script é uma mão na roda para iniciar uma auditoria eficiente, sem riscos e com dados valiosos.



Comentários

Postagens mais visitadas deste blog

Microsoft Authenticator agora suporta Passkeys: Como ativar e testar

 A autenticação de dois fatores (MFA) sempre foi uma das melhores práticas para proteger contas online. Agora, a Microsoft deu um passo além ao adicionar suporte nativo para Passkeys no Microsoft Authenticator . Essa atualização, lançada em janeiro de 2025, permite que os usuários façam login sem precisar de senhas tradicionais, utilizando métodos resistentes a phishing e mais convenientes, como biometria ou PIN. Neste artigo, vamos explorar o que são Passkeys, os benefícios desse novo recurso e como ativá-lo e testá-lo no Microsoft Authenticator . O que são Passkeys? As Passkeys são um método moderno de autenticação baseado no padrão FIDO2/WebAuthn , que permite que os usuários façam login de maneira segura sem precisar inserir senhas. Em vez disso, eles usam biometria (impressão digital ou reconhecimento facial), um PIN ou outro fator local para validar a identidade. Principais benefícios das Passkeys - Resistência a phishing: Como não há senhas para serem roubadas, ataques d...

Mudança no Processo de Exclusão de Usuário no Microsoft 365

 A Microsoft fez uma atualização importante no processo de exclusão de usuários no Microsoft 365 . Agora, ao excluir um usuário, os delegados (pessoas que têm acesso à caixa de correio e aos arquivos) terão apenas 30 dias para acessar o OneDrive do usuário excluído. O que muda? Prazo reduzido : O tempo de acesso aos arquivos foi limitado a 30 dias após a exclusão do usuário, o que significa que os dados ficam acessíveis por um período mais curto. Impacto nos Delegados : Antes, os delegados podiam acessar os dados por mais tempo. Agora, a Microsoft reduziu esse prazo para evitar o armazenamento prolongado de dados de usuários excluídos. Ação Rápida Necessária : Caso seja necessário manter os arquivos por mais tempo, a organização deve tomar providências para transferir ou arquivar esses dados antes que o acesso expire. Por que isso é importante? Essa mudança reflete um esforço da Microsoft para alinhar a gestão de dados com práticas de segurança mais rígidas, incentivando as empre...

Microsoft está removendo as permissões "Todos, exceto usuários externos" no OneDrive

 Já encontrou arquivos no OneDrive acessíveis para toda a sua organização, mesmo sem ter compartilhado intencionalmente? Isso acontece por conta da permissão "Todos, exceto usuários externos" (EEEU) , que permite o acesso interno sem restrições. Mas isso está prestes a mudar. - A partir de 10 de abril de 2025 , a Microsoft removerá a permissão EEEU dos sites raiz do OneDrive e das bibliotecas de documentos padrão, reduzindo o risco de compartilhamento acidental de dados. - Se seus aplicativos, processos ou usuários dependem dessa permissão, eles perderão o acesso assim que a alteração for aplicada. - No entanto, permissões diretas de arquivos e pastas não serão afetadas – quem já tem acesso explícito continuará com permissão. Muitas organizações deixam conteúdos abertos para todos os usuários internos sem perceber. Apesar de parecer inofensivo, isso aumenta riscos de segurança e pode levar à exposição involuntária de dados. O que você deve fazer? ✅ Revisar as permissões ...