PowerShell can be a lot of fun and quite powerful because you can script several functions together to create Admin and maintenance function that would take you days to do through the UI.  If I am an admin who has been granted the Manage Profiles right and Full Control in the permissions section of the UPS, I can do some pretty interesting things with a few basic scripts.

For example, imagine that the company has just gone through a massive re-org and now we have a whole bunch of colleagues who have either changed their department or had their department renamed.  Imagine trying to do that for 50 colleagues through the UI, it is doable, but tedious.  Now imagine it was 500 colleagues or even 5000 colleagues.  This is where PowerShell can come in and really save the day.

So, imagine we’re given a Comma Separated Values (CSV) file with the colleague NTID and Department Name and we need to update this information in SharePoint User Profiles.

First step would be to check out the Import-CSV cmdlet ( http://technet.microsoft.com/en-us/library/ee176874.aspx )

Seems like this will work perfectly for our needs, so let’s start building up our script.

I always load in the SharePoint PowerShell snapin:

#First load the SharePoint commands
add-PSSnapIn Microsoft.SharePoint.PowerShell

Now we set up our Job variables, good coding says do this at the top so they are easy to find and change, you can probably further comment them, but the variable names should be descriptive enough so anyone else reading your script will know what’s going on.

#Set up the job variables
$csvfile="Department.csv"
$mySiteUrl = "http://mysite"
$upAttribute = "Department"

We will then need to instantiate

a UserProfileManager object for the mysites, more information about UPM can be found here: http://msdn.microsoft.com/en-us/library/microsoft.office.server.userprofiles.userprofilemanager.aspx (Side note: Why hasn’t Microsoft started producing PowerShell Examples in their documentation pages?  You’d think PowerShell is starting to come into its own enough to be listed next to the C# and VB examples)

#Connect to User Profile Manager service
$site = Get-SPSite $mySiteUrl
$context = Get-SPServiceContext $site
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

Now we transform our CSV file into data we can consume inside our script.

#Create Lists from each item in CSV file
$csvData = Import-Csv $csvfile

And the magic of it all happens here, because we’re going to iterate through our data and apply the new values through our UPM that we’ve instantiated.

#Now iterate through the list to update the attribute with new value
foreach ($line in $csvData)
{
    #Check to see if user profile exists
    if ($profileManager.UserExists($line.NTName))
        {
        #Get user profile and change the value
        $up = $profileManager.GetUserProfile($line.NTName)
        $up[$upAttribute].Value = $line.PropertyVal
        $up.Commit()
        }
    else
    {
        write-host "Profile for user"$line.NTName "cannot be found"
    }
}

Last but definitely not least, release our site object!  Anyone who has dealt with SharePoint programming for more than a day or two will tell you always dispose of your objects when you’re done with them.  Always call dispose on your object even if you think during the course of the run – whether it’s PowerShell or C# – the object will be disposed of anyways.

#Dispose of site object
$site.Dispose()

And there you have it.  A very simple script that will allow us to read in a file containing NTID’s and Departments and update the User Profiles.  Save this script and you’re ready for any re-orgs that come your way!  For those of you who want to cut and past the whole script, here it is all put together:

#First load the SharePoint commands
add-PSSnapIn Microsoft.SharePoint.PowerShell

#Set up the job variables
$csvfile="Department.csv"
$mySiteUrl = "http://mysite"
$upAttribute = "Department"

#Connect to User Profile Manager service
$site = Get-SPSite $mySiteUrl
$context = Get-SPServiceContext $site
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

#Create Lists from each item in CSV file
$csvData = Import-Csv $csvfile

#Now iterate through the list to update the attribute with new value
foreach ($line in $csvData)
{
    #Check to see if user profile exists
    if ($profileManager.UserExists($line.NTName))
        {
        #Get user profile and change the value
        $up = $profileManager.GetUserProfile($line.NTName)
        $up[$upAttribute].Value = $line.PropertyVal
        $up.Commit()
        }
    else
    {
        write-host "Profile for user"$line.NTName "cannot be found"
    }
}

#Dispose of site object
$site.Dispose()