-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAudit-ExternalUserAccess.ps1
More file actions
127 lines (105 loc) · 4.09 KB
/
Audit-ExternalUserAccess.ps1
File metadata and controls
127 lines (105 loc) · 4.09 KB
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
<#
.SYNOPSIS
Audits external (guest) user access across Microsoft Teams, SharePoint Online, and Microsoft 365 Groups.
.DESCRIPTION
This script connects to Microsoft Graph and Microsoft Teams to identify guest users and where they have
access:
- Teams membership
- Microsoft 365 Group membership
- (Optional future extension) SharePoint site sharing links or direct access
It can optionally filter guest users by inactivity (no sign-in for X days), and exports results to Excel
with one sheet per resource type.
.PARAMETER InactiveDays
Optional. Only include guest users whose last sign-in was more than X days ago.
.PARAMETER OutputPath
Optional. Directory to save the Excel file. Defaults to "C:\Scripts".
.EXAMPLE
.\Audit-ExternalUserAccess.ps1 -InactiveDays 90
.EXAMPLE
.\Audit-ExternalUserAccess.ps1 -OutputPath "D:\Reports"
.NOTES
Requires:
- Microsoft.Graph module (Teams, Users, Groups)
- MicrosoftTeams module
- ImportExcel module
- Microsoft Graph permissions: Directory.Read.All, Group.Read.All, Reports.Read.All
#>
[CmdletBinding()]
param (
[int]$InactiveDays,
[string]$OutputPath = "C:\Scripts"
)
# Validate modules
foreach ($module in @("Microsoft.Graph", "MicrosoftTeams", "ImportExcel")) {
if (-not (Get-Module -ListAvailable -Name $module)) {
Install-Module $module -Scope CurrentUser -Force
}
}
Import-Module Microsoft.Graph.Users
Import-Module Microsoft.Graph.Groups
Import-Module Microsoft.Graph.Reports
Import-Module MicrosoftTeams
Import-Module ImportExcel
# Connect to Graph and Teams
Connect-MgGraph -Scopes "Directory.Read.All", "Group.Read.All", "User.Read.All", "Reports.Read.All"
Select-MgProfile -Name beta
Connect-MicrosoftTeams
$cutoff = if ($PSBoundParameters.ContainsKey('InactiveDays')) {
(Get-Date).AddDays(-$InactiveDays)
} else {
$null
}
$guests = Get-MgUser -Filter "userType eq 'Guest'" -All -Property Id, DisplayName, Mail, SignInActivity, UserPrincipalName
if ($cutoff) {
$guests = $guests | Where-Object {
$lastSignIn = $_.SignInActivity.LastSignInDateTime
-not $lastSignIn -or ($lastSignIn -lt $cutoff)
}
}
# Audit Teams access
$teamsData = @()
foreach ($user in $guests) {
try {
$teams = Get-TeamUser -User $user.UserPrincipalName -ErrorAction SilentlyContinue
foreach ($team in $teams) {
$teamsData += [PSCustomObject]@{
UserPrincipalName = $user.UserPrincipalName
DisplayName = $user.DisplayName
LastSignIn = $user.SignInActivity.LastSignInDateTime
TeamName = $team.DisplayName
Role = $team.Role
}
}
} catch {}
}
# Audit Microsoft 365 Group membership
$groupData = @()
$allGroups = Get-MgGroup -Filter "groupTypes/any(c:c eq 'Unified')" -All -Property Id, DisplayName
foreach ($group in $allGroups) {
try {
$members = Get-MgGroupMember -GroupId $group.Id -All | Where-Object { $_.AdditionalProperties.userType -eq 'Guest' }
foreach ($member in $members) {
$user = $guests | Where-Object { $_.Id -eq $member.Id }
if ($user) {
$groupData += [PSCustomObject]@{
GroupName = $group.DisplayName
UserPrincipalName = $user.UserPrincipalName
DisplayName = $user.DisplayName
LastSignIn = $user.SignInActivity.LastSignInDateTime
}
}
}
} catch {}
}
# Prepare Excel output
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$outputFile = Join-Path $OutputPath "ExternalUserAccess_$timestamp.xlsx"
if ($teamsData.Count -gt 0) {
$teamsData | Export-Excel -Path $outputFile -WorksheetName "TeamsAccess" -AutoSize -AutoFilter -FreezeTopRow -BoldTopRow
}
if ($groupData.Count -gt 0) {
$groupData | Export-Excel -Path $outputFile -WorksheetName "M365GroupAccess" -AutoSize -AutoFilter -FreezeTopRow -BoldTopRow
}
Write-Host "Report saved to: $outputFile" -ForegroundColor Green
Disconnect-MgGraph
Disconnect-MicrosoftTeams