Code Sample – Enumerating ODB sites in SharePoint Online tenant

There was a requirement a while back to enumerate all the MySites [aka ODB Sites/OneDrive for Business sites/Personal Sites] present on a SharePoint Online tenant. Since there was no way to see this in the UI on the admin centre, we need to use a script to grab this information. The detection logic involved enumerating all the user profiles on the tenant, and then grabbing the personal space property [if present]. This will give us the MySites on the tenant. We are using web service calls here to accomplish this - UserProfileService.asmx

#install SharePoint Online Client SDK on the machine you are running this from.

#run this script as local box admin

# Keep tenant admin account details handy

# ensure there is a folder called c:\op on the box that is running this script.

 

#grab tenant information

$domain
=
Read-Host
"Enter the domain prefix"

$adminURI
=
'https://'
+
$domain
+
'-admin.sharepoint.com'

$admin_account
=
Read-Host
"Enter the tenant admin account login"

$pwd
=
read-host
-AsSecureString
"Enter the admin account password"

 

#load the assemblies

$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")

 

#SPO Credentials

$creds
=
New-Object
Microsoft.SharePoint.Client.SharePointOnlineCredentials($Admin_Account, $pwd)

 

# 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

 

# Take care of auth cookies

$strAuthCookie
=
$creds.GetAuthenticationCookie($AdminURI)

$uri
=
New-Object
System.Uri($AdminURI)

$container
=
New-Object
System.Net.CookieContainer

$container.SetCookies($uri, $strAuthCookie)

$UserProfileService.CookieContainer = $container

 

# Grab the first User profile, at index -1

$odbsites
= @()

$UserProfileResult
=
$UserProfileService.GetUserProfileByIndex(-1)

 

Write-Host
"Enumeration of PersonalSites on the tenant"

Write-Host
"Starting- This could take a while."

 

$NumProfiles
=
$UserProfileService.GetUserProfileCount()

$i
=
1

 

# As long as the next User profile is NOT the one we started with (at -1)...

While ($UserProfileResult.NextValue -ne
-1)

{

Write-Host
"Examining profile $i of $NumProfiles"

 

# Look for the Personal Space object in the User Profile and pull it out

# (PersonalSpace is the name of the path to a user's mysite)

$Prop
=
$UserProfileResult.UserProfile |
Where-Object { $_.Name -eq
"PersonalSpace" }

$Url= $Prop.Values[0].Value

 

# If "PersonalSpace" (which we've copied to $Url) exists, log it to our array...

if ($Url)

{

#$Url | Out-File $LogFile -Append -Force

$odbsites+=('https://'+$domain+'-my.sharepoint.com'+$url)

}

 

# And now we check the next profile the same way...

$UserProfileResult
=
$UserProfileService.GetUserProfileByIndex($UserProfileResult.NextValue)

$i++

}

 

 

#Dump out the ODB Sites URL to the file system

$odbsites
|
out-file
c:\op\odbsites.txt