Skip to content
@JaredMeredith

@JaredMeredith

Learn. Share. Repeat.

  • Blog
  • Resume
  • Strengths Finder Top 5
    • Strengths Finder All 34
  • 16Peronalities
  • Builder Profile 10
C#, Email, Programming, SharePoint, SQL

Programmatically update the manager field from a SQL table for sharepoint user profile

05/29/201504/25/2016 Jared Meredith

Oh, what a journey this was. Googling, reading, BCS this, BCS that, you can do it, you can’t do it, then a somewhat vague article that almost explained it (but not quite of course). As you may or may not know, updating the manager field in user profile is a pain. You cannot map it to anything other than BCS through the built-in mechanisms. This is because of the complicated person type in SharePoint (which by default is mostly not to be messed with).

After much travail I came out the other side of the tunnel with a working solution to update the user profile manager field programmatically from SQL. This snippet loops through my SQL table, checks for the user in user profile. If the user exists then it will check to ensure the manager exists. If both check out then the update statement executes. The results are gathered as a log and emailed as html.

I created a SQL table that had the user to update and the manager to update for that user. I placed the SQL table on the same server as my sharepoint db so I could utilize the accounts that were already created there.

I ended up putting my code snippet inside of the Execute event on a custom SharePoint timer job. For info on creating custom timer jobs, you can consult this article.

Here’s my using statements above the namespace on the timer job:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;

Once you have a timer job just insert this snippet into your execute event.

string message = "";

int counter = 0;

// get a reference to the current site collection's content database
SPWebApplication webApplication = this.Parent as SPWebApplication;
SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];

// proceed if you have a valid content database id
using (SPSite site = new SPSite(contentDb.Sites[0].ID))
{
// proceed if you have a valid site service context based on the site
using (new SPServiceContextScope(SPServiceContext.GetContext(site)))
{
// create a reusable user profile user container
UserProfileManager upm = new UserProfileManager();

// sql string
using (var connection = new SqlConnection("Data Source=SERVERNAME;Initial Catalog=YOUR_DB;User Id=DOMAIN\\userWithSQLAccess;Password=userWithSQLAccessPwd;Integrated Security=SSPI;"))
{
// perform the following transactions with the following SQL command
using (var command = connection.CreateCommand())
{
// query used in the database that populates the users whom we want to update their manager with
command.CommandText = "SELECT [AccountName], [ManagerAcctName] FROM [YOUR_DB].[dbo].[YOUR_TABLE]";

// open the connection and start the reader
connection.Open();
using (var reader = command.ExecuteReader())
{
// retrieve and assign values from SQL to object variables
var indexOfColumn1 = reader.GetOrdinal("AccountName");
var indexOfColumn2 = reader.GetOrdinal("ManagerAcctName");

// perform while there are row results from the query above
while (reader.Read())
{
// assign reader object values to object variables
var value1 = reader.GetValue(indexOfColumn1);
var value2 = reader.GetValue(indexOfColumn2);

// create strings and assigned converted string values of object variables
string sAccount = String.Empty;
string sManager = String.Empty;
string sManagerAcctName = String.Empty;
string oldManager = String.Empty;
sAccount = value1.ToString();
sManagerAcctName = value2.ToString();

// check to see that the user profile exists for an account
if (upm.UserExists(sAccount))
{
// create a reusable user profile for checking SQL per row
UserProfile u = upm.GetUserProfile(sAccount);

// check for the presense of an old manager
if (String.IsNullOrEmpty(u["Manager"].Value.ToString()))
{
// if the manager doesn't exist clear the value
oldManager = "";
}
else
{
// if the manager exists the place it there to log it
oldManager = u["Manager"].Value.ToString();
}

// verify that the manager exists
if (sManager != null)
{
// create and assign the string value of the manager value from SQL
string mAccount = sManagerAcctName.ToString();

// verify that there is a user profile value for the manager field given from SQL
if (upm.UserExists(mAccount))
{
// Assign the manager value from SQL to the user profile manager field
u["Manager"].Value = mAccount;
// commit the user profile save
u.Commit();

// check to see if there was an old manager field populated
if (string.IsNullOrEmpty(oldManager))
{
// log that user had no prior manager but will now after this update
message = message + sAccount + " had no previous manager but is now updated " + " to " + mAccount + "<br />";
}
else
{
// log that the user had a prior manager but is now updated to a new one from this process
message = message + sAccount + " manager was updated from " + oldManager + " to " + mAccount + "<br />";
}

// keep count
counter = counter + 1;
}
else
{
// if you are here than the manager value from SQL is not a valid user profile user = SKIP
}
}
else
{
// if you are here then there is not a manager value in the SQL data = SKIP
}
}
else
{
// if you are here than the row on the SQL data was not a valid user profile user = SKIP
}
}
}

// close the SQL connection when done
connection.Close();

// attempt to send the email message
try
{
// definet the mail client that will send the message
SmtpClient client = new SmtpClient();
client.Port = 25;
client.Host = "exchangeserver.yourdomain.com";

// get and assign the to field of the email message
string toemail = "";
toemail = "yoursharepointadmin@yourdomain.com";

// build the mail message for the mail client to send
MailMessage mm = new MailMessage();
mm.From = new MailAddress("donotreply@yourdomain.com");
mm.To.Add(new MailAddress(toemail));

// put the rest of email together
mm.Subject = "AD Manager To UPS Timer Job - " + counter.ToString() + " records processed";
mm.Body = message;
mm.IsBodyHtml = true;

// send the message
client.Send(mm);
}
catch
{
// handle error if you want
}
}
}
}
}

Help me out and share!

  • Click to email a link to a friend (Opens in new window)
  • Click to print (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • Click to share on Twitter (Opens in new window)
  • Click to share on Reddit (Opens in new window)
  • Click to share on Tumblr (Opens in new window)
  • More
  • Click to share on Pinterest (Opens in new window)
  • Click to share on Pocket (Opens in new window)
  • Click to share on Telegram (Opens in new window)
  • Click to share on WhatsApp (Opens in new window)
  • Click to share on Skype (Opens in new window)

Like this:

Like Loading...

Related

Tagged C#, Email, SharePoint, SQL, user profile

Published by Jared Meredith

Principal Architect with 15+ years’ experience with expertise in all things Enterprise Architecture. View all posts by Jared Meredith

Post navigation

Previous postProgrammatically Send An Email Message With An Html Body (C#)
Next postExecute An Oracle Stored Procedure With Parameters (C#)

About Me

Jared Meredith

Jared Meredith

Principal Architect with 15+ years’ experience with expertise in all things Enterprise Architecture.

Personal Links

  • LinkedIn Profile
  • @JaredMeredith
  • Credly

View Full Profile →

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 73 other subscribers

Why did I start the site…?

I started this site mainly as a place where I can put any gotchas and snafus I find along the way to better help the development community. I hope it helps as time goes on.

Questions? Comments?

If you have a question about a post then please leave a comment. I'll reply on the comment to keep all answers for everyone to see. If you have a private technical inquiry unrelated to any posts, please direct it to jared.meredith@live.com.

The Latest

  • Presentation Now Available: The Power of Cross-Platform Automated Web-Based Testing in CICD Pipelines
  • TLDR: Reflection + Pain = Progress
  • Join me for “Healthcare Technology During COVID-19” by KTech
  • Communications during coronavirus and a socially distant remote workforce
  • Going to Codestock? Come see me!

Categories

Create a website or blog at WordPress.com
  • Follow Following
    • @JaredMeredith
    • Join 73 other followers
    • Already have a WordPress.com account? Log in now.
    • @JaredMeredith
    • Customize
    • Follow Following
    • Sign up
    • Log in
    • Copy shortlink
    • Report this content
    • View post in Reader
    • Manage subscriptions
    • Collapse this bar
%d bloggers like this: