aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPascal Dulieu <pascal@dulieu.uk>2025-05-20 15:47:26 +0100
committerPascal Dulieu <pascal@dulieu.uk>2025-05-20 15:47:26 +0100
commit4fe1417944a536acf3fcf5aa881a6a99fc26c16b (patch)
treea644843401e1dc40028b8223f32eb30c5079dab4
Script, templates & README
-rw-r--r--README.md44
-rw-r--r--T2R.ps159
-rw-r--r--remote-template.conf13
-rw-r--r--union-template.conf3
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
diff --git a/T2R.ps1 b/T2R.ps1
new file mode 100644
index 0000000..288b4ee
--- /dev/null
+++ b/T2R.ps1
@@ -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