Configuring OneDrive for Business organisation for ER 2.0.26

Applies to ER 2.0.26 and above.

To scan OneDrive for Business with ER 2.0.26:

  1. Create a new Office 365 group and name it "ER2OneDrive" or similar. This group will be used to hold all target user accounts with OneDrive for Business enabled. See Microsoft: Create an Office 365 group in the admin center for more information.
  2. Connect to SharePoint Online using the SharePoint Online Management Shell. Using the Management Shell, get a list of all Office 365 users with OneDrive for Business enabled. See Microsoft: How to display a list of OneDrive for Business site collections for more information.
  3. Add the list of Office 365 users with OneDrive for Business enabled to the “ER2OneDrive” group.
  4. Create a service account to scan OneDrive for Business, or use an existing service account. This service account should be assigned Global Administrator permissions.
    Info: A service account is a user account created only for use with a specific service or application to interact with a system.
  5. Add the service account as a secondary administrator for the “My Site” Site Collection on all target OneDrive for Business accounts. See Microsoft: Assign eDiscovery permissions to OneDrive for Business sites for more information.

The PowerShell script below is a reference that you can use to automate the above steps.

To run this script, you must have the SharePoint Online Management Shell installed.

Review this script before running it in your environment.

# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

$LogFilePath = "$pwd\AdminUpdate-$(get-date -uformat '%Y-%m-%d-%H_%M').csv"
if (!(Test-Path $LogFilePath)) {
  New-Item $LogFilePath -type file *>$null
  Write-Output "Created log file: $LogFilePath"
}
else {
  Write-Output "Logging to $LogFilePath"
}

#----
# Check if SharePoint Online Management Shell ps module is installed
if (!(Get-Command Get-SPOUser -ErrorAction SilentlyContinue)) {
  $err = "SharePoint Online Management Shell tools required."
  Write-Output $err
  $err | Out-File $LogFilePath -Append
  Exit 1
}

#----
# Initializes important variables
do {
  while (!($adminUPN)) {
    $adminUPN = Read-Host -Prompt "
Enter a global administrator account UPN (User Principal Name).
This is usually the full email address of an Office365 administrator account.
E.g. admin@contoso.onmicrosoft.com`n"}
  while (!($TenantName)) {
  $TenantName = Read-Host -Prompt "
Enter your Office365 tenant name/organisation name.
E.g. For <user_name>@contoso.onmicrosoft.com, enter: contoso`n"}
  Write-Output "`nGlobal Admin UPN: $adminUPN
Tenant name: $TenantName"
  #----
  # Retry block. If user confirms settings, sets $retryIndex to 1 and breaks do-until loop
  $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
    "Use these settings."
  $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
    "Change settings."
  $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
  $retry = $Host.UI.PromptForChoice("-------------------", "Use these settings?", $options, 0)
  switch ($retry) {
    0 { 
      $retryIndex = 1
      Write-Output "Global Admin UPN: $adminUPN
Tenant name: $TenantName" | Out-File $LogFilePath -Append
    }
    1 { 
      # reset values so basic validation can be done
      $adminUPN = $null
      $TenantName = $null
      $retryIndex = 0 
    }
  }
} until ($retryIndex -eq 1)

Write-Output "Getting Credentials"
#----
# Check if credentials pass; otherwise re-prompt user
do {
  $retryIndex=0
  try {
        $Credential = Get-Credential -UserName $adminUPN -Message "User Must be a Global Admin"
        Connect-SPOService -Credential $credential -Url https://$TenantName-admin.sharepoint.com
    # If successful, break loop
    # If err != nil, move into catch block
    $retryIndex++
  }
  catch {
    $err = $_.Exception
    Write-Output $err
    $err | Out-File $LogFilePath -Append

    #----
    # Retry block. If select yes (try again), restarts do-until loop to attempt Connect-SPOService again
    $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
      "Try connecting again."
    $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
      "Abort connection."
    $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
    $retry = $Host.UI.PromptForChoice("", "Try again?", $options, 0)
    switch ($retry) {
      0 { $retryIndex = 0 }
      1 { Exit 1 }
    }
  }
} until ($retryIndex -ne 0)

#----
# Create the Outlook Sharepoint Session
Write-Output "Getting Session"
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Credential -Authentication Basic -AllowRedirection

#----
# Access the Session
Write-Output "Importing Session"
Import-PSSession $session

Write-Output "Creating New Group"
# Prompt for Group Name
do {
  while (!($newGroupName)) {
    $newGroupName = Read-Host -Prompt "Enter a new Group Name to store all the OneDrive Users. E.g. OneDriveUsers`n"}
  Write-Output "`nNew Group Name : $newGroupName"
  #----
  # Retry block. If user confirms settings, sets $retryIndex to 1 and breaks do-until loop
  $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
    "Use this name."
  $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
    "Change name."
  $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
  $retry = $Host.UI.PromptForChoice("-------------------", "Use these settings?", $options, 0)
  switch ($retry) {
    0 { 
      $retryIndex = 1
      Write-Output "New Group Name: $newGroupName" | Out-File $LogFilePath -Append
    # Create Group Name
    New-UnifiedGroup -DisplayName $newGroupName -Alias $newGroupName
    Write-Output "Created Group $newGroupName." | Out-File $LogFilePath -Append
    }
    1 { 
      # reset values so basic validation can be done
      $newGroupName = $null
      $retryIndex = 0 
    }
  }
} until ($retryIndex -eq 1)



#----
# General try-catch to validate values obtained via SharePoint Online Management Tools
try {
  # Specify your organisation admin central url
  $AdminURI = "https://$TenantName-admin.sharepoint.com"
  $siteURI = "https://$TenantName-my.sharepoint.com"
  $loadInfo1 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
  $loadInfo2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
  $loadInfo3 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.UserProfiles")
  $creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials ($Credential.UserName, $Credential.Password)
  # Add the path of the User Profile Service to the SPO admin URL, then create a new webservice proxy to access it
  $proxyaddr = "$AdminURI/_vti_bin/UserProfileService.asmx?wsdl"
  $UserProfileService = New-WebServiceProxy -Uri $proxyaddr -UseDefaultCredential False
  $UserProfileService.Credentials = $creds
  # Set variables for authentication cookies
  $strAuthCookie = $creds.GetAuthenticationCookie($AdminURI)
  $uri = New-Object System.Uri($AdminURI)
  $container = New-Object System.Net.CookieContainer
  $container.SetCookies($uri, $strAuthCookie)
  $UserProfileService.CookieContainer = $container
  # Sets the first User profile, at index -1
  $UserProfileResult = $UserProfileService.GetUserProfileByIndex(-1)
  Write-Output "Please wait. Getting list of OneDrive for Business user profiles..."

  # $UserProfileService calls will also include sharepoint online system profiles that are not 
  # part of userland i.e. not usable by sharepoint online admins or users.
  # There should be about 7 system profiles.
  # Don't panic if you can't get all of them
  $NumProfiles = $UserProfileService.GetUserProfileCount()

  # Initialize counters
  $i = 1
  $ExaminedProfiles=0
}
catch {
  # If any of the above fail, script will fail; therefore, exit gracefully.
  $err = $_.Exception
  Write-Output $err
  $err | Out-File $LogFilePath -Append
  Exit 1
}

# Final confirmation before script execution
do {
  $retryIndex=0
  $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
    "Add all OneDrive for Business user profiles to $newGroupName."
  $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
    "Cancel."
  $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
    $retry = $Host.UI.PromptForChoice("", "This will add all OneDrive for Business user profiles to $newGroupName. Are you sure?", $options, 0)
  switch ($retry) {
    0 { $retryIndex++; Continue }
    1 { Write-Output "Cancelling..."
      Exit 1 }
  }
} until ($retryIndex -ne 0)

#----
# Loop through all available User profiles
# As long as the next User profile is NOT the one we started with (at -1)...
While ($UserProfileResult.NextValue -ne -1) {
  Write-Output "Getting user $i" | Out-File $LogFilePath -Append
  # Look for the Personal Space object in the User Profile and retrieve it
  # (PersonalSpace is the name of the path to a user's OneDrive for Business site.
  # Users who have not yet created a OneDrive for Business site do not have this property set.)
  $Prop = $UserProfileResult.UserProfile | Where-Object { $_.Name -eq "PersonalSpace" }
  $PropUserName = $UserProfileResult.UserProfile | Where-Object { $_.Name -eq "UserName" }
  Write-Output $UserProfileResult.UserProfile | Out-File $LogFilePath -Append
  $Url = $Prop.Values[0].Value
  $UserName = $PropUserName.Values[0].Value
  
  # If OneDrive is activated for the user (i.e. personal Site Collection or 
  # My Site site collection exists), then set the secondary admin
  if ($Url) {
    $sitename = $siteURI + $Url
    try {
      # If you change the $false to $true this will add a secondary user rather than remove it
      $temp1 = Add-UnifiedGroupLinks $newGroupName -Links $UserName -LinkType Member
      $status = "Added $UserName to Group $newGroupName"
      Write-Output $status 
      $status | Out-File $LogFilePath -Append     
      $ExaminedProfiles++
    }
    catch [System.Exception] {
      $err = $Error[0].Exception
      Write-Output $err
      $err | Out-File $LogFilePath -Append
    }
  }
  # And now we check the next profile the same way...
  $UserProfileResult = $UserProfileService.GetUserProfileByIndex($UserProfileResult.NextValue)
  $i++
}

# Done
Remove-PSSession $session

# Done
$Done = "Added $ExaminedProfiles OneDrive for Business user profiles to Group $newGroupName."
$Done | Out-File $LogFilePath -Append
Write-Output $Done
Exit 0
Exit 0
Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.