Thursday, May 23, 2013

SharePoint 2010/2013: Using PowerShell to Find Empty User Profile Properties

ADD THIS INFORMATION TO YOUR KINDLE LIBRARY!

Check out the whole SharePoint 2013 Solution Series
New Titles Added Weekly!

One of my readers, Mark Cole, needed some assistance on a PowerShell script. Together we crafted a quick solution to find all user profiles in SharePoint that did not have an entry for a specific property. Mark constructed most of the script and I put on some finishing touches.

Essentially we wanted to find all people that did not have a picture associated with their SharePoint User Profile. A user profile's picture information is stored in the PictureURL property. Therefore our example script finds all profiles that do not have an entry in PictureURL.

Here is what we did (full script at bottom of post):

First we needed some variables so we can easily modify the script for other properties or environments:

# Dynamic Settings
$mySiteUrl = "
http://mysite.company.net"
$findProperty = "PictureUrl"


Next, we needed to establish the server context:

# Obtain Context based on site
$mySiteHostSite = Get-SPSite $mySiteUrl
$mySiteHostWeb = $mySiteHostSite.OpenWeb()
$context = Get-SPServiceContext $mySiteHostSite



From the context we can instantiate a ProfileManager object and retrieve all of the SharePoint User Profiles:

# Obtain Profiles from the Profile Manager
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$AllProfiles = $profileManager.GetEnumerator()
$outputCollection = @()



Next, we loop through the profiles and retrieve the account name (for identification purposes) and the property we are interested in finding:

# Loop through profiles and retrieve the desired property
foreach ($profile in $AllProfiles)
{
    $output = New-Object System.Object
    $output | Add-Member -type NoteProperty -Name AccountName -Value $profile["AccountName"].ToString()
    $output | Add-Member -type NoteProperty -Name $findProperty -Value $profile[$findProperty]
    $outputCollection += $output
}


Finally, we list out the collection items that do not have a value for the property (ie. null):
# List all Accounts that do not contain the property
$outputCollection | Where-Object {[bool]$_.($findProperty) -ne $true}




FULL SCRIPT

# Dynamic Settings
$mySiteUrl = "http://mysite.company.net"
$findProperty = "PictureUrl"

Write-Host "Beginning Processing--`n"

# Obtain Context based on site
$mySiteHostSite = Get-SPSite $mySiteUrl
$mySiteHostWeb = $mySiteHostSite.OpenWeb()
$context = Get-SPServiceContext $mySiteHostSite

# Obtain Profiles from the Profile Manager
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$AllProfiles = $profileManager.GetEnumerator()
$outputCollection = @()

# Loop through profiles and retrieve the desired property
foreach ($profile in $AllProfiles)
{
    $output = New-Object System.Object
    $output | Add-Member -type NoteProperty -Name AccountName -Value $profile["AccountName"].ToString()
    $output | Add-Member -type NoteProperty -Name $findProperty -Value $profile[$findProperty]
    $outputCollection += $output
}

# List all Accounts that do not contain the property
$outputCollection | Where-Object {[bool]$_.($findProperty) -ne $true}






 

9 comments:

  1. This article gives the light in which we can observe the reality. this is very nice one and gives knowledgeable information.

    ReplyDelete
  2. This looks like a very useful script for me. However, I get a series of errors when I run it:

    New-Object : Exception calling ".ctor" with "1" argument(s): "Object reference
    not set to an instance of an object."
    At M:\spprofiles.ps1:13 char:29
    + $profileManager = New-Object <<<< Microsoft.Office.Server.UserProfiles.UserP
    rofileManager($context)
    + CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvoca
    tionException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.Power
    Shell.Commands.NewObjectCommand

    You cannot call a method on a null-valued expression.
    At M:\spprofiles.ps1:14 char:45
    + $AllProfiles = $profileManager.GetEnumerator <<<< ()
    + CategoryInfo : InvalidOperation: (GetEnumerator:String) [], Run
    timeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Cannot index into a null array.
    At M:\spprofiles.ps1:21 char:79
    + $output | Add-Member -type NoteProperty -Name AccountName -Value $profile
    [ <<<< "AccountName"].ToString()
    + CategoryInfo : InvalidOperation: (AccountName:String) [], Runti
    meException
    + FullyQualifiedErrorId : NullArray

    Cannot index into a null array.
    At M:\spprofiles.ps1:22 char:81
    + $output | Add-Member -type NoteProperty -Name $findProperty -Value $profi
    le[ <<<< $findProperty]
    + CategoryInfo : InvalidOperation: (PictureUrl:String) [], Runtim
    eException
    + FullyQualifiedErrorId : NullArray

    ReplyDelete
    Replies
    1. Make sure the New-Object line includes the next line in post so they are on the same line. I had to put in a line break for spacing in tbe post.

      Delete
    2. This code should all be on the same line:

      $profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

      Delete
    3. Steve, Thanks for Replying. I turned out to be a permissions issue. Thanks again for the script!

      Delete
    4. Steve, I've got the same error as the user above. The code you mentioned is on the same line.
      What permissions does the user need to run your script?

      Delete
    5. The account must have permissions granted in the User Profile Service Application. I always run PowerShell and SharePoint Management Console as administrator too.

      Delete
  3. thanks for the scripts. it helped me to pull some profile properties.

    Deepthi

    ReplyDelete
    Replies
    1. Great script...I work for a large company and our pictures are not not in AD.

      Delete