Sunday, September 28, 2014

Clean up SharePoint User Profile Store using PowerShell

Today i had a problem in my development environment for my SharePoint Projects regarding User Profile Store. My user profile was a messed up and was not available for editing in central administration. When i searched for my profile it still there but not shown for administration.  This was a really strange behavior because a couple of days it worked well. I added various new profile properties to my user profile service application. So the recreation of User Profile Service 
Application was not an option. Deletion of orphan or corrupted user profiles is not possible using Central Administration or even using avaliable PowerShell commands.

But there is a solution using PowerShell without compiled code. Using PowerShell everything what is avaliable in the server object model is avaliable. First of all two assemblies must be referenced.
These assemblies are:

These assemblies are:

Script:

/* Load required Assemblies for SharePoint Server and User Profile */
[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.Office.Server”)
[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.Office.Server.UserProfiles”)
/* Central Adminstration URL or any Web Application*/
$url = "http://myserver:Port"
/* Create a new Context Object */
$contextWeb = New-Object Microsoft.SharePoint.SPSite("http://servername");
/* Get the right Service Context */
$ServerContext = [Microsoft.Office.Server.ServerContext]::GetContext($contextWeb);
/* create a new connection to the UserProfileManager */
$UserProfileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServerContext);
/* Ger all User Profiles */
$Profiles = $UserProfileManager.GetEnumerator();
/* Loop through user profile */
foreach ($oUser in $Profiles ) {
/* Remove Profile */
$UserProfileManager.RemoveUserProfile($oUser.item("AccountName"));
}

This script can be extended to delete only specific users from user profile information. At the end I was able to solve my problem. My User Profile was deleted and recreated on first access and due profile import. Everything worked fine.

In the old days you had to write some custom command line tool to address those batch update and deletion task. With the introduction of PowerShell to SharePoint any possible administrative task could be accomplished by just use scripting.

Those assemblies could be referenced using System.Reflection and the rest of the script is quite simple SharePoint Development. So get a context object, open profile service application get all use and delete them.

Update Mysites/UserProfile user image url

I have recently had reason to update the PictureURL property value via PowerShell in SharePoint 2013 for all users in the system.
As a result, I wrote the following PowerShell script to update the property value using string replace.

You will ideally need to run this on the server with an account with the appropriate permissions to update all user profiles.

Script:

#Set up default variables
  
  #My Site URL
  $mySiteUrl = "http://mysite/"
  
  #The part of the picture URL you are trying to find
  $currentURLValue = "http://mypersonalsite"
  
  #The value that will replace the above
 $newURLValue = "http://mysite:80"
 #The internal name for PictureURL
 $upPictureURLAttribute = "PictureURL"
 #Get site objects and connect to User Profile Manager service
 $site = Get-SPSite $mySiteUrl
 $context = Get-SPServiceContext $site
 $profileManager = New-Object   Microsoft.Office.Server.UserProfiles.UserProfileManager($context) 
 $profiles = $profileManager.GetEnumerator()
 foreach ($userProfile in $profiles) {
  if ($userProfile[$upPictureURLAttribute] -ne '') {
    
    $newPictureURL = $userProfile[$upPictureURLAttribute].toString()
    $newPictureURL  = $newPictureURL.Replace($currentURLValue, $newURLValue)
    
    write-host "Before: " $userProfile[$upPictureURLAttribute].toString() " | After: " $newPictureURL 
    
    #Get user profile and change the value - uncomment the lines below to commit the changes
    #$userProfile[$upPictureURLAttribute].Value = $newPictureURL
    #$userProfile.Commit()
  }
 }

Get the Site Collection url's for a specific Data base using Powershell script

Get-SPSite -Limit All -ContentDatabase "DBTestSiteCol" | Select URL, Owner, SecondaryOwner | Export-CSV C:\SiteInfoDB.csv -NoTypeInformation

Deploying solutions in SharePoint 2013


Disable-SPFeature -Identity "Feature1" -Url "http://sharepointsite" -force

Uninstall-SPFeature -Identity "<Feature Name>" -force

OR

Uninstall-SPFeature -Identity "<Feature ID>" -force

Uninstall-SPSolution -Identity testsolution.wsp

Remove-SPSolution -Identity testsolution.wsp

Add-SPSolution -LiteralPath "C:\Packages\testsolution.wsp"

Install-SPSolution -Identity testsolution.wsp -GACDeployment -CompatibilityLevel {14,15}

Saturday, September 27, 2014

How to display Search Results filtered on a specific Content Source

One of the things you may wish to do if you have multiple content sources is to limit a search result to a specific Content Source. For example I have created a BCS connection to a database table containing a list of products from the sample database Adventureworks product table. When I search, I only want to see results from the products table, like below.



 The first thing we would need to do is setup a content Source. For this example, I had previously created a BCS connection to the Adventureworks product table. Now I will create a search content source to point to this BCS connection. When I create a new content source on the search administration page and select BCS Service, a list of external data sources display. In this example I selected my Adventureworks data source.


When I am done it displays here in my content source list. I will need to do a full crawl to populate the index with items.



 Next, I will want to create a Result Source.  A Result Source will allow me to create a scope, or a subset of the crawled content to only return my BCS content source data. in the snapshots below I created a result source called AWResultSource. Note that I have created this result source at the search application level. this allows me to leverage the result source from any site collection. I could also create this same kind of filter at the result page or site collection level which we will see later in this blog.

  

 On the new Result Source page I have chosen "Local SharePoint" and "SharePoint Search Results" and then I will select "launch Query Builder". This will bring up the page to build the actual filter. When I first go to select my property from the property filter, the content source property does not show up. I needed to select "Show all managed properties".

  

 Now I select the ContentSource property, choose Manual value, and enter the name of the content source I created earlier. On the right, you will get a sample of the results to make sure you are on track. If you get a nasty message about not being able to show a preview, you will need to turn on the "Search Server Webpart and properties" feature in site settings for the admin site.

 

The feature name:



 At this point, I have a content source to index the content, and I have a result source to filter search results for the content.

Now I will add it to a search center site. The rest of this blog is focused on modifying the search center site collection.
For your reference, go to the Site Settings page for your search center and select "Manage Result Sources". You will note that the Result Source I created above is in the list. If I had wanted to, I could have just added it here and it would be available for this site collection.



 At this point I need a page to show the filtered results with. This is the interesting part, the settings for the filter to only show the results for the content source is part of the results page. Now lets create the page. Go to the Pages library under Site Contents for the search center site. Select Files, New Document, and then Page. Note that the page layout is a Search Results page layout. choose a name and save. In the screenshot below I created a page called awresultpage.



Now we will edit the page to set our filter. Edit the page and choose edit the webpart for the Search results webpart. in the "Properties for Search Results" section, select change query.




 For "Select a query" choose the result source. In this case it would be the AWresultSource we created earlier. This will set the filter on the results we want. Again I should see a search result preview. Note that I could have set the result source filter right here instead of at the service application level. You have lots of options for the visibility level for returning a subset of the crawled index.



The last thing I need to do is to modify the Search Settings page under site settings to show the menu item on the search page. Here I will add a link under Configure Search Navigation.



 The link points to the results page I created.



Now when I go to the search page, I see products as a menu option. and when I click it, I see the results for the content source.

 

Restart Microsoft SharePoint Foundation Web Application Service. Error

I wanted to share some information in case you are planning to restart “Microsoft SharePoint Foundation Web Application” service or any other service and got stuck with status showing “Stopping” you can use power shell command mentioned below.

I had a situation when “Microsoft SharePoint Foundation Web Application” service was Showing “Stopping” status for more than 7 hours and even reboot and IIS reset did not do anything. I was able to restore service in normal condition using command mentioned below.

Note: In case you are planning to restart “Microsoft SharePoint Foundation Web Application” service better back up your IIS and Virtual directory folder to be on the safe side.

If you have the same situation where some service is stuck use power shell to stop it

$svc = Get-SPServiceInstance | where {$_.TypeName -like "*Foundation Web*"}
$svc.Status = "Offline"
$svc.Update()

You can use PowerShell to start it again

$svc = Get-SPServiceInstance | where {$_.TypeName -like "*Foundation Web*"}
$svc.Status = "Online"
$svc.Update()

In order to get virtual directories back run this PowerShell command

$wa = Get-SPWebApplication http://webAppUrl
$wa.ProvisionGlobally()

Update Redirect Page url programatically

Below is the code to update the Redirect url of a page in sharepoint.

Code snippet:

SPSite site = new SPSite("http://sharepointsite");
SPWeb web = site.OpenWeb();
SPList library = web.Lists["Pages"];
SPQuery query = new SPQuery();
query.Query = "<<Where><Eq><FieldRef Name='ContentType' /><Value Type='Computed'>Redirect Page</Value></Eq></Where><OrderBy><FieldRef Name='Created' Ascending='true' /></OrderBy>";
query.RowLimit = 4;
SPListItemCollection items = library.GetItems(query);
foreach (SPListItem item in items)
  {
     if (item.ContentType.Name == "Redirect Page")
         {
              item.File.CheckOut();
              SPFieldUrlValue urlValue = new SPFieldUrlValue();
              urlValue.Description = "https://www.google.com"; // ValidURL is a correct URL that I've tested
              urlValue.Url = "https://www.google.com";
              item["Redirect URL"] = urlValue;
              item.SystemUpdate(false);
              item.File.CheckIn("", SPCheckinType.MajorCheckIn);                  
         }              

  }