SharePoint Use Cases

I recently created a view in a document library that shows files modified in the last 30 days. We use a number of levels (folders) in this document library so I wanted to indicate in which folder a modified file was stored.

Here is how you can do this. This is an overkill for task as simple as this one, but it only solution I could think of. It works!

  1. Create a new single text line column in your library e.g. Path
  2. Fire up SharePoint Designer (2010 or 2013) and create a new List Workflow that fires when item is created

Here is how your workflow activities should look like:

Workflow Activities

 

Here is what this workflow does:

  1. Copies value from a hidden column Server Relative URL to a variable substring. Please note: we are omitting first 35 characters. These 35 leading characters are path to the document library and you will need to change this number to match your environment. In my case full Server Relative URL looks like this: /finance/invoices/Shared Documents/2013/05/URA/TeamViewer_552075866.pdf
    In this example step stores /2013/05/URA/TeamViewer_552075866.pdf to the substring variable.
  2. This step removes original filename from string. In my case result of this step is /2013/05/URA//.pdf (Please note: I have no idea how to replace something with an empty string in SharePoint Designer, so I am using “/” instead)
  3. This step replaces filetype with /, the result of this step is /2013/05/URA//./
  4. Replaces “//./” with single “/”. Final result is /2013/05/URA/
  5. This step updates original item, column Path, with the result of previous four steps

Hope this helps!

We recently upgraded our company to Office365 from Google Apps (more details in another post). Our colleagues from Marketing Department never used SharePoint in real production so I received an interesting question: “Toni, how do I lock a document so no one can change it while I do?”

The answer is, you need to perform check out. Here is how you can do this in SharePoint 2013:

1. Check out a document in SharePoint 2013

Check out document in SharePoint 2013



 2. Check out a document from Word 2013 (or 2010)

Check out document Word 2013 - Step 1Check out document Word 2013 - Step 2

Use case: You have been given a task to create an email notification from your workflow that contains full name of the user who created certain item, along with some other information that is irrelevant to this blog post.

While creating workflows in SharePoint Designer you will quickly notice that most activities will display Person columns (like Created By or Modified By) as username (e.g. CONTOSO\toni or even i:0#.f|aspnetmembership|toni) not full name.

Here is a couple of simple steps to overcome that problem (all the screenshots were created with SharePoint Designer 2013).

  • Create a new workflow in SharePoint Designer
  • Insert Send an Email action and then click These Users link
  • In the Define E-mail message field type your desired email body text and click Add or Change Lookup
  • In the Lookup for String dialog
    • Select User Profiles as Data source
    • Field from source: Name
    • In the Find the List Item, select Account Name as field and then filter by Current Item: Created By (or Modified By, or some other Person column, or any other column that contains username)

User Profiles in SharePoint Designer

This simple procedure will instruct your workflow to Query User Profiles store and to retrieve Name of a User whose Account Name equals Current Item: Created By (you can filter by any other column that is a Person column or contains username of a user).

Recently, we finally migrated all our content to SharePoint Online (Office365). Microsoft really did a great job with their infrastructure and optimizations. SharePoint works great in the cloud.

When deploying our new intranet portal I defined the following rule for Document Libraries:

  • Each should be visible in Quick Launch
  • Major versions should be enabled

You can achieve this:

  • By manually configuring each document library (Please don’t.)
  • By creating a document library template with these settings (it will work, but if someone uses default template, it will not follow your guidelines)
  • By automating this via .NET code or PowerShell

For our internal use I developed a small C# app that uses SharePoint Client Object Model to configure the settings mentioned above. My friend Wictor Wilen has posted this great Office365 / SharePoint Online authentication library that saved me a lot of time.

The sample below will iterate your sites and update Document Library settings to match the rule I mentioned above. You will also need the library from Wictor.

Please note: I have no idea if this code is optimal. It might break your SharePoint. It worked well for our, English template based site collection.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Client;

namespace Acceleratio.Office365.DLUpdates {
    class Program {
        static void Main(string[] args) {

            Console.Write("SharePoint Online URL (e.g. https://contoso.sharepoint.com): ");
            string url = Console.ReadLine();
            Console.Write("Username (e.g. billg@contoso.onmicrosoft.com): ");
            string username = Console.ReadLine();
            Console.Write("Password: ");
            string password = ReadPassword();

            // download here: http://www.wictorwilen.se/Post/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx
            Wictor.Office365.MsOnlineClaimsHelper claimsHelper = new Wictor.Office365.MsOnlineClaimsHelper(url, username, password);
            using (ClientContext context = new ClientContext(url))
            {
                context.ExecutingWebRequest += claimsHelper.clientContext_ExecutingWebRequest;

                context.Load(context.Web);
                context.ExecuteQuery();

                Console.WriteLine("Please wait while we update your site. This can take a while... Go for a run!");
                GetSubSites(context, context.Web);
            }
        }

        private static void GetSubSites(ClientContext context, Web web)
        {
            Console.WriteLine("Updating {0}", web.ServerRelativeUrl);
            UpdateDocumentLibrarySettings(context, web);

            context.Load(web.Webs);
            context.ExecuteQuery();

            foreach(Web w in web.Webs)
            {
                GetSubSites(context, w);
            }
        }

        private static void UpdateDocumentLibrarySettings(ClientContext context, Web web)
        {
            context.Load(web.Lists);
            context.ExecuteQuery();

            ListCollection lists = web.Lists;
            foreach (List list in lists)
            {
                context.Load(list.ContentTypes);
                context.Load(list, l => l.IsSiteAssetsLibrary);
                context.ExecuteQuery();

                // Only non hidden, non system Document Libraries will be updated (update for different languages)
                if (!list.Hidden && !list.IsSiteAssetsLibrary && list.BaseType == BaseType.DocumentLibrary && list.Title != "Form Templates" && list.Title != "Style Library")
                {
                    list.EnableVersioning = true;

                    // Site Pages lib will not be visible on Quick Launch (update for different languages)
                    if(list.Title != "Site Pages")
                    {
                        list.OnQuickLaunch = true;
                    }

                    list.Update();
                }
            }
        }

        private static string ReadPassword()
        {
            string pass = "";
            ConsoleKeyInfo key;

            do
            {
                key = Console.ReadKey(true);

                // Backspace Should Not Work
                if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter)
                {
                    pass += key.KeyChar;
                    Console.Write("*");
                }
                else
                {
                    if (key.Key == ConsoleKey.Backspace && pass.Length > 0)
                    {
                        pass = pass.Substring(0, (pass.Length - 1));
                        Console.Write("\b \b");
                    }
                }
            }
            // Stops Receving Keys Once Enter is Pressed
            while (key.Key != ConsoleKey.Enter);

            Console.WriteLine();

            return pass;
        }
    }
}

18 Feb, 2013

SharePoint 2013 – Links for IT PROs

Posted by: Toni Frankola In: SharePoint 2013

I recently delivered a couple of SharePoint 2013 readiness courses for the new SharePoint IT PROs. Here are some links I usually email to them after the course:

(Please comment below if you think I should add something… This post will be updated as I discover new things)

General Links

Configuring User Profile Service

Recommended Reading (soon)

Installing SharePoint

Maintaining SharePoint systems

Forums

Useful SharePoint IT PRO Blogs

Various sites

PowerShell

ULS Log Viewer

Misc

Tags: ,

In last three years I helped numerous customers to install and configure SharePoint 2010 (2013). New User Profile Service application introduced the ability to easily sync User Profile properties from & to Active Directory. In this article I will explain how you can leverage PowerShell to sync user profile photos from file share to SharePoint and Active Directory.

This is how your final result might look like:

The Muppets - Automatically importing user profile pictures to SharePoint 2013 (and 2010)

The problem

Companies often have employee pictures somewhere, in most situations on a file share drive in JPG format. Back in 2010 I found this script and over the years made a number of modifications to it. The script (which you can download below) will iterate through a designated folder and update profile picture for every user in SharePoint (if user exists).

1. Create a folder on your SharePoint server with all the profile pictures
2. Each employee should have a picture in the following format: username.jpg
3. Run the script from SharePoint Management Shell with the following parameters (change these to match your environment):

Update-SPProfilePictures "http://my-sites-host-url" "User Photos" "C:\Photos-Path\" "Your_Domain"

Please note: The script has been tested with English language template of My Site Host. If your  host was deployed in another language this script might not work, or you will have to change User Photos parameter to something else.

Additional features

Once user profile photo is stored in SharePoint, you can easily export it back to Active Directory. Exchange will pick it up from there and, if you are using Outlook (Lync) 2010 or newer, employee pictures will be shown there as well.

Prerequisites, notes and further reading

  • Make sure your SharePoint is up to date with latest patches (currently Feb 2012 CU or later).
  • Make sure you follow Spence Harbar’s instructions on How to Configure User Profile Service in SharePoint 2010 or/and updates for 2013.
  • Make sure profiles are already synced with AD before running the script.
  • My Sites (My Profiles) also need to be configured before you run the script.
  • User running sync must have proper privileges to update Profile properties.
  • You need to run Search crawl before pictures are updated in Search Results.
  • If this process will be automatic, you should probably deny users to update profile pictures on their own.
  • How to configure export of profile pictures.
  • The ideal picture size is 144×144 px for SharePoint. In case you are planning to further export to Active Directory (Outlook & Lnyc) it’s size should be 10kb or less.
  • User performing sync should have the following permissions.

This is the full script, enjoy:

cls
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
	Add-PSSnapin Microsoft.SharePoint.PowerShell;
}

#---------------------------------------------------------------------------------
# Default Values
#---------------------------------------------------------------------------------

$spNotFoundMsg = "Unable to connect to SharePoint.  Please verify that the site '$siteUrl' is hosted on the local machine.";

#-----------------------------------------------------
# Load Assemblies
#-----------------------------------------------------

if ([Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") -eq $null)		{ throw $spNotFoundMsg; }
if ([Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server") -eq $null)	{ throw $spNotFoundMsg; }

#-----------------------------------------------------
# Functions
#-----------------------------------------------------

function ToSimpleString([string]$value, [bool]$trim = $true, [bool]$removeSpaces = $true, [bool]$toLower = $true)
{
    if ($value -eq $null) { return [System.String]::Empty; }

    if ($trim)
    {
        $value = $value.Trim();
    }

    if ($removeSpaces)
    {
        $value = $value.Replace(" ", "");
    }

    if ($toLower)
    {
        $value = $value.ToLower();
    }

    return $value;
}

function GetSPSite($url)
{
    [Microsoft.SharePoint.SPSite]$site = New-Object "Microsoft.SharePoint.SPSite" -ArgumentList $url
    return $site;
}

function GetSPWeb($url)
{
    [Microsoft.SharePoint.SPSite]$site = GetSPSite -url $url;
    [Microsoft.SharePoint.SPWeb]$web = $site.OpenWeb();
    return $web
}

function GetSPList($url, $listName)
{
    $listName = (ToSimpleString -value $listName);

    [Microsoft.SharePoint.SPWeb]$web = GetSPWeb -url $url;
    foreach($list in $web.Lists)
    {
        $title = (ToSimpleString -value $list.Title);
        if ($listName -eq $title)
        {
            return $list;
        }
    }
    return $null;
}

function GetSPDocumentLibrary($url, $libraryName)
{
    [Microsoft.SharePoint.SPDocumentLibrary]$lib = [Microsoft.SharePoint.SPDocumentLibrary](GetSPList -url $url -listName $libraryName);
    return $lib;
}

function GetSPFile($libraryInstance, $fileName)
{
    $fileName = (ToSimpleString -value $fileName -removeSpaces $false);

    foreach($file in $libraryInstance.RootFolder.Files)
    {
        $itemName = (ToSimpleString -value $file.Name -removeSpaces $false);
        if ($fileName -eq $itemName)
        {
            return $file;
        }
    }
    return $null;
}

function UploadSPFile([string]$url, [string]$libraryName, [string]$filePath, [System.Text.StringBuilder]$verbose = $null)
{
    try
    {
        [Microsoft.SharePoint.SPDocumentLibrary]$lib = (GetSPDocumentLibrary -url $url -libraryName $libraryName);
        if ($lib -eq $null)
        {
            throw (([string]'Cannot find document library "') + ([string]$libraryName) + ([string]'" at url "') + ([string]$url) + ([string]'"!'));
        }

        $bytes = [System.IO.File]::ReadAllBytes($filePath);
        $fileName = [System.IO.Path]::GetFileName($filePath);

        [Microsoft.SharePoint.SPFile]$file = GetSPFile -libraryInstance $lib -fileName $fileName;

        if ($file -eq $null)
        {
            if ($verbose -ne $null)
            {
                [void]$verbose.AppendLine("Uploading File...");
            }
            $file = $lib.RootFolder.Files.Add($fileName, $bytes);
        }
        else
        {
            if ($verbose -ne $null)
            {
                [void]$verbose.AppendLine("File Exists, overwriting...");
            }
            $file.SaveBinary($bytes);
        }

        if ($verbose -ne $null)
        {
            [void]$verbose.AppendLine(($bytes.Length.ToString()) + ([string]" bytes written!"));
        }

        return $file;
    }
    catch
    {
        if ($verbose -ne $null)
        {
            [void]$verbose.AppendLine(([string]'Error: Upload to document library "') + ([string]$libraryName) + ([string]'" at "') + ([string]$url) + ([string]'" or file "') + ([string]$filePath) + ([string]'" failed!'));
            [void]$verbose.AppendLine([string]'Error: ' + [string]$error[1]);
        }
    }

    return $null;
}

function GetSpContext($url)
{
    [Microsoft.SharePoint.SPSite]$site = GetSPSite -url $url
    return [Microsoft.Office.Server.ServerContext]::GetContext($site);
}

function GetProfileManager($url)
{
	[Microsoft.Office.Server.ServerContext]$ctx = GetSpContext -url $url
    [Microsoft.Office.Server.UserProfiles.UserProfileManager]$upm = New-Object "Microsoft.Office.Server.UserProfiles.UserProfileManager" -ArgumentList $ctx

    return $upm;
}

function GetSPUser($url, $loginName)
{
   [Microsoft.SharePoint.SPWeb]$web = GetSPWeb -url $url
   [Microsoft.SharePoint.SPUser]$user = $web.AllUsers[$loginName]
   return $user;
}

function GetProfilePropertyName($userProfileManager, $propertyName)
{
    $propertyName = (ToSimpleString -value $propertyName);
    $propertyName = $propertyName.Replace("sps-", "");

    foreach($prop in $userProfileManager.Properties)
    {
        [string]$n = (ToSimpleString -value $prop.DisplayName);
        $n = $n.Replace("sps-", "");
        if ($propertyName -eq $n) { return $prop.Name.ToString(); }

        $n = (ToSimpleString -value $prop.Name);
        $n = $n.Replace("sps-", "");
        if ($propertyName -eq $n) { return $prop.Name.ToString(); }
    }

    return $null;
}

#This function is VERY different from [System.IO.Path]::Combine
function CombineUrls([string]$baseUrl, [string]$relUrl)
{
    [System.Uri]$base = New-Object System.Uri($baseUrl, [System.UriKind]::Absolute);
    [System.Uri]$rel = New-Object System.Uri($relUrl, [System.UriKind]::Relative);

    return (New-Object System.Uri($base, $rel)).ToString();
}

function Update-SPProfilePictures([string]$webUrl, [string]$picLibraryName, [string]$localFolderPath, [string]$domain)
{
	#Get web and picture library folder that will store the pictures
	$web = Get-SPWeb $webUrl
	$picFolder = $web.Folders[$picLibraryName]
	if(!$picFolder)
	{
		Write-Host "Picture Library Folder not found"
		return
	 }

	#Attach to local folder and enumerate through all files
	$files = ([System.IO.DirectoryInfo] (Get-Item $localFolderPath)).GetFiles() | ForEach-Object {

		$username = [IO.Path]::GetFileNameWithoutExtension($_.FullName);

		#Create file stream object from file
		$fileStream = ([System.IO.FileInfo] (Get-Item $_.FullName)).OpenRead()
		$contents = new-object byte[] $fileStream.Length
		$fileStream.Read($contents, 0, [int]$fileStream.Length);
		$fileStream.Close();

		write-host "Copying" $_.Name "to" $picLibraryName "in" $web.Title "..."

		#Add file
		$spFile = $picFolder.Files.Add($picFolder.Url + "/" + $_.Name, $contents, $true)
		$spItem = $spFile.Item

		$upm = GetProfileManager -url $webUrl
		$up = $null;
		$up = $upm.GetUserProfile("$domain\$username");

		$picturePropertyName = GetProfilePropertyName -UserProfileManager $upm -PropertyName "PictureUrl";

		if($up -ne $null)
		{
			if (-not [System.String]::IsNullOrEmpty($picturePropertyName))
			{
				$PortraitUrl = CombineUrls -baseUrl $spFile.Web.Url -relUrl $spFile.ServerRelativeUrl;
				Write-Host $PortraitUrl
				$up.get_Item($picturePropertyName).Value = $PortraitUrl;
				$up.Commit();
			}
		}

	}

	Write-Host "Updating User Profile Photo Store..." -foregroundcolor yellow
	Update-SPProfilePhotoStore –MySiteHostLocation $webUrl
	Write-Host "Done" -foregroundcolor green
}

SharePoint User Profiles Service Application has a lot of nice and very useful features but it misses one small but important thing. Customers often want to display all their contacts (from User Profile Store) in a single list, phonebook style.

Here is a simple solution how to achieve this with a PowerShell script. The script queries the User Profile store and then copies user profile information to a simple SharePoint list (based on Contacts list template). The final result might look like this:

Please note:

  • If your company has more than 1000 employees this solution might not scale properly.
  • The script below was designed for English based SharePoint site templates, additional modifications might be required for other languages.
  • The script must be executed under user that has both read privileges to User Profile Service Application and contribute privileges for your site.

Configuration steps:

  • On your intranet/team site create a list based on the Contacts list template
  • Create an additional column in this list: UserName – Single line of text

Here is the script:

cls
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
	Add-PSSnapin Microsoft.SharePoint.PowerShell;
}
function Enumerate-SPUserProfiles($webUrl, $listName)
{
	$x= [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
	$x= [System.Reflection.Assembly]::LoadWithPartialName("microsoft.sharepoint.portal")
	$x= [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")
	$x= [System.Reflection.Assembly]::LoadWithPartialName("System.Web")
	$sites = Get-SPSite
	$context = [Microsoft.Office.Server.ServerContext]::GetContext($sites[0])
	$profileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

	$web = Get-SPWeb $webUrl
	$list = $web.Lists[$listName]

	# gets all the user profiles, those that have domain\username as DisplayName are excluded
	$profileManager.GetEnumerator() | ?{$_.DisplayName -notlike '*\*' -and $_.ProfileType -eq "User" } | foreach-object { Update-PhoneBook $_ $web $list $webUrl } |
}

function Update-PhoneBook($user, $web, $list, $webUrl)
{
	if($user.Item("FirstName") -ne "" -and $user.Item("FirstName") -ne $null)
	{
		$spQuery = new-object Microsoft.SharePoint.SPQuery
		$userName = $user.Item("UserName")
		$camlQuery = "<Where><Eq><FieldRef Name='UserName' /><Value Type='Text'>$userName</Value></Eq></Where>";
		$spQuery.Query = $camlQuery
		$spQuery.RowLimit = 1
	 	$spListItemCollection = $list.GetItems($spQuery)
		$domain = (gwmi WIN32_ComputerSystem).Domain

		if($spListItemCollection.Count -ge 1)
		{
			Write-Host "Updating $username..."
			Update-Contact $spListItemCollection[0] $user $domain $webUrl
		}
		else
		{
			Write-Host "Adding $username..."
			$contact = $list.items.add();
			Update-Contact $contact $user $domain $webUrl
		}
	}
}

function Update-Contact($contact, $user, $domain, $webUrl)
{
	$lastName = $user.Item("LastName");
	$contact["Title"] = "$lastName";

	$firstName = $user.Item("FirstName");
	$contact["FirstName"] = "$firstName";

	$workEmail = $user.Item("WorkEmail");
	$contact["Email"] = "$workEmail";

	$workPhone = $user.Item("WorkPhone");
	$contact["WorkPhone"] = "$workPhone";

	$CellPhone = $user.Item("CellPhone");
	$contact["CellPhone"] = "$cellPhone";

	$office = $user.Item("Office");
	$contact["Office"] = "$office";

	$department = $user.Item("Department");
	$contact["Department"] = "$department";

	$userName = $user.Item("UserName");
	$contact["UserName"] = "$userName";

	$contact.update()
}

You can run it by typing:

Enumerate-SPUserProfiles "http://your_site_url" "List_Name"

At Acceleratio, we often receive various use case requests from customers using our product Documentation Toolkit for SharePoint, here are few of those use cases:

Use case – Upgrading farms or resuming maintenance after rogue admin left

Customer writes:

I have taken over administration of a SharePoint farm at [enter company name here] and will be migrating all sites to a new farm. The former administrator is no longer here and very little documentation exists, but discovered your tool on one of the servers and has proven to be quite useful.

Here is how you can use us Documentation Toolkit to help you document SharePoint farm topology and ease you administration efforts:

Use case – Managing permissions and audit reports

Customer writes:

The Office of the Lord Commander has requested an account termination. Please remove Jon Snow (JS030329) from all the SharePoint sites effective 2:30pm this afternoon. Also, for security purposes, please provide an audit report of the sites and permissions removed.

Yup, people leave companies, are fired, or change positions, so SharePoint admins need to manage these things. Here is how our tool helps you with these tasks:

  • Use the advanced load to load SharePoint farm configuration and all the permissions given
  • Use the Permission Explorer to explore permissions by Web Applications or Site Collections or
  • Open the User Permissions report to check all permissions for an individual user. Reports can easily be exported to Excel or PDF for other departments.

One of mine customers wanted to replace their existing phone directory with the SharePoint OOTB user profiles. They already had all the data in the Active Directory and also had pictures for most employees, so SharePoint sounded like an obvious choice. One of the requests was to have search as you type suggestions for people search. The good news is: this already exists in SharePoint, you just just need some PowerShell magic to work correctly.

SharePoint People Search As You Type

A note from the official documentation:

Query suggestions depend on users’ searches. Only search queries that have been previously returned and then clicked through at least six times will appear in either the search box list or the Related Queries Web Part. Therefore, a newly deployed SharePoint Server 2010 system will not show query suggestions in either location. Moreover, a query suggestion will only appear in the search box list or the Related Queries Web Part if the query suggestion contains at least one of the words that are typed.

This is what you need to do to configure this for your environment:

1. Execute the following script in your environment. For parts of this script I used this script by Daniel Root). Make sure you change to match your Search Service Application name (line 22) before exacting.

cls
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
	Add-PSSnapin Microsoft.SharePoint.PowerShell;
}

function Enumerate-SPUserProfiles($SearchServiceApp)
{
	$x= [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
	$x= [System.Reflection.Assembly]::LoadWithPartialName("microsoft.sharepoint.portal")
	$x= [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")
	$x= [System.Reflection.Assembly]::LoadWithPartialName("System.Web")

	$sites = Get-SPSite
	$context = [Microsoft.Office.Server.ServerContext]::GetContext($sites[0])
	$profileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
	# gets all the user profiles, those that have domain\username as DisplayName are excluded
	$profileManager.GetEnumerator() | ?{$_.DisplayName -notlike '*\*' } | foreach-object { Add-SPSuggestion $SearchServiceApp $_ } |
}

function Add-SPSuggestion($SearchServiceApp, $User)
{
	New-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $searchapp -Language En-Us -Type QuerySuggestionAlwaysSuggest -Name $User.DisplayName
}

#Change to match your Search Service Application Name
$searchapp = Get-SPEnterpriseSearchServiceApplication -Identity "Search Service Application"

Enumerate-SPUserProfiles
Start-SPTimerJob -Identity "prepare query suggestions"

2. Navigate to your Search Center > People Search page

3. Edit People Search Web Part properties

4. Check the Show query suggestion option

Show Query Suggestions

5. Save Page

That’s it! You are done!

18 Jul, 2012

Sync your files to SharePoint 2013 or Office 365

Posted by: Toni Frankola In: SharePoint 2013

As you probably heard SharePoint 2013 Preview has been released. There is number of cool features available but there is one that’s super simple yet so very useful. I am huge fan of DropBox, this simple application allows you to sync your folders to the cloud. Now you can do the same with SharePoint 2013, no special requirements to configure this.

Figure below shows a document library synced to my computer. All the changes are propagated back and forth. Very cool and helpful feature.

Update 2013-04-04: I have updated this screenshot to match SharePoint 2013 / Office365 RTM.

Sync to SkyDrive Pro


About

Real-life use case and opinions about collaboration, CRM and web technologies and stuff by Toni Frankola. More...

Toni Frankola - SharePoint MVP Profile

All postings on this blog are provided "AS IS" with no warranties, and confer no rights. All entries in this blog are my opinion and don't necessarily reflect the opinion of my employer.