Instantly share code, notes, and snippets.
Created
October 19, 2024 18:46
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save AlexanderHolmeset/ad2067a6653c62927b716cb4a0fc0241 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Parameters for the app registration | |
$ClientId = "XXXXXXXXXXXX" | |
$TenantId = "XXXXXXXXXXXX" | |
$ClientSecret = "XXXXXXXXXXXX" | |
# Convert the Client Secret to a SecureString | |
$SecureClientSecret = ConvertTo-SecureString -String $ClientSecret -AsPlainText -Force | |
# Create a PSCredential object with the Client ID and Secure Client Secret | |
$ClientSecretCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ClientId, $SecureClientSecret | |
# Connect to Microsoft Graph using the Tenant ID and Client Secret Credential | |
Connect-MgGraph -TenantId $TenantId -ClientSecretCredential $ClientSecretCredential | |
# Initialize the output array | |
$OutputData = @() | |
function Get-AllDriveItems { | |
param ( | |
[Parameter(Mandatory)] | |
[string]$DriveId, | |
[Parameter()] | |
[string]$ParentId, | |
[Parameter()] | |
[string]$CurrentPath = "" | |
) | |
$Items = @() | |
if ($ParentId) { | |
Write-Host "Processing folder with ParentId: $ParentId" -ForegroundColor Cyan | |
try { | |
$ParentItem = Get-MgDriveItem -DriveId $DriveId -DriveItemId $ParentId -ExpandProperty 'children' -ErrorAction Stop | |
$DriveItems = $ParentItem.Children | |
if($DriveItems) { | |
Write-Host "Found $($DriveItems.Count) child items in folder '$($ParentItem.Name)' (ParentId: $ParentId)" -ForegroundColor Green | |
} else { | |
Write-Host "No child items found in folder '$($ParentItem.Name)' (ParentId: $ParentId)" -ForegroundColor Yellow | |
} | |
} catch { | |
Write-Warning "Failed to get children for item ID '$ParentId'. Error: $_" | |
return $Items | |
} | |
} else { | |
Write-Host "Processing root folder" -ForegroundColor Cyan | |
try { | |
$RootItem = Get-MgDriveRoot -DriveId $DriveId -ExpandProperty 'children' -ErrorAction Stop | |
$DriveItems = $RootItem.Children | |
if($DriveItems) { | |
Write-Host "Found $($DriveItems.Count) items in root folder" -ForegroundColor Green | |
} else { | |
Write-Host "No items found in root folder" -ForegroundColor Yellow | |
} | |
} catch { | |
Write-Error "Failed to get root item and its children. Error: $_" | |
return $Items | |
} | |
} | |
if (-not $DriveItems) { | |
Write-Verbose "No items found at this level." | |
return $Items | |
} | |
foreach ($Item in $DriveItems) { | |
# Update the file path | |
if ($CurrentPath -eq "") { | |
$ItemPath = "/$($Item.Name)" | |
} else { | |
$ItemPath = "$CurrentPath/$($Item.Name)" | |
} | |
# Add the ItemPath property to the item | |
$Item | Add-Member -NotePropertyName 'ItemPath' -NotePropertyValue $ItemPath | |
$Items += $Item | |
Write-Host "Found item: $($Item.Name) (Id: $($Item.Id))" -ForegroundColor Green | |
if ($Item.Folder) { | |
Write-Host "Recursing into folder: $($Item.Name) (Id: $($Item.Id))" -ForegroundColor Cyan | |
if ($Item.Id) { | |
$Items += Get-AllDriveItems -DriveId $DriveId -ParentId $Item.Id -CurrentPath $ItemPath | |
} else { | |
Write-Warning "Item '$($Item.Name)' has a null ID and cannot be processed." | |
} | |
} | |
} | |
return $Items | |
} | |
# Get all users except the specified one | |
$excludedUser = "[email protected]" | |
# Retrieve all users except the excluded one | |
$users = Get-MgBetaUser -All -Filter "accountEnabled eq true" | Where-Object{$_.usertype -eq "Member"} | Where-Object { $_.UserPrincipalName -ne $excludedUser } | |
foreach ($user in $users) { | |
Write-Host "Processing user: $($user.DisplayName) <$($user.UserPrincipalName)>" -ForegroundColor Magenta | |
try { | |
# Get the user's default drive (OneDrive) | |
$drive = Get-MgUserDrive -UserId $user.Id -ErrorAction Stop | |
if ($drive) { | |
$driveId = $drive.Id | |
# Get all items in the user's OneDrive starting from the root | |
$AllItems = Get-AllDriveItems -DriveId $driveId | |
Write-Host "Total items retrieved for user $($user.DisplayName): $($AllItems.Count)" -ForegroundColor Green | |
foreach ($Item in $AllItems) { | |
Write-Host "Processing item: $($Item.Name) (Id: $($Item.Id))" -ForegroundColor Gray | |
# Get the permissions for the item | |
try { | |
$Permissions = Get-MgDriveItemPermission -DriveId $driveId -DriveItemId $Item.Id -All -ErrorAction Stop | |
} catch { | |
Write-Warning "Failed to get permissions for item '$($Item.Name)'. Error: $_" | |
continue | |
} | |
if (!$Permissions) { | |
Write-Host "No permissions found for item '$($Item.Name)'" -ForegroundColor Yellow | |
} else { | |
Write-Host "Found $($Permissions.Count) permissions for item '$($Item.Name)'" -ForegroundColor Green | |
} | |
foreach ($Permission in $Permissions) { | |
# Check if the permission is a link (shared link) | |
if ($Permission.Link) { | |
# Initialize PermissionType variable | |
$PermissionType = $null | |
# Check if the link scope is "organization" or "anonymous" | |
if ($Permission.Link.Scope -eq "organization") { | |
$PermissionType = "Everyone except external users" | |
} elseif ($Permission.Link.Scope -eq "anonymous") { | |
$PermissionType = "Anonymous" | |
} | |
if ($PermissionType) { | |
Write-Host "Item '$($Item.Name)' is shared with '$PermissionType'." -ForegroundColor Cyan | |
Write-Host "URL: $($Item.WebUrl)" -ForegroundColor Blue | |
# Create a custom object with the desired properties | |
$OutputObject = [PSCustomObject]@{ | |
UserPrincipalName = $user.UserPrincipalName | |
Name = $user.DisplayName | |
ItemName = $Item.Name | |
ItemUrl = $Item.WebUrl | |
FilePath = $Item.ItemPath | |
PermissionType = $PermissionType | |
} | |
# Add the object to the output array | |
$OutputData += $OutputObject | |
} | |
} else { | |
# Check if permission has roles and grantedTo identifying an anonymous share | |
if (($Permission.Roles -contains "read") -and ($Permission.GrantedToIdentities -eq $null) -and ($Permission.ShareId)) { | |
$PermissionType = "Anonymous" | |
Write-Host "Item '$($Item.Name)' has an anonymous share link." -ForegroundColor Cyan | |
Write-Host "URL: $($Item.WebUrl)" -ForegroundColor Blue | |
# Create a custom object with the desired properties | |
$OutputObject = [PSCustomObject]@{ | |
UserPrincipalName = $user.UserPrincipalName | |
Name = $user.DisplayName | |
ItemName = $Item.Name | |
ItemUrl = $Item.WebUrl | |
FilePath = $Item.ItemPath | |
PermissionType = $PermissionType | |
} | |
# Add the object to the output array | |
$OutputData += $OutputObject | |
} else { | |
Write-Host "Permission is not a link or not anonymous for item '$($Item.Name)'" -ForegroundColor Gray | |
} | |
} | |
} | |
} | |
} else { | |
Write-Host "User $($user.DisplayName) does not have a OneDrive provisioned." -ForegroundColor Yellow | |
} | |
} catch { | |
Write-Warning "Failed to process user $($user.DisplayName). Error: $_" | |
continue | |
} | |
} | |
# Now, process all SharePoint sites and their document libraries | |
Write-Host "Starting to process all SharePoint sites and their document libraries..." -ForegroundColor Magenta | |
try { | |
# Retrieve all SharePoint sites | |
$sites = Get-MgSite -All | Where-Object { $_.WebUrl -notlike "*personal*" } | |
} catch { | |
Write-Error "Failed to retrieve SharePoint sites. Error: $_" | |
exit | |
} | |
foreach ($site in $sites) { | |
Write-Host "Processing site: $($site.DisplayName) <$($site.WebUrl)>" -ForegroundColor Magenta | |
try { | |
# Get all document libraries (drives) in the site | |
$drives = Get-MgSiteDrive -SiteId $site.Id -ErrorAction Stop | |
foreach ($drive in $drives) { | |
Write-Host "Processing document library: $($drive.Name)" -ForegroundColor Cyan | |
$driveId = $drive.Id | |
# Get all items in the document library starting from the root | |
$AllItems = Get-AllDriveItems -DriveId $driveId | |
Write-Host "Total items retrieved in document library '$($drive.Name)': $($AllItems.Count)" -ForegroundColor Green | |
foreach ($Item in $AllItems) { | |
Write-Host "Processing item: $($Item.Name) (Id: $($Item.Id))" -ForegroundColor Gray | |
# Get the permissions for the item | |
try { | |
$Permissions = Get-MgDriveItemPermission -DriveId $driveId -DriveItemId $Item.Id -All -ErrorAction Stop | |
} catch { | |
Write-Warning "Failed to get permissions for item '$($Item.Name)'. Error: $_" | |
continue | |
} | |
if (!$Permissions) { | |
Write-Host "No permissions found for item '$($Item.Name)'" -ForegroundColor Yellow | |
} else { | |
Write-Host "Found $($Permissions.Count) permissions for item '$($Item.Name)'" -ForegroundColor Green | |
} | |
foreach ($Permission in $Permissions) { | |
# Check if the permission is a link (shared link) | |
if ($Permission.Link) { | |
# Initialize PermissionType variable | |
$PermissionType = $null | |
# Check if the link scope is "organization" or "anonymous" | |
if ($Permission.Link.Scope -eq "organization") { | |
$PermissionType = "Everyone except external users" | |
} elseif ($Permission.Link.Scope -eq "anonymous") { | |
$PermissionType = "Anonymous" | |
} | |
if ($PermissionType) { | |
Write-Host "Item '$($Item.Name)' is shared with '$PermissionType'." -ForegroundColor Cyan | |
Write-Host "URL: $($Item.WebUrl)" -ForegroundColor Blue | |
# Create a custom object with the desired properties | |
$OutputObject = [PSCustomObject]@{ | |
SiteUrl = $site.WebUrl | |
SiteName = $site.DisplayName | |
DocumentLibrary = $drive.Name | |
ItemName = $Item.Name | |
ItemUrl = $Item.WebUrl | |
FilePath = $Item.ItemPath | |
PermissionType = $PermissionType | |
} | |
# Add the object to the output array | |
$OutputData += $OutputObject | |
} | |
} else { | |
# Check if permission has roles and grantedTo identifying an anonymous share | |
if (($Permission.Roles -contains "read") -and ($Permission.GrantedToIdentities -eq $null) -and ($Permission.ShareId)) { | |
$PermissionType = "Anonymous" | |
Write-Host "Item '$($Item.Name)' has an anonymous share link." -ForegroundColor Cyan | |
Write-Host "URL: $($Item.WebUrl)" -ForegroundColor Blue | |
# Create a custom object with the desired properties | |
$OutputObject = [PSCustomObject]@{ | |
SiteUrl = $site.WebUrl | |
SiteName = $site.DisplayName | |
DocumentLibrary = $drive.Name | |
ItemName = $Item.Name | |
ItemUrl = $Item.WebUrl | |
FilePath = $Item.ItemPath | |
PermissionType = $PermissionType | |
} | |
# Add the object to the output array | |
$OutputData += $OutputObject | |
} else { | |
Write-Host "Permission is not a link or not anonymous for item '$($Item.Name)'" -ForegroundColor Gray | |
} | |
} | |
} | |
} | |
} | |
} catch { | |
Write-Warning "Failed to process site $($site.DisplayName). Error: $_" | |
continue | |
} | |
} | |
# Output or process the collected data as needed | |
# For example, output to console | |
$OutputData | |
# Optionally, export to CSV | |
# $OutputData | Export-Csv -Path 'C:\Path\To\Output.csv' -NoTypeInformation |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment