FastTrack/scripts/Get-AuditGuestTeams/Get-AuditGuestTeams.ps1

245 строки
13 KiB
PowerShell

<#
.Description
This Script function will create a report that will help IT PROs to Monitor and Audit Guest users. The report generated by the script will show the following details:
1. How many Microsoft 365 Groups contains Guest accounts added as member and to list those Guest accounts and corresponding Group;
2. Sign-in logs in Azure Active Directory - Audits if the Guest accounts already Sign-in in the tenant, if the Guest user accepted the invite and also the last time they Signd-In in the tenant;
3. List what is the current Azure B2B Collaboration restrictions configured;
Once you run the script, you will get a report in the Shell/Screen or you can choose to be exported to a TXT/CSV file;
Both ways of executing the script:
Getting data on Screen: ".\Get-AuditGuestTeams -ExportMethod onScreen"
Getting data on a TXT file and CSV: ".\Get-AuditGuestTeams -ExportMethod Report"
Important Detail: The script will require AzureADPreview module. The script will remove the old modules and install the new and needed modules for you;
.Requirements
- This Script function needs AzureADPreview module version "2.0.2.138" or higher installed - the script will install/update it for you;
- If you have AzureAD Module installed, this module must be uninstalled first - the script will uninstall it for you;
- Administrator rights to Install/Uninstall Modules;
- Administrator rights in the tenant to list Microsoft 365 Groups/Users and Azure Sign-In logs;
- You must set ExecutionPolicy to allow running the script. Example: Set-ExecutionPolicy -ExecutionPolicy Unrestricted
.PARAMETER: "ExportMethod"
- This parameter will define the way the outcome will be displayed: On Shell/Screen or saved into the Downloads folder of the user profile;
.PARAMETER: "ExportFolderPath"
- Folder path where files will get exported. By Default will be the user's Downloads folder.
.EXAMPLE:
- ".\Get-AuditGuestTeams -ExportMethod onScreen"
- ".\Get-AuditGuestTeams -ExportMethod Report"
- ".\Get-AuditGuestTeams -ExportMethod Report" -ExportFolderPath "C:\Temp"
.Version: V1.1
.Author: Tiago Roxo
.Contributions: Agustin Gallegos
#>
#FUNCTION PARAMS
param(
[Parameter(Position=0,ParameterSetName='ExportMethod')]
[validateset("onScreen","Report")]
[string] $ExportMethod = "onScreen",
[string] $ExportFolderPath = "$env:USERPROFILE\Downloads"
)
cls
#VARs
$details = @()
$number = 0
$InactiveDays = "30"
$startDate = (Get-Date).AddDays("-$InactiveDays").ToString('yyyy-MM-dd')
$endDate = (Get-Date).ToString('yyyy-MM-dd')
#Auto Checking/Install/Uninstall/Update Azure AD Modules
Write-Host "Checking if Azure AD Preview Module is installed on the System..." -BackgroundColor White -ForegroundColor Black
try{
Import-Module AzureAdPreview -ErrorAction Stop
$moduleVersion = Get-module -Name AzureAdPreview
if($moduleVersion.Version.ToString() -ge "2.0.2.138"){
}else{
Write-Host "Azure AD Preview Module Module not updated. Current Version: " $moduleVersion.Version.ToString() -BackgroundColor Yellow -ForegroundColor Black
Write-Host "Updating..." -BackgroundColor Yellow -ForegroundColor Black
Update-Module AzureAdPreview
$moduleVersion = Get-module -Name AzureAdPreview
}
Write-Host "Azure AD Preview Module Module is Installed/Updated. Current Version: "$moduleVersion.Version.ToString() -BackgroundColor Green -ForegroundColor Black
Write-Host "Connecting now to O365 services..." -BackgroundColor Green -ForegroundColor Black
try{Connect-AzureAD -Confirm:$False}catch{break}
}catch{
if(Get-InstalledModule -name "Azuread" -ErrorAction SilentlyContinue){
Write-Host "We found AzureAD module installed on the system. To install AzureAdPreview Module, we need to uninstall AzureAD Module first." -BackgroundColor Yellow -ForegroundColor Black
Read-Host "`nPress any key to Uninstall now AzureAd Module or stop the execution of the script now!"
Get-Package -Name AzureAd -AllVersions | Uninstall-Package | Out-Null
}
Write-Host "Azure AD Preview Module Module not Installed on the system. Install the Module before proceed!" -BackgroundColor Red -ForegroundColor Black
Read-Host "`nPress any key to Install AzureAdPreview Module or stop the execution of the script now!"
Install-Module AzureADPreview -Confirm:$False -Force
Import-Module AzureADPreview
Write-Host "Connecting now to O365 services..." -BackgroundColor Green -ForegroundColor Black
try{Connect-AzureAD -Confirm:$False}catch{break}
}
#Scan starts here
Write-Host "Loading now Azure Sign-In Logs and O365 Groups/Guests..." -BackgroundColor white -ForegroundColor Black
#Creating a list of Guest Users
$guestUsers = @()
$guestUsers = Get-AzureADUser | Where-Object { $_.UserType -eq 'Guest'}
#Auditing SignIn Log's for the Guest Accounts
$loggedOnUsers = @()
foreach($m in $guestUsers){
$MAIL = $m.Mail
$loggedOnUsers += Get-AzureADAuditSignInLogs -top 1000 -Filter "UserPrincipalName eq '$MAIL'"
}
#Creating a list of Microsoft 365 Groups
$M365Groups = @()
$M365Groups = Get-AzureADGroup
#Getting Tenant Details
$tenantName = @()
$tenantName = Get-AzureADTenantDetail
#Creating an List of existing Guest users in the tenant
$CSVGuestUsersAudit = @()
$CSVGuestUsersInGroups = @()
#Getting Tenant Azure B2B Policy
$B2BManagementPolicy = Get-AzureADPolicy | ? {$_.DisplayName -eq "B2BManagementPolicy" } | Select -ExpandProperty Definition
$BlockedDomains = @()
$AlloweddDomains = @()
try {$BlockedDomains = ($B2BManagementPolicy | ConvertFrom-Json).B2BManagementPolicy.InvitationsAllowedAndBlockedDomainsPolicy.BlockedDomains}catch{}
try {$AlloweddDomains = ($B2BManagementPolicy | ConvertFrom-Json).B2BManagementPolicy.InvitationsAllowedAndBlockedDomainsPolicy.AllowedDomains}catch{}
#List the tenant Details
$details += "`n____________________________________________"
$details += "`nTenant Details:"
$details += "`nName: " + $tenantName.DisplayName
$details += "`nTenantId: " + $tenantName.ObjectId
$details += "`n____________________________________________"
#Scan all the Microsoft 365 Groups and the list the guest that are part of the Groups
$details += "`n" + "Microsoft 365 Groups Details:"
$details += "`n" + ($M365Groups).Count + " Microsoft 365 Groups Found in the tenant."
foreach($i in $M365Groups)
{
$guestuser = @()
$guestuser = Get-AzureADGroupMember -ObjectId $i.ObjectId -All $true | Where-Object { $_.UserType -eq 'Guest'}
if ($guestuser)
{
$number = $number + 1
}
}
$details += "`n" + $number + " Microsoft 365 Groups Found in the tenant with Guests invited."
#$details += "`n____________________________________________"
foreach($i in $M365Groups)
{
$guestUser = Get-AzureADGroupMember -ObjectId $i.ObjectId -All $true | Where-Object { $_.UserType -eq 'Guest'}
if ($guestUser)
{
$details += "`n----------------"
$details += "`nGroup Name: " + $i.DisplayName
$details += "`n" + "Group Guest Details: " + ($guestUser).count + " Guest Users Found in the M365 Group"
foreach($o in $guestUser){
$auditUser = $loggedOnUsers | where UserPrincipalName -eq $o.mail | select * -First 1
try {
$details += "`n-> " + $auditUser.UserDisplayName + " | " + $auditUser.UserPrincipalName + " | " + "Last SignIn Time: " + $auditUser.CreatedDateTime.SubString(0,10)
$CSVGuestUsersInGroups += New-Object -TypeName psobject -Property @{GroupName=$i.DisplayName; DisplayName=$o.DisplayName; Mail=$o.mail; LastSignInTime=$auditUser.CreatedDateTime.SubString(0,10)}
}catch{
$details += "`n-> " + $o.DisplayName + " | " + $o.mail + " | " + "Last SignIn Time: No records found"
$CSVGuestUsersInGroups += New-Object -TypeName psobject -Property @{GroupName=$i.DisplayName; DisplayName=$o.DisplayName; Mail=$o.mail; LastSignInTime="No records found"}
}
}
#$details += "`n----------------"
}else{
#$details += "`n----------------"
#$details += "`nGroup Name: " + $i.DisplayName
#$details += "`n0 Guest users found in the M365 Group"
}
}
#Scan/Audit All Guest Users that's never Sign-In and/or that haven't Sign-In for more than $InactiveDays days
$details += "`n____________________________________________"
$details += "`nTotal Guest Users configured in the Tenant: " + ($guestUsers).Count
$details += "`nTenant Guest Users details:"
$details += "`n----------------"
foreach($t in $guestUsers){
try{
$newtest = $loggedOnUsers | where UserPrincipalName -eq $t.mail | select createdDateTime -First 1
$newdate =@()
$newdate = $newtest.CreatedDateTime.SubString(0,10)
$newdate.ToString("yyyy-MM-dd")
}catch{}
if($newtest -eq $null){
$details += "`n-> [!WARNING]`t " + $t.Displayname + " | " + $t.mail + " | Invite Status: " + $t.UserState + " | Last SignIn Time: No records found | [Possible Stale user]"
$CSVGuestUsersAudit += New-Object -TypeName psobject -Property @{DisplayName=$t.Displayname; Mail=$t.mail; InviteStatus=$t.UserState ; LastSignInTime="No records found" ; obs= "[Possible Stale user]"}
}elseif($newdate -le $startDate){
$details += "`n-> [!WARNING]`t " + $t.Displayname + " | " + $t.mail + " | Invite Status: " + $t.UserState + " | Last SignIn Time: $newdate | [no Sign-In details for more than $InactiveDays days!][Possible Stale user]"
$CSVGuestUsersAudit += New-Object -TypeName psobject -Property @{DisplayName=$t.Displayname; Mail=$t.mail; State=$t.InviteStatus ; LastSignInTime=$newdate; Obs="[no Sign-In details for more than $InactiveDays days!][Possible Stale user]"}
}elseif($newtest){
$details += "`n-> " + $t.Displayname + " | " + $t.mail + " | Invite Status: " + $t.UserState + " | Last SignIn Time: " + $newdate
$CSVGuestUsersAudit += New-Object -TypeName psobject -Property @{DisplayName=$t.Displayname; Mail=$t.mail; State=$t.InviteStatus ; LastSignInTime=$newdate; Obs=""}
}
}
#List Azure B2B Collaboration restrictions
$details += "`n----------------"
$details += "`nAzure B2B Collaboration restrictions:"
if ($BlockedDomains -ne $null){
$details += "`nAzure B2B Policy is configured to 'Deny invitations to the specified domains'."
$details += "`nAzure B2B Blocked Domains: " + $BlockedDomains
}elseif($AlloweddDomains -ne $null){
$details += "`nAzure B2B Policy is configured to 'Allow invitations only to the specified domains (most restrictive)'."
$details += "`nAzure B2B Allowed Domains: " + $AlloweddDomains
}else{
$details += "`nAzure B2B Policy is configured to 'Allow invitations to be sent to any domain (most inclusive)'."
}
$details += "`n____________________________________________"
$details += "`nReport Generated on: " + (Get-Date)
$details += "`n____________________________________________"
#Export information to the screen or file
if($ExportMethod -eq "onScreen"){
Write-Host $details
Write-Host "If you wish to save the outcome to a file, run the following cmdlet: .\Get-AuditGuestTeams -ExportMethod Report"
}elseif($ExportMethod -eq "Report"){
# Determining if 'Downloads' folder is in the user's profile folder, or under Onedrive mapped folders.
if ( -not(Test-Path $ExportFolderPath) ){
if ( Test-Path "$env:OneDriveCommercial\Downloads"){
$ExportFolderPath = "$env:OneDriveCommercial\Downloads"
}
else{
Write-Host "'Downloads' folder could not be located. Please re-run the script and specify the parameter 'ExportFolderPath' with a custom folder"
}
}
$fileName = "ReportAuditGuestTeams_"+ (Get-Date).ToString('yyyy-MM-dd') +".txt"
$file = "$ExportFolderPath\$fileName"
$details | Out-File -FilePath $file -Force
$fileName = "CSVGuestUsersInGroups_"+ (Get-Date).ToString('yyyy-MM-dd') +".csv"
$fileCSV1 = "$ExportFolderPath\$fileName"
$CSVGuestUsersInGroups | Select-Object -Property GroupName,DisplayName,Mail,LastSignInTime | Export-Csv -Path $fileCSV1 -NoTypeInformation
$fileName = "CSVGuestUsersAudit_"+ (Get-Date).ToString('yyyy-MM-dd') +".csv"
$fileCSV2 = "$ExportFolderPath\$fileName"
$CSVGuestUsersAudit | Select-Object -Property DisplayName,Mail,InviteStatus,LastSignInTime,obs | Export-Csv -Path $fileCSV2 -NoTypeInformation
Write-Host "`nAll 3 files will be stored in the following location:" $ExportFolderPath -BackgroundColor Green -ForegroundColor Black
Write-Host "`Opening the files..." -BackgroundColor Green -ForegroundColor Black
start notepad $file
start excel $fileCSV1
start excel $fileCSV2
}
Read-Host "Press Enter Exit"