Segurança no Microsoft Entra ID: Como Identificar e Gerenciar Usuários Guest no Microsoft Entra ID
Olá pessoal! Blz?
No artigo de hoje gostaria de trazer algo que me fez pensar um pouco após um amigo trazer essa questão para mim: como saber se um usuário Guest ainda está ativo no tenant de origem? e depois como a Microsoft não criou algo para controlar isso no Microsoft Entra ID de forma automática.
Acho que a resposta é simples na verdade, “Você como dono ou responsável pela segurança do Microsoft Entra ID deveria rever, controlar e manter a segurança do ambiente”.
A colaboração externa é essencial nos ambientes modernos em nuvem. Com o crescimento do modelo B2B, empresas frequentemente convidam usuários externos (guests) para seus ambientes através do Microsoft Entra ID. Mas existe uma pergunta crítica que muitas organizações deixam passar:
Esses usuários ainda deveriam ter acesso ao seu ambiente?
Ok, eu sei, eu sei!!!!! Se a conta está desativada no tenant de origem não vai conseguir fazer login no seu tenant! Mas e se por algum motivo essa conta for reabilitada, a conta passa a ter novamente o acesso ao seu tenant e assinatura?
Contas guest inativas se acumulam silenciosamente ao longo do tempo — e podem se tornar um risco significativo de segurança e compliance.
Por que usuários Guest inativos são um risco?
Usuários externos (guest) representam um desafio particular dentro da governança de identidades. Diferente dos usuários internos, que normalmente seguem processos bem definidos de admissão, movimentação e desligamento, contas guest não estão sujeitas ao mesmo nível de controle organizacional. Muitas vezes, esses usuários pertencem a outras empresas e, portanto, estão fora do domínio direto de gestão do seu tenant no Microsoft Entra ID.
Esse cenário abre espaço para diversos riscos. Um usuário pode, por exemplo, já ter deixado a empresa de origem e ainda manter acesso ao seu ambiente. Em outros casos, contas são criadas, mas nunca chegam a ser utilizadas — permanecendo ativas indefinidamente. Há também o risco mais crítico: credenciais comprometidas de usuários externos que continuam válidas e com acesso ao seu tenant, sem qualquer visibilidade direta da sua equipe.
Além disso, como não é possível verificar diretamente o estado da conta no tenant de origem, a organização perde ainda mais controle sobre essas identidades. Isso reforça a necessidade de monitoramento ativo e políticas de governança específicas para usuários guest.
Pode chegar um momento, especialmente em uma grande empresa, que haverá muitos usuários Guest dependendo de quantos parceiros a empresa tem, parceiros para projetos específicos, parceiros de suporte, etc…
No portal do Microsoft Entra ID -> Users -> All Users você pode filtrar por User type == “Guest” e ver todos os usuários Guest em seu Tenant:
No perfil do usuário podemos preencher o campo Company name para ter uma melhor identificação da empresa do usuário.
Estratégias recomendadas de governança
Antes de partir para automações, é essencial estabelecer uma base sólida de governança utilizando recursos do Microsoft Entra ID Governance. Esses controles garantem que o acesso de usuários externos seja continuamente validado e alinhado às necessidades do negócio. Algumas práticas fundamentais incluem:
- Access Reviews: Revisões periódicas para confirmar se o acesso ainda é necessário
- Expiração de usuários guest: Remoção automática após determinado período
- Monitoramento de atividade: Identificação de contas inativas ou pouco utilizadas
Essas medidas ajudam a evitar o acúmulo de acessos desnecessários e criam a base para uma estratégia de segurança mais madura.
Identificando usuários Guest inativos com PowerShell
Depois de entender os riscos e estabelecer uma base mínima de governança, o próximo passo é ganhar visibilidade sobre quais usuários guest realmente estão utilizando o ambiente. Uma forma prática de fazer isso é consultando o Microsoft Graph via PowerShell, cruzando informações de tipo de usuário com atividade de login.
Com essa abordagem, é possível identificar tanto contas que nunca chegaram a ser utilizadas quanto usuários que não acessam o tenant há um período relevante. Isso ajuda a transformar uma preocupação abstrata em dados concretos, facilitando revisões de acesso, ações de cleanup e decisões de segurança mais assertivas.
Abaixo, segue um script simples e eficiente para apoiar esse processo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$InactiveDays = 90
$CutoffDate = (Get-Date).AddDays(-$InactiveDays)
Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All"
Select-MgProfile -Name "v1.0"
$Guests = Get-MgUser -All -Filter "userType eq 'Guest'" `
-Property "displayName,userPrincipalName,signInActivity,externalUserState,accountEnabled"
$Report = foreach ($User in $Guests) {
$LastLogin = $User.SignInActivity.LastSuccessfulSignInDateTime
if (!$LastLogin) {
$Status = "No sign-ins found"
}
elseif ([datetime]$LastLogin -lt $CutoffDate) {
$Status = "Inactive"
}
else {
$Status = "Active"
}
[PSCustomObject]@{
Nome = $User.DisplayName
UPN = $User.UserPrincipalName
UltimoLogin = $LastLogin
Status = $Status
}
}
$Report | Where-Object {$_.Status -ne "Active"} | Format-Table
O script classifica os usuários guest com base na atividade de login, o script filtra os usuários que não estão com o status “Active” que é excluído por ter feito login a menos que X dias.
- Active: realizou login recentemente
- Inactive: não acessa há mais de X dias
- No sign-ins found: nunca utilizou o acesso concedido
Essa classificação facilita a identificação de contas que podem ser revisadas ou removidas com segurança.
O que fazer após identificar contas inativas
Após identificar usuários inativos ou que nunca fizeram logon, o próximo passo é agir sobre essas informações. Essa visibilidade permite revisar acessos que podem não ser mais necessários e reduzir riscos no ambiente.
Contas sem uso podem indicar acessos desnecessários ou abandonados, enquanto usuários inativos há longos períodos devem ser reavaliados quanto à necessidade de manter permissões ativas.
A partir disso, é possível:
- Revisar acessos com os responsáveis
- Desabilitar contas temporariamente
- Notificar usuários antes de remoção
- Automatizar processos de cleanup
Esse processo transforma dados em ação e fortalece a governança de identidades no tenant.
Relatório semanal de contas Guest no tenant
O que eu gosto e procuro fazer é gerar um relatório semanal e enviar aos responsáveis, pois quando mais de uma pessoa recebe uma lista com algum tipo de alerta esperamos que ações sejam tomadas. Essa prática adiciona uma camada contínua de visibilidade e permite acompanhar a evolução do acesso externo ao longo do tempo.
Segue abaixo o script powershell que você usar em uma Azure Automation Account para automatizar o envio semanal do relatório e você receberia um e-mail parecido com o abaixo, ou você pode personalizar com a sua preferência:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
param(
[int]$InactiveDays = 90,
[string]$SenderUserId = "[email protected]",
[string[]]$Recipients = @("[email protected]","[email protected]")
)
$CutoffDate = (Get-Date).AddDays(-$InactiveDays)
$DateStamp = Get-Date -Format "dd-MM-yyyy"
Connect-MgGraph -Identity -NoWelcome -Scopes "Mail.Send","Mail.Send.Shared","User.Read"
$Guests = Get-MgUser -All `
-Filter "userType eq 'Guest'" `
-Property "id,displayName,userPrincipalName,mail,createdDateTime,externalUserState,accountEnabled,signInActivity,companyName"
$Report = foreach ($User in $Guests) {
$LastSuccessful = $null
if ($User.SignInActivity) {
$LastSuccessful = $User.SignInActivity.LastSuccessfulSignInDateTime
}
if (-not $LastSuccessful) {
$Status = "Never signed in"
}
elseif ([datetime]$LastSuccessful -lt $CutoffDate) {
$Status = "Inactive"
}
else {
$Status = "Active"
}
[PSCustomObject]@{
DisplayName = $User.DisplayName
UserPrincipalName = $User.UserPrincipalName
Status = $Status
LastSuccessfulSignInDateTime = $LastSuccessful
CompanyName = $User.CompanyName
}
}
$AccountsForReview = $Report |
Where-Object { $_.Status -in @("Inactive","Never signed in") } |
Sort-Object Status, DisplayName
$RowsHtml = foreach ($Row in $AccountsForReview) {
$LastLogin = if ($Row.LastSuccessfulSignInDateTime) {
([datetime]$Row.LastSuccessfulSignInDateTime).ToString("dd-MM-yyyy HH:mm")
}
else {
"N/A"
}
@"
<tr>
<td>$($Row.DisplayName)</td>
<td>$($Row.UserPrincipalName)</td>
<td><center>$LastLogin</center></td>
<td><center>$($Row.CompanyName)</center></td>
</tr>
"@
}
$RowsHtmlString = ($RowsHtml -join "`n")
$BodyHtml = @"
<html>
<head>
<style>
body {
font-family: Arial, sans-serif;
font-size: 16px;
}
.container {
max-width: 900px;
}
h2 {
color: #1f4e79;
}
table {
border-collapse: collapse;
width: 100%;
margin-top: 12px;
font-family: Arial, sans-serif;
font-size: 16px;
}
th {
background-color: #1f4e79;
color: white;
text-align: center;
padding: 5px;
font-size: 16px;
font-family: Arial, sans-serif;
border: 1px solid #d9d9d9;
}
td {
padding: 5px;
border: 1px solid #d9d9d9;
white-space: nowrap;
font-family: Arial, sans-serif;
font-size: 16px;
}
</style>
</head>
<body>
<div class="container">
<h2>Weekly Guest Users Report - $DateStamp</h2>
<p>Hello team,</p>
<p>Please find below the weekly guest user summary for the tenant.</p>
<table>
<tr>
<th>Display Name</th>
<th>User PrincipalName</th>
<th>Last Sign-In</th>
<th>Company Name</th>
</tr>
$RowsHtmlString
</table>
</div>
</body>
</html>
"@
$ToRecipients = foreach ($Recipient in $Recipients) {
@{
emailAddress = @{
address = $Recipient
}
}
}
$MailBody = @{
message = @{
subject = "Weekly Guest Users Report - $DateStamp"
body = @{
contentType = "HTML"
content = $BodyHtml
}
toRecipients = $ToRecipients
}
saveToSentItems = $true
}
Send-MgUserMail -UserId $SenderUserId -BodyParameter $MailBody
Concluindo!
Gerenciar usuários guest vai muito além de apenas conceder acesso — é um processo contínuo de visibilidade, controle e revisão. Ao combinar identificação de inatividade, automação e relatórios recorrentes, a organização passa a reduzir riscos e fortalecer sua postura de segurança.
Mais do que uma tarefa operacional, essa prática representa um passo importante rumo a uma governança de identidades mais madura e eficiente.
Artigos relacionados
Manage guest access with access reviews
Understand and manage the properties of B2B guest users
Compartilhe o artigo com seus amigos clicando nos icones abaixo!!!



