-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRevoke_User_Tokens.ps1
146 lines (125 loc) · 6.25 KB
/
Revoke_User_Tokens.ps1
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
# Function to check if the script is running with elevated privileges
function Test-IsAdmin {
$currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
return $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
# Function to check and install required modules
function Ensure-Module {
param (
[string]$ModuleName
)
try {
if (-not (Get-Module -ListAvailable -Name $ModuleName)) {
Write-Host "Module $ModuleName is not installed. Installing..." -ForegroundColor Yellow
Install-Module -Name $ModuleName -Force -AllowClobber -ErrorAction Stop
Write-Host "Module $ModuleName installed successfully." -ForegroundColor Green
} else {
Write-Host "Module $ModuleName is already installed." -ForegroundColor Green
}
}
catch {
Write-Host "Failed to install $ModuleName. Please check your connection or module source." -ForegroundColor Red
exit
}
}
# Default settings for Verbose and Debug modes
$VerboseMode = $false
$DebugMode = $false
# Set Execution Policy to RemoteSigned
Write-Host "Temporarily setting the Execution Policy to RemoteSigned for the current session..." -ForegroundColor Yellow
Set-ExecutionPolicy RemoteSigned -Scope Process -Force
# Ensure required modules are installed
Ensure-Module -ModuleName "Microsoft.Graph.Authentication"
Ensure-Module -ModuleName "Microsoft.Graph.Users"
Ensure-Module -ModuleName "Microsoft.Graph.Reports"
# Secure connection to Microsoft Graph
try {
Write-Host "Connecting to Microsoft Graph with scopes: User.Read.All, AuditLog.Read.All, Directory.Read.All"
Connect-MgGraph -Scopes "User.Read.All, AuditLog.Read.All, Directory.Read.All" -ErrorAction Stop
}
catch {
Write-Host "Failed to connect to Microsoft Graph. Ensure you have the necessary permissions and network connectivity." -ForegroundColor Red
exit
}
# Loop to revoke sessions for multiple users
do {
$userInput = Read-Host "Please enter the User Principal Name (UPN) or ObjectID of the user"
# Query the user's last sign-in status before revocation
try {
Write-Host "Querying the user's sign-in activity before revocation..."
$signInActivitiesBefore = Get-MgAuditLogSignIn -Filter "userPrincipalName eq '$userInput' or userId eq '$userInput'" -Top 1 |
Select-Object CreatedDateTime, Status, TokenIssuerType, ResourceDisplayName, ApplicationDisplayName, IPAddress
}
catch {
Write-Host "Failed to query sign-in activity for $userInput. Ensure the user exists." -ForegroundColor Red
continue
}
$signInActivitiesBefore | Format-Table -AutoSize
# Revoke all sessions for the user
Write-Host "Revoking all sign-in sessions for the user..."
Revoke-MgUserSignInSession -UserId $userInput -Verbose:$VerboseMode -Debug:$DebugMode
Write-Host "Sign-in sessions have been revoked for $userInput." -ForegroundColor Yellow
# Get the last password change timestamp
try {
Write-Host "Retrieving the user's last password change date..."
$userDetails = Get-MgUser -UserId $userInput -Property passwordLastSet
if ($userDetails.passwordLastSet) {
Write-Host "User's password was last updated on: $($userDetails.passwordLastSet)" -ForegroundColor Green
} else {
Write-Host "Password change information not available for this user." -ForegroundColor Red
}
}
catch {
Write-Host "Failed to retrieve the last password change date for $userInput." -ForegroundColor Red
}
# Inform the script runner to have the user reset their password
Write-Host " "
Write-Host "[URGENT] The user's password must be reset immediately. Please inform the user to reset their password." -ForegroundColor Red
Write-Host " "
# Sleep to give time for token revocation to propagate
Start-Sleep -Seconds 30 # Increased wait time for propagation
# Query audit logs for the revocation event
try {
Write-Host "Querying the audit logs for the revocation event..."
$auditLogs = Get-MgAuditLogDirectoryAudit -Filter "activityDisplayName eq 'Revoke sign-in sessions' and targetResources/any(t: t/userPrincipalName eq '$userInput')" -Top 5
if ($auditLogs) {
Write-Host "Revocation events found in audit logs:"
$auditLogs | Format-Table -AutoSize
} else {
Write-Host "No revocation events found in the audit logs. Please ensure the revocation process completed successfully." -ForegroundColor Red
}
}
catch {
Write-Host "Failed to query audit logs for revocation events." -ForegroundColor Red
}
# Query the user's sign-in activity after revocation
try {
Write-Host "Querying the user's sign-in activity after revocation..."
$signInActivitiesAfter = Get-MgAuditLogSignIn -Filter "userPrincipalName eq '$userInput' or userId eq '$userInput'" -Top 1 |
Select-Object CreatedDateTime, Status, TokenIssuerType, ResourceDisplayName, ApplicationDisplayName, IPAddress
}
catch {
Write-Host "Failed to query sign-in activity after revocation for $userInput." -ForegroundColor Red
continue
}
$signInActivitiesAfter | Format-Table -AutoSize
# Verify if any new sign-ins occurred after revocation
if ($signInActivitiesBefore.CreatedDateTime -eq $signInActivitiesAfter.CreatedDateTime) {
Write-Host "No new sign-in detected after revocation. The user may still have valid access tokens for the session." -ForegroundColor Yellow
} else {
Write-Host "The user's sign-in status has changed. The revocation was successful." -ForegroundColor Green
}
# Skip user interaction when in Debug mode
if (-not $DebugMode) {
$moreUsers = Read-Host "Are there any more users to revoke? (Yes/No)"
if ($moreUsers -match "^(n|no)$") {
break
}
} else {
# Automatically set $moreUsers to "no" during Debug mode
$moreUsers = "no"
}
# Clear variables for the next user iteration
$userInput, $signInActivitiesBefore, $signInActivitiesAfter = $null, $null, $null
} until ($moreUsers -match "^(n|no)$")
Write-Host "Script execution completed." -ForegroundColor Green