SharePoint Org Chart jQuery Based Solution

I'm sure we are all familiar with the Silverlight based built-in SharePoint Org Chart.  And if we're being honest I'm sure we'd all agree that it kinda sucks.  It's a great idea and may be ok in some simple cases but reality is it just isn't that customizable and a lot of the time doesn't meet your company's needs.

I started a quest to find a good alternative to the default SharePoint Org Chart and through some intense Googling I stumbled across this awesome FREE solution on Github:

https://github.com/Aymkdn/OrgChart-JS-Sharepoint

Huge shout out to the developer of this solution.  This is a jQuery based Org Chart Solution.  You simply go to the site, download the JS/CSS files and upload them to your SharePoint Environment.  The beauty of this solution is it's highly customizable.  The link above has great step by step details on how to get the solution set up.

Note:  This solution is dependent on pulling the User Information from a SharePoint List.  

You might be thinking..."Man that sucks, why can't it pull directly from AD".  Well it can with a little help from our friend PowerShell.  This is something I added on to this solution to make it truly dynamic.

I won't go into details on how to set up the Org Chart solution since it's already outlined in the link I provided.  The purpose of this blog is to show you how to automatically pull in your user data from AD into the SharePoint list so the Org Chart Solution can display it.

Step 1:  Put the following script on your SharePoint Server

 cls
 #Add SharePoint PowerShell SnapIn if not already added
    if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
        Add-PSSnapin "Microsoft.SharePoint.PowerShell"
    }

    $webUrl = "**Insert SharePoint URL Here**"
    $listName = "**Insert Org Chart List Name Here**"
 
$web = Get-SPWeb $webUrl
$list = $web.Lists[$listName]

    $site = new-object Microsoft.SharePoint.SPSite("**Insert MySite Host URL Here**");  
    $ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($site);

    #Get UserProfileManager from the My Site Host Site context
    $ProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext)  
    $AllProfiles = $ProfileManager.GetEnumerator()
    #Delete all items in list
    $items = $list.items
    foreach ($item in $items)
    {
    Write-host "Ok, Bye Bye $($item.id)" -foregroundcolor red
    $list.getitembyid($Item.id).Delete()
    }

    #Loop through user profiles and add users back
    foreach($profile in $AllProfiles)
    {
        $DisplayName = $profile.DisplayName
        $AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value
        #$formattedAcctName = $AccountName.IndexOf("\").Value
        $pos = $AccountName.IndexOf("\")
        $formattedAcctName = $AccountName.Substring($pos+1)
        $FirstName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::FirstName].Value
        $LastName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::LastName].Value
        $JobTitle = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::Title].Value
        $Manager = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::Manager].Value
        $posMgr = $Manager.IndexOf("\")
        $formattedManager = $Manager.Substring($posMgr+1)
        $Picture = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::PictureURL].Value
     

        #Here goes writing Logic to your SharePoint List + Check if account already existing in the SharePoint list then ignore writing.......
        write-host "Profile for account ", $formattedAcctName
        write-host "First Name ", $FirstName
        write-host "Last Name " , $LastName
        write-host "Job Title " , $JobTitle
        write-host "Manager " , $formattedManager
        write-host "Picture " , $Picture
        # Only write item if the user has a Last Name and Picture -- Overwrite this if you don't want to restrict this
        if( ($LastName) -and ($Picture))
 {
         
                $newItem = $list.AddItem()
                $newItem["Title"] = $formattedAcctName
                $newItem["FirstName"] = $FirstName
                $newItem["LastName"] = $LastName
                $newItem["UserID"] = $formattedAcctName
                $newItem["ManagerID"] = $formattedManager
                $newItem["Image"] = $Picture
                $newItem["Description"] = $JobTitle
                $newItem.Update()
                write-host "Item Created: ", $formattedAcctName
        }
        else
        {
            Write-Host 'Variable is null'
        }
}

    write-host "Finished."
    $site.Dispose()

Step 2:  Schedule the above script to run nightly with Windows Task Scheduler

And that's it you're done!


Comments