diff --git a/OneDrive-AutoMapper.ps1 b/OneDrive-AutoMapper.ps1 index 43219da..015fccb 100644 --- a/OneDrive-AutoMapper.ps1 +++ b/OneDrive-AutoMapper.ps1 @@ -23,7 +23,11 @@ For this script the following permissions must be assigned during the app regist Log file output to users %TEMP% folder (%temp%\OneDrive-AutoMapper_log.txt) .COPYRIGHT +Source: https://github.com/mardahl/OneDrive-AutoMapper + @michael_mardahl on Twitter (new followers appreciated) / https://www.iphase.dk +Modifications by cybermoloch@magitekai.com (@cyber_moloch on Twitter), https://github.com/cybermoloch + Some parts of the authentication functions have been heavily modified from their original state, initially provided by Microsoft as samples of Accessing Intune. Licensed under the MIT license. Please credit me if you fint this script useful and do some cool things with it. @@ -33,35 +37,15 @@ N.B. This is an updated version of my previous script "AutoMapUnifiedGroupDrives Use at your own risk, no warranty given! #> -#################################################### -# -# CONFIG -# -#################################################### - - #Required credentials - Get the client_id and client_secret from the app when creating it i Azure AD - $client_id = "88d56j01-856ja-tjdj-8166-9sdju56j56j" #App ID - $client_secret = "i3stryjtyjdtyjdtyz1Xhl:" #API Access Key Password - #Idealy you would secure this secret in some way, instead of having it here in clear text. - - #tenant_id can be read from the azure portal of your tenant (a.k.a Directory ID, shown when you do the App Registration) - $tenant_id = "1jd56j54-cj6d565-4d56je-9jd54-118f5d6j8" #Directory ID - - #Set to $true to delete leftover folders from previous syncs (if false, nothing wil be synced if the destination folder already exists) - $CleanupLeftovers = $true - #Enabling cleanup will also ensure that a folder get's re-added if a user removes it. - - #Seconds to wait between each mount - not having a delay can cause OneDrive to barf when adding multiple sync folders at once. (default: 3 sec) - $waitSec = 3 - - #List of site names to exclude from being added to OneDrive - #Just add the name of the site to this array, and remove the dummy entries. - $excludeSiteList = @("DummyDumDum","Blankorama","Nonenana") - - #Special params for some advanced modification - $global:sharedDocumentsName = "Shared Documents" #change if for some reason your tenant displays the shared documents folders with another name - $global:graphApiVersion = "v1.0" #should be "v1.0" - $VerbosePreference = "Continue" #change to SilentlyContinue to dial down the output. +param +( + [Parameter(Mandatory = $true)] + $TenantID, + [Parameter(Mandatory = $true)] + $ClientID, + [Parameter(Mandatory = $true)] + $ClientSecret +) #################################################### # @@ -85,15 +69,15 @@ Function Get-AuthToken { param ( - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $TenantID, - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $ClientID, - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $ClientSecret ) - try{ + try { # Define parameters for Microsoft Graph access token retrieval $resource = "https://graph.microsoft.com" $authority = "https://login.microsoftonline.com/$TenantID" @@ -104,35 +88,34 @@ Function Get-AuthToken { $response = Invoke-RestMethod -Uri $tokenEndpointUri -Body $content -Method Post -UseBasicParsing - Write-Host "Got new Access Token!" -ForegroundColor Green - Write-Host + Write-Information "Got new Access Token!" # If the accesstoken is valid then create the authentication header - if($response.access_token){ + if ($response.access_token) { - # Creating header for Authorization token + # Creating header for Authorization token - $authHeader = @{ - 'Content-Type'='application/json' - 'Authorization'="Bearer " + $response.access_token - 'ExpiresOn'=$response.expires_on + $authHeader = @{ + 'Content-Type' = 'application/json' + 'Authorization' = "Bearer " + $response.access_token + 'ExpiresOn' = $response.expires_on } - return $authHeader + return $authHeader } - else{ + else { - Write-Error "Authorization Access Token is null, check that the client_id and client_secret is correct..." - break + Write-Error "Authorization Access Token is null, check that the client_id and client_secret is correct..." + break } } - catch{ + catch { - FatalWebError -Exeption $_.Exception -Function "Get-AuthToken" + Out-FatalWebError -Exception $_.Exception -Function "Get-AuthToken" } @@ -154,11 +137,21 @@ Function Get-ValidToken { NAME: Get-ValidToken #> + param + ( + [Parameter(Mandatory = $true)] + $TenantID, + [Parameter(Mandatory = $true)] + $ClientID, + [Parameter(Mandatory = $true)] + $ClientSecret + ) + #Fixing client_secret illegal char (+), which do't go well with web requests - $client_secret = $($client_secret).Replace("+","%2B") + $ClientSecret = $($ClientSecret).Replace("+", "%2B") # Checking if authToken exists before running authentication - if($global:authToken){ + if ($global:authToken) { # Get current time in (UTC) UNIX format (and ditch the milliseconds) $CurrentTimeUnix = $((get-date ([DateTime]::UtcNow) -UFormat +%s)).split((Get-Culture).NumberFormat.NumberDecimalSeparator)[0] @@ -166,18 +159,16 @@ Function Get-ValidToken { # If the authToken exists checking when it expires (converted to minutes for readability in output) $TokenExpires = [MATH]::floor(([int]$authToken.ExpiresOn - [int]$CurrentTimeUnix) / 60) - if($TokenExpires -le 0){ + if ($TokenExpires -le 0) { - Write-Host "Authentication Token expired" $TokenExpires "minutes ago! - Requesting new one..." -ForegroundColor Green - $global:authToken = Get-AuthToken -TenantID $tenant_id -ClientID $client_id -ClientSecret $client_secret + Write-Information ("Authentication Token expired " + $TokenExpires + " minutes ago! - Requesting new one...") + $global:authToken = Get-AuthToken -TenantID $TenantID -ClientID $ClientID -ClientSecret $ClientSecret - } - else{ - - Write-Host "Using valid Authentication Token that expires in" $TokenExpires "minutes..." -ForegroundColor Green - Write-Host + } + else { - } + Write-Information ("Using valid Authentication Token that expires in " + $TokenExpires + " minutes...") + } } @@ -186,7 +177,7 @@ Function Get-ValidToken { else { # Getting the authorization token - $global:authToken = Get-AuthToken -TenantID $tenant_id -ClientID $client_id -ClientSecret $client_secret + $global:authToken = Get-AuthToken -TenantID $TenantID -ClientID $ClientID -ClientSecret $ClientSecret } @@ -194,7 +185,7 @@ Function Get-ValidToken { #################################################### -Function FatalWebError { +Function Out-FatalWebError { <# .SYNOPSIS @@ -202,38 +193,37 @@ Function FatalWebError { .DESCRIPTION Unwraps most of the exeptions details and gets the response codes from the web request, afterwards it stops script execution. .EXAMPLE - FatalWebError -Exception $_.Exception -Function "myFunctionName" + Out-FatalWebError -Exception $_.Exception -Function "myFunctionName" Shows the error message and the name of the function calling it. .NOTES - NAME: FatalWebError + NAME: Out-FatalWebError #> param ( - [Parameter(Mandatory=$true)] - $Exeption, # Should be the execption trace, you might try $_.Exception - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] + $Exception, # Should be the exception trace, you might try $_.Exception + [Parameter(Mandatory = $true)] $Function # Name of the function that calls this function (for readability) ) -#Handles errors for all my Try/Catch'es + #Handles errors for all my Try/Catch'es - $errorResponse = $Exeption.Response.GetResponseStream() - $reader = New-Object System.IO.StreamReader($errorResponse) - $reader.BaseStream.Position = 0 - $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); - Write-Host "Failed to execute Function : $Function" -f Red - Write-Host "Response content:`n$responseBody" -f Red - Write-Host "Request to $Uri failed with HTTP Status $($Exeption.Response.StatusCode) $($Exeption.Response.StatusDescription)" -f Red - write-host - break + $errorResponse = $Exeption.Response.GetResponseStream() + $reader = New-Object System.IO.StreamReader($errorResponse) + $reader.BaseStream.Position = 0 + $reader.DiscardBufferedData() + $responseBody = $reader.ReadToEnd(); + Write-Error "Failed to execute Function : $Function" + Write-Error "Response content:`n$responseBody" + Write-Error "Request to $Uri failed with HTTP Status $($Exception.Response.StatusCode) $($Exception.Response.StatusDescription)" + break } #################################################### -Function Get-UnifiedGroups(){ +Function Get-UnifiedGroups() { <# .SYNOPSIS @@ -249,7 +239,7 @@ Function Get-UnifiedGroups(){ param ( - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $UPN ) @@ -258,23 +248,17 @@ Function Get-UnifiedGroups(){ $uri = "https://graph.microsoft.com/$graphApiVersion/$Resource" try { - Return (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value - } catch { - - FatalWebError -Exeption $_.Exception -Function "Get-UnifiedGroups" - + # Out-FatalWebError -Exception $_.Exception -Function "Get-UnifiedGroups" } - - } #################################################### -Function Get-UnifiedGroupDrive(){ +Function Get-UnifiedGroupDrive() { <# .SYNOPSIS @@ -290,7 +274,7 @@ Function Get-UnifiedGroupDrive(){ param ( - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $GroupID ) @@ -305,7 +289,7 @@ Function Get-UnifiedGroupDrive(){ catch { - FatalWebError -Exeption $_.Exception -Function "Get-UnifiedGroupDrive" + Out-FatalWebError -Exception $_.Exception -Function "Get-UnifiedGroupDrive" } @@ -314,7 +298,7 @@ Function Get-UnifiedGroupDrive(){ ##################################################### -Function Get-UnifiedGroupDriveList(){ +Function Get-UnifiedGroupDriveList() { <# .SYNOPSIS @@ -331,7 +315,7 @@ Function Get-UnifiedGroupDriveList(){ param ( - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $GroupID ) @@ -347,7 +331,7 @@ Function Get-UnifiedGroupDriveList(){ catch { - FatalWebError -Exeption $_.Exception -Function "Get-GroupDriveListID" + Out-FatalWebError -Exception $_.Exception -Function "Get-GroupDriveListID" } @@ -356,7 +340,7 @@ Function Get-UnifiedGroupDriveList(){ ##################################################### -Function Get-CurrentUserODInfo(){ +Function Get-CurrentUserODInfo() { <# .SYNOPSIS @@ -364,14 +348,14 @@ Function Get-CurrentUserODInfo(){ .DESCRIPTION The function parses the HKCU registry hive, matching certain propertied with the specified TenantID - Returning userEmail and UserFolder if a match is found .EXAMPLE - Get-CurrentUserODInfo -TennantID "00000000-0000000-0000000" + Get-CurrentUserODInfo -TenantID "00000000-0000000-0000000" .NOTES NAME: Get-CurrentUserODInfo #> param ( - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $TenantID ) @@ -380,7 +364,7 @@ Function Get-CurrentUserODInfo(){ $ODFBaccounts = Get-ChildItem -Path $ODFBregPath #resetting ODUserEmail in case script is run multiple times in same session - $ODuserEmail -eq $null + $ODuserEmail = $null #Find the correct OneDrive Account for this tennant, in case the user has multiple OD accounts. foreach ($Account in $ODFBaccounts) { @@ -389,18 +373,18 @@ Function Get-CurrentUserODInfo(){ $ODTenant = Get-ItemProperty -Path "Registry::$($Account.Name)" | Select-Object -ExpandProperty ConfiguredTenantId - if ($ODTenant -eq $TenantID) { + if ($ODTenant -eq $TenantID) { - $ODuserEmail = Get-ItemProperty -Path "Registry::$($Account.Name)" | Select-Object -ExpandProperty UserEmail - $ODuserFolder = Get-ItemProperty -Path "Registry::$($Account.Name)" | Select-Object -ExpandProperty UserFolder - $ODuserTenantName = Get-ItemProperty -Path "Registry::$($Account.Name)" | Select-Object -ExpandProperty DisplayName - #Getting a list of Existing MountPoints that are synced with the OneDrive Client (key might not exist is no drives are syncing, so we silently continue on any error. - $MountPoints = Get-Item -Path "Registry::$($Account.Name)\Tenants\$ODuserTenantName" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Property - } + $ODuserEmail = Get-ItemProperty -Path "Registry::$($Account.Name)" | Select-Object -ExpandProperty UserEmail + $ODuserFolder = Get-ItemProperty -Path "Registry::$($Account.Name)" | Select-Object -ExpandProperty UserFolder + $ODuserTenantName = Get-ItemProperty -Path "Registry::$($Account.Name)" | Select-Object -ExpandProperty DisplayName + #Getting a list of Existing MountPoints that are synced with the OneDrive Client (key might not exist is no drives are syncing, so we silently continue on any error. + $MountPoints = Get-Item -Path "Registry::$($Account.Name)\Tenants\$ODuserTenantName" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Property + } } } - if ($ODuserEmail -eq $null) { + if ($null -eq $ODuserEmail) { Write-Error "No configured OneDrive accounts found for the configured Tenant ID! Script will exit now." exit 1 @@ -410,10 +394,10 @@ Function Get-CurrentUserODInfo(){ #Building hashtable with our aquired OneDrive info and returning it to the caller. $ODinfo = @{ - 'Email'=$ODuserEmail - 'Folder'=$ODuserFolder - 'TenantName'=$ODuserTenantName - 'MountPoints'=$MountPoints + 'Email' = $ODuserEmail + 'Folder' = $ODuserFolder + 'TenantName' = $ODuserTenantName + 'MountPoints' = $MountPoints } return $ODinfo @@ -423,60 +407,60 @@ Function Get-CurrentUserODInfo(){ ###################################################### -Function Get-GroupODSyncURL(){ +Function Get-GroupODSyncURL() { <# .SYNOPSIS - This function is used to find the OneDrive user email and folder of the currently logged in user, matching a specific Azure AD Tennant ID + This function is used to find the OneDrive URL used for syncing. .DESCRIPTION - The function parses the HKCU registry hive, matching certain propertied with the specified TenantID - Returning userEmail and UserFolder if a match is found + The function parses the groups available to the user to return th e list of URLs to use in the sync. .EXAMPLE - Get-CurrentUserODInfo -TennantID "00000000-0000000-0000000" + Get-GroupODSyncURL -GroupID '00000000-0000-0000-0000-000000000000' -UPN 'user@contoso.com' .NOTES - NAME: Get-CurrentUserODInfo + NAME: Get-GroupODSyncURL #> param ( - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $GroupID, - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $UPN ) - #Executing other functions in order to get the ID's we require to build the odopen:// URL. - $DriveInfo = Get-UnifiedGroupDrive -GroupID $GroupID - $ListInfo = Get-UnifiedGroupDriveList -GroupID $GroupID - - #Building our odopen:// URL from the information we have gathered, and encoding it correctly so OneDrive wont barf when we feed it. - $siteid = [System.Web.HttpUtility]::UrlEncode("{$($DriveInfo.id.Split(',')[1])}") - $webid = [System.Web.HttpUtility]::UrlEncode("{$($DriveInfo.id.Split(',')[2])}") - $upn = [System.Web.HttpUtility]::UrlEncode($UPN) - $webURL = [System.Web.HttpUtility]::UrlEncode($DriveInfo.webUrl) - $webtitle = [System.Web.HttpUtility]::UrlEncode($DriveInfo.DisplayName).Replace("+","%20") - - # Checking to see if this library is excluded - foreach ($siteName in $excludeSiteList) { - if ($DriveInfo.name -eq $siteName) { - return $false - } + #Executing other functions in order to get the ID's we require to build the odopen:// URL. + $DriveInfo = Get-UnifiedGroupDrive -GroupID $GroupID + $ListInfo = Get-UnifiedGroupDriveList -GroupID $GroupID + + #Building our odopen:// URL from the information we have gathered, and encoding it correctly so OneDrive wont barf when we feed it. + $siteid = [System.Web.HttpUtility]::UrlEncode("{$($DriveInfo.id.Split(',')[1])}") + $webid = [System.Web.HttpUtility]::UrlEncode("{$($DriveInfo.id.Split(',')[2])}") + $upn = [System.Web.HttpUtility]::UrlEncode($UPN) + $webURL = [System.Web.HttpUtility]::UrlEncode($DriveInfo.webUrl) + $webtitle = [System.Web.HttpUtility]::UrlEncode($DriveInfo.DisplayName).Replace("+", "%20") + + # Checking to see if this library is excluded + foreach ($siteName in $excludeSiteList) { + if ($DriveInfo.name -eq $siteName) { + return $false } + } - #Finding the correct ListID for the "Shared Documents" library - $sharedDocumentsListId = $ListInfo | Where-Object Name -Match $sharedDocumentsName | Select-Object -ExpandProperty id - $listid = [System.Web.HttpUtility]::UrlEncode($sharedDocumentsListId) + #Finding the correct ListID for the "Shared Documents" library + $sharedDocumentsListId = $ListInfo | Where-Object Name -Match $sharedDocumentsName | Select-Object -ExpandProperty id + $listid = [System.Web.HttpUtility]::UrlEncode($sharedDocumentsListId) - #Returning the correctly assembled ODOPEN URL - return "odopen://sync/?siteId=$siteid&webId=$webid&listId=$listid&userEmail=$upn&webUrl=$webURL&webtitle=$webtitle" + #Returning the correctly assembled ODOPEN URL + return "odopen://sync/?siteId=$siteid&webId=$webid&listId=$listid&userEmail=$upn&webUrl=$webURL&webtitle=$webtitle" - #If you want a custom suffix for your list titles, then you can use this retunr string instead, remember to outcomment the other one above! - #$listtitle = [System.Web.HttpUtility]::UrlEncode("Documents") - #return "odopen://sync/?siteId=$siteid&webId=$webid&listId=$listid&userEmail=$upn&webUrl=$webURL&webtitle=$webtitle&listtitle=$listtitle" + #If you want a custom suffix for your list titles, then you can use this retunr string instead, remember to outcomment the other one above! + #$listtitle = [System.Web.HttpUtility]::UrlEncode("Documents") + #return "odopen://sync/?siteId=$siteid&webId=$webid&listId=$listid&userEmail=$upn&webUrl=$webURL&webtitle=$webtitle&listtitle=$listtitle" } ###################################################### -Function Get-DriveMembers(){ +Function Get-DriveMembers() { <# .SYNOPSIS @@ -492,7 +476,7 @@ Function Get-DriveMembers(){ param ( - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] $GroupID ) @@ -507,7 +491,7 @@ Function Get-DriveMembers(){ catch { - FatalWebError -Exeption $_.Exception -Function "Get-Drive" + Out-FatalWebError -Exception $_.Exception -Function "Get-Drive" } @@ -515,7 +499,7 @@ Function Get-DriveMembers(){ ###################################################### -function WaitForOneDrive () { +function Wait-OneDriveClient () { <# .SYNOPSIS @@ -523,13 +507,19 @@ function WaitForOneDrive () { .DESCRIPTION The function poll's for the OneDrive process every second, and will resume script execution, once it's running .EXAMPLE - WaitForOneDrive + Wait-OneDriveClient .NOTES NAME: WaitforOneDrive #> + [CmdletBinding()] + param ( + [Parameter(Position = 0)] + [Int32][ValidateRange(1, 3000)] + $MaxWaitSec = '300' #maximum number of seconds we are willing to wait for the OneDrive Process. (not an exact counter, might be a bit longer) + ) + $started = $false - $maxWaitSec = 300 #maximum number of seconds we are willing to wait for the OneDrive Process. (not an exact counter, might be a bit longer) $wait = 0 #Initial Wait counter Do { @@ -537,17 +527,18 @@ function WaitForOneDrive () { $status = Get-Process OneDrive -ErrorAction SilentlyContinue #Looking for the OneDrive Process If (!($status)) { - Write-Output 'Waiting for OneDrive to start...' + Write-Information 'Waiting for OneDrive to start...' Start-Sleep -Seconds 1 - } Else { - Write-Output 'OneDrive has started yo!' + } + Else { + Write-Information 'OneDrive has started yo!' $started = $true } $wait++ #increase wait counter - If ($wait -eq $maxWaitSec) { - Write-Output "Failed to find OneDrive Process. Exiting Script!" + If ($wait -eq $MaxWaitSec) { + Write-Information "Failed to find OneDrive Process. Exiting Script!" Exit } @@ -555,89 +546,126 @@ function WaitForOneDrive () { Until ( $started ) } +function Mount-OneDriveUnifiedGroups { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + $TenantID, + #tenant_id can be read from the azure portal of your tenant (a.k.a Directory ID, shown when you do the App Registration) + #Required credentials - Get the client_id and client_secret from the app when creating it i Azure AD + #Idealy you would secure this secret in some way, instead of having it here in clear text. + [Parameter(Mandatory = $true)] + $ClientID, + [Parameter(Mandatory = $true)] + $ClientSecret, + [Parameter(Mandatory = $false)] + $CleanupLeftovers = $true, + #Set to $true to delete leftover folders from previous syncs (if false, nothing wil be synced if the destination folder already exists) + #Enabling cleanup will also ensure that a folder get's re-added if a user removes it. + [Parameter(Mandatory = $false)] + [Int32][ValidateRange(1, 300)] + $WaitSec = 10, #Seconds to wait between each mount - not having a delay can cause OneDrive to barf when adding multiple sync folders at once. + [Parameter(Mandatory = $false)] + [Array]$ExcludeSiteList, + #List of site names to exclude from being added to OneDrive + #Just add the name of the site to this array, and remove the dummy entries. + # $excludeSiteList = @("DummyDumDum", "Blankorama", "Nonenana") + [Parameter(Mandatory = $false)] + $VerbosePreference = 'Continue' #change to SilentlyContinue to dial down the output. + ) + + begin { + #Special params for some advanced modification + $global:sharedDocumentsName = "Shared Documents" #change if for some reason your tenant displays the shared documents folders with another name + $global:graphApiVersion = "v1.0" #should be "v1.0" + } + + process { + Start-Transcript "$env:TEMP\OneDrive-AutoMapper_log.txt" -Force + # Wait for OneDrive Process + Wait-OneDriveClient + # Getting OneDrive data for currently logged in user, and matching it with the configured Tenant ID + $OneDrive = Get-CurrentUserODInfo -TenantID $TenantID -##################################################### -# -# SCRIPT EXECUTION -# -###################################################### - -# Starting log -Start-Transcript "$env:TEMP\OneDrive-AutoMapper_log.txt" -Force - -# Wait for OneDrive Process -WaitForOneDrive - -# Getting OneDrive data for currently logged in user, and matching it with the configured Tenant ID -$OneDrive = Get-CurrentUserODInfo -TenantID $tenant_id - -# Calling Microsoft to see if they will give us access with the parameters defined in the config section of this script. -Get-ValidToken + # Calling Microsoft to see if they will give us access with the parameters defined in the config section of this script. + Get-ValidToken -TenantID $TenantID -ClientID $ClientID -ClientSecret $ClientSecret -# Getting a list of all O365 Unified Groups -$allUnifiedGroups = $null -$allUnifiedGroups = Get-UnifiedGroups -UPN $($OneDrive.Email) + # Getting a list of all O365 Unified Groups + $allUnifiedGroups = $null + $allUnifiedGroups = Get-UnifiedGroups -UPN $($OneDrive.Email) -# Getting OneDrive Sync URL's for all Unified Groups + # Getting OneDrive Sync URL's for all Unified Groups -Write-Host "Mounting OneDrive all Unified Groups in Tenant ($($OneDrive.TenantName)) that is accessible by $($OneDrive.Email)" -ForegroundColor Yellow -Write-Host + Write-Information "Mounting OneDrive all Unified Groups in Tenant ($($OneDrive.TenantName)) that is accessible by $($OneDrive.Email)" -foreach ($Group in $allUnifiedGroups) { + foreach ($Group in $allUnifiedGroups) { - #Skip if group is not unified - if (!$($group.groupTypes -like "Unified*")){Continue} + #Skip if group is not unified + if (!$($group.groupTypes -like "Unified*")) { Continue } - # Validate that the users is not already Syncing the Drive - if ($($OneDrive.MountPoints) -match [Regex]::Escape("\$($Group.displayName) -")){ - Write-Host "The site ($($Group.displayName)) is already synced! Skipping..." -ForegroundColor Yellow - Write-Host - continue #skip this group and go to the next group - } + # Validate that the users is not already Syncing the Drive + if ($($OneDrive.MountPoints) -match [Regex]::Escape("\$($Group.displayName) -")) { + Write-Information "The site ($($Group.displayName)) is already synced! Skipping..." + continue #skip this group and go to the next group + } - Write-Host "Attempting to sync the drive ($($Group.displayName))..." -ForegroundColor Yellow + Write-Information "Attempting to sync the drive ($($Group.displayName))..." - # Getting the OneDrive Sync URL for the Group Drive - $ODsyncURL = Get-GroupODSyncURL -GroupID $Group.id -UPN $OneDrive.Email + # Getting the OneDrive Sync URL for the Group Drive + $ODsyncURL = Get-GroupODSyncURL -GroupID $Group.id -UPN $OneDrive.Email - #Skipping this Library if it has been excluded - if ($ODsyncURL -eq $false) { - Write-Host "This drive is on the excluded sites list! Skipping..." -ForegroundColor DarkYellow - continue #skip this group and go to the next group - } else { - Write-Verbose $Group.displayName - Write-Verbose $ODsyncURL - } - - # Check for leftover folders, and start sync if none found, else cleanup and start sync. - $UserHomePath = join-Path -Path $env:HOMEDRIVE -ChildPath $env:HOMEPATH - $BusinessPath = Join-Path -Path $UserHomePath -ChildPath $($OneDrive.TenantName) + #Skipping this Library if it has been excluded + if ($ODsyncURL -eq $false) { + Write-Information "This drive is on the excluded sites list! Skipping..." + continue #skip this group and go to the next group + } + else { + Write-Verbose $Group.displayName + Write-Verbose $ODsyncURL + } - try { - $syncFolders = Get-ChildItem $BusinessPath -ErrorAction Stop - foreach ($folder in $syncFolders) { - if (($($folder.Name) -like ("$($Group.displayName) - *")) -and ($CleanupLeftovers -eq $true)) { - $localSyncPath = Join-Path -Path $BusinessPath -ChildPath $($folder.Name) -ErrorAction SilentlyContinue - "Found existing sync for folder for : $($Group.displayName)" - Write-Host "Leftover Folder Found for $localSyncPath" -ForegroundColor Red - Write-Host '$CleanupLeftovers is set to true - Deleting old folder and starting sync' -ForegroundColor Yellow - Remove-Item -Path $localSyncPath -Force -Recurse -ErrorAction SilentlyContinue - } elseif ($($folder.Name) -like ("$($Group.displayName) - *")) { - Write-Host "Existing folder found for : '$($Group.displayName)'" -ForegroundColor Red - Write-Host "OneDrive will complain because 'CleanupLeftovers' is not set to True." -ForegroundColor Red + # Check for leftover folders, and start sync if none found, else cleanup and start sync. + $UserHomePath = join-Path -Path $env:HOMEDRIVE -ChildPath $env:HOMEPATH + $BusinessPath = Join-Path -Path $UserHomePath -ChildPath $($OneDrive.TenantName) + + try { + $syncFolders = Get-ChildItem $BusinessPath -ErrorAction Stop + foreach ($folder in $syncFolders) { + if (($($folder.Name) -like ("$($Group.displayName) - *")) -and ($CleanupLeftovers -eq $true)) { + $localSyncPath = Join-Path -Path $BusinessPath -ChildPath $($folder.Name) -ErrorAction SilentlyContinue + "Found existing sync for folder for : $($Group.displayName)" + Write-Information "Leftover Folder Found for $localSyncPath" + Write-Information '$CleanupLeftovers is set to true - Deleting old folder and starting sync' + Remove-Item -Path $localSyncPath -Force -Recurse -ErrorAction SilentlyContinue + } + elseif ($($folder.Name) -like ("$($Group.displayName) - *")) { + Write-Information "Existing folder found for : '$($Group.displayName)'" + Write-Information "OneDrive will complain because 'CleanupLeftovers' is not set to True." + } + } + } + catch { + Write-Verbose "No previous sync folders found for this user in path : $BusinessPath" } + + Write-Information "The site ($($Group.displayName)) is NOT synced! Adding to OneDrive client..." + Start-Process $ODsyncURL # Sending site info to the OneDrive client + Start-Sleep -Seconds $waitSec + } - } catch { - Write-Verbose "No previous sync folders found for this user in path : $BusinessPath" + Stop-Transcript } - - Write-Host - Write-Host "The site ($($Group.displayName)) is NOT synced! Adding to OneDrive client..." -ForegroundColor Yellow - Start $ODsyncURL # Sending site info to the OneDrive client - Sleep -Seconds $waitSec - Write-Host + end { + + } } -#Ending log -Stop-Transcript + +##################################################### +# +# SCRIPT EXECUTION +# +###################################################### + + Mount-OneDriveUnifiedGroups -TenantID $TenantID -ClientID $ClientID -ClientSecret $ClientSecret \ No newline at end of file