diff options
| author | Pascal Dulieu <pascal@dulieu.uk> | 2025-05-20 15:47:26 +0100 |
|---|---|---|
| committer | Pascal Dulieu <pascal@dulieu.uk> | 2025-05-20 15:47:26 +0100 |
| commit | 4fe1417944a536acf3fcf5aa881a6a99fc26c16b (patch) | |
| tree | a644843401e1dc40028b8223f32eb30c5079dab4 | |
Script, templates & README
| -rw-r--r-- | README.md | 44 | ||||
| -rw-r--r-- | T2R.ps1 | 59 | ||||
| -rw-r--r-- | remote-template.conf | 13 | ||||
| -rw-r--r-- | union-template.conf | 3 |
4 files changed, 119 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..fab25bb --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# Teams to rclone + +powershell script to collect all the drive_ids in sharepoint associated to a team and create a union mount. Read only permissions for creating local backups and/or archives + +## Why? + +Becuase microsoft dont like to make things easy and create sharepoint subsites for private and shared teams channels within a team + +## Setup + +1. Create an app in the app registrations section in azure. portal.azure.com > App registrations > New registration (if you dont already have an app) +2. Name the app, leave everything as default. +3. Once the app has been made make note of the Application (client) ID and Directory (tennant) ID +4. Go to Certificates & Secrets > Client secrets and create a new client secret, set the expire and click add +5. Once it has been generated make a note of the Value, once you change page that will be stared out and you wont be able to see it again. +6. In your T2R.ps1 set the `tennantId`, `clientID` and `client secret (Value)` +7. in the remote-template.conf set the `client ID`, `client secret (value)` and `tennantID` +8. Go to `API permissions > Add a permission > Microsoft Graph > Application permissions` and add the below permissions + +```plain +Channel.ReadBasic.All +Directory.Read.All +Files.Read.All +Group.Read.All +Sites.Read.All +Team.ReadBasic.All +``` + +9. Once those have been added go to `Add a permission > Sharepoint > Application permissions` and add the below permission + +```plain +Sites.Read.All +``` + +1. Once the permissions have been set and your remote-template.conf and the top 2 lines of the T2R.ps1 is filled in, run T2R.ps1 and enter your team name +2. Wait a few seconds for it to do its thing and you should see rclone.conf show up +3. run `rclone lsd --config ./rclone TEAM_NAME_union:` to see a list of the root folders for the team it has pulled + +## Usage + +- Run the script +- Enter your team name when it asks +- Wait +- Run `rclone lsd --config ./rclone TEAM_NAME_union:` when the script is finished @@ -0,0 +1,59 @@ +$tenantId = "00000000-0000-0000-0000-000000000000" +$clientID = "00000000-0000-0000-0000-000000000000" +$clientSecret = (ConvertTo-SecureString "CLIENT_SECRET_VALUE" -AsPlainText -Force ) +$Scope = "https://graph.microsoft.com/.default" +$authToken = Get-MsalToken -ClientId $clientID -ClientSecret $clientSecret -TenantId $tenantId -Scopes $Scope + +$TeamsTeam = Read-Host "Enter team name" + +$Headers = @{ + "Authorization" = "Bearer $($authToken.AccessToken)" + "Content-type" = "application/json" +} + +$allTeams = @() +$aadTeams = (Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/teams/" -Headers $Headers -Method Get -ContentType "application/json") +$allTeams += $aadTeams.value +if ($aadTeams.'@odata.nextLink') { + do { + $aadTeams = (Invoke-RestMethod -Uri $aadTeams.'@odata.nextLink' -Headers $Headers -Method Get -ContentType "application/json") + $allTeams += $aadTeams.value + } until (!$aadTeams.'@odata.nextLink') +} +$aadTeams = $allTeams + +$channels = [System.Collections.ArrayList]::New() + +foreach ($teams in $aadTeams) { + if ($teams.displayName -like "$($TeamsTeam)*") { + $apiUri = "https://graph.microsoft.com/v1.0/teams/$($teams.id)/channels" + $Team = Invoke-RestMethod -Headers $Headers -Uri $apiUri -Method GET + $channelList = $Team.Value + foreach ($channel in $channelList) { + $channelFolder = Invoke-RestMethod -Headers $Headers -Uri "https://graph.microsoft.com/v1.0/teams/$($teams.id)/channels/$($channel.id)/filesFolder" -Method GET + $DriveID = $channelFolder.parentReference.driveId + $displayName = $channelFolder.name -replace " ", "_" -replace ",", "" + $Result = [PSCustomObject]@{ + displayName = $displayName + driveID = $DriveID + membershipType = $channel.membershipType + teamName = $teams.displayName + } + [void]$channels.Add($Result) + } + } +} + +$uniqueDrives = $channels | Sort-Object -Property driveID -Unique | Select-Object displayName, driveID, membershipType, teamName +$uniqueDrives | ForEach-Object { if ($_.membershipType -eq 'standard') { $_.displayName = $_.teamName -replace " ", "_" } } +foreach ($drive in $uniqueDrives) { + $config = Get-Content -Path ./remote-template.conf -Raw + $remote = $config -f $drive.displayName, $drive.driveID + Add-Content -Value $remote -Path ./rclone.conf +} + +$teamNames = $($uniqueDrives.displayName -join [Environment]::NewLine) -replace "\n", ": " +$teamNames = $teamNames + ":" +$union = Get-Content -Path ./union-template.conf -Raw +$unionConf = $union -f "$($channels[0].teamName)_union", $teamNames +Add-Content -Value $unionConf -Path ./rclone.conf
\ No newline at end of file diff --git a/remote-template.conf b/remote-template.conf new file mode 100644 index 0000000..8918da9 --- /dev/null +++ b/remote-template.conf @@ -0,0 +1,13 @@ +[{0}] +type = onedrive +drive_id = {1} +drive_type = documentLibrary +client_id = +client_secret = +tenant = +client_credentials = true +access_scopes = Files.Read Files.Read.All Sites.Read.All offline_access +link_scope = organization +auth_url = https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize +token_url = https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token + diff --git a/union-template.conf b/union-template.conf new file mode 100644 index 0000000..5920179 --- /dev/null +++ b/union-template.conf @@ -0,0 +1,3 @@ +[{0}] +type = union +upstreams = {1}
\ No newline at end of file |
