simon
simon

Reputation: 140

Getting ALL users from SharePoint online tenant and set userprofile property via Powershell

UPDATE:

Vadim has a good answer below but this is how I did:

namespace UserProfile.Manipulation.CSOM.Console
{
    class Program
    {
        static void Main(string[] args)
        {
            searchAllUsers();

        }

        private static void searchAllUsers()
        {
            string siteCollectionUrl = "https://tenant.sharepoint.com/sites/intranet";
            string tenantAdminLoginName = "adminlogin";
            string tenantAdminPassword = "Password";

            using (ClientContext clientContext = new ClientContext(siteCollectionUrl))
            {
                SecureString passWord = new SecureString();

                foreach (char c in tenantAdminPassword.ToCharArray()) passWord.AppendChar(c);

                clientContext.Credentials = new SharePointOnlineCredentials(tenantAdminLoginName, passWord);

                KeywordQuery keywordQuery = new KeywordQuery(clientContext);
                keywordQuery.QueryText = "*";
                keywordQuery.SourceId = new Guid("B09A7990-05EA-4AF9-81EF-EDFAB16C4E31");
                keywordQuery.TrimDuplicates = false;


                keywordQuery.RowLimit = 500;
//startrow changed 3 times since 500 limitations.
                keywordQuery.StartRow = 1001;

                SearchExecutor searchExecutor = new SearchExecutor(clientContext);
                ClientResult<ResultTableCollection> results = searchExecutor.ExecuteQuery(keywordQuery);
                clientContext.ExecuteQuery();

                foreach (var resultRow in results.Value[0].ResultRows)
                {
                    SetSingleValueProfileProperty(resultRow["AccountName"].ToString());

                }

            }

        }

        private static void SetSingleValueProfileProperty(string accountName)
        {

            string tenantAdministrationUrl = "https://tentnatname-admin.sharepoint.com";
            string tenantAdminLoginName = "adminlogin";
            string tenantAdminPassword = "password";

            string UserAccountName = accountName;

            using (ClientContext clientContext = new ClientContext(tenantAdministrationUrl))
            {
                SecureString passWord = new SecureString();

                foreach (char c in tenantAdminPassword.ToCharArray()) passWord.AppendChar(c);

                clientContext.Credentials = new SharePointOnlineCredentials(tenantAdminLoginName, passWord);

                PeopleManager peopleManager = new PeopleManager(clientContext);

                peopleManager.SetSingleValueProfileProperty(UserAccountName, "SPS-PicturePlaceholderState", "1");

                clientContext.ExecuteQuery();
            }
        }


    }

}

I need to set a property on ALL userprofiles within a tenant.

It doesnt seem possible to get all user profiles from "UPA" via CSOM and powershell!?

Its possible (in theory) to loop trough all sitecollections and add all users to maybe some array and afterwards only select unique from that array (to remove duplicates):

$sites = Get-SPOSite | select *
foreach ($site in $sites) {

Get-SPOUser -Site $site

...and so on

And then loop trough that array and use csom:

$pMAn = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($context)

$userProfile = $pMan.GetPropertiesFor($user.LoginName)
$ctx.Load($userProfile)

$ctx.ExecuteQuery()
$pMan.SetSingleVlueProfileProperty($userProfile.AccountName, "property", $value)

$ctx.ExecuteQuery()

Anyone who can think of a smarter solution?

Upvotes: 2

Views: 6469

Answers (1)

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59328

As you mentioned, there is no straightforward ways of getting all user profiles within SharePoint tenant using SharePoint Online CSOM API. But you could consider the following approach:

Example

Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.UserProfiles.dll"



Function Get-SPOContext([string]$Url,[string]$UserName,[string]$Password)
{
   $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
   $context.Credentials = Get-SPOCredentials -UserName $UserName -Password $Password
   return $context
}


Function Get-SPOCredentials([string]$UserName,[string]$Password)
{
   $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
   return New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
}



Function Print-UserProfileInfo([Microsoft.SharePoint.Client.UserProfiles.PeopleManager]$PeopleManager,[string]$AccountName){
   $ctx = $PeopleManager.Context
   $accountName = "i:0#.f|membership|" + $AccountName  #claim format  
   $userProfile = $PeopleManager.GetPropertiesFor($AccountName)
   $ctx.Load($userProfile)
   $ctx.ExecuteQuery()
   Write-Host $userProfile.PersonalUrl
}




$tenantUrl = "https://contoso.sharepoint.com/"
$userName = "[email protected]" 
$password = "password"

$secPassword = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($userName, $secPassword)
Connect-MsolService -Credential $cred
$allUsers = Get-MsolUser




$Context = Get-SPOContext -Url $tenantUrl -UserName $userName -Password $password
$peopleManager = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($Context)
$allUsers |  % { Print-UserProfileInfo -PeopleManager $peopleManager -AccountName $_.UserPrincipalName }
$Context.Dispose()

Upvotes: 2

Related Questions