Fixing the Usage and Health Data Collection Service Application Proxy (By Tristan Watkins)

Unfortunately in every farm that I have provisioned so far using powershell I keep running into this issue that the Usage and Health Data Collection Service Application Proxy is set to Stopped.

The fix that Tristan Watkins describes on his blog here fixes just that.

Commands:

#Run Get-SPServiceApplicationProxy to enumerate the IDs of all the Service Application Proxies in your farm.
DisplayName          TypeName             Id
-----------          --------             --
State Service App... State Service Proxy  e51696f1-3523-4e20-9b75-578485024b37
Managed Metadata ... Managed Metadata ... 830bafcf-f0d3-4254-91e4-8cfe11840e27
Search Service Ap... Search Service Ap... a988d821-8247-4294-ba11-961b22e51f8b
Application Disco... Application Disco... af617d69-7332-49f3-a61c-0eef3f7470cf
Excel Services Ap... Excel Services Ap... b6c5b951-7b4d-4837-83f3-c916c1ef6c7d
WSS_UsageApplication Usage and Health ... 83301455-c854-4596-af5c-0bc6ee963b6d

#Copy the ID for the WSS_UsageApplication.
$UP = Get-SPServiceApplicationProxy | where {$_.ID -eq "PASTE ID HERE"}
$UP.Provision()

If you refresh the Manage Service Application page the proxy should be started now.

Provision SharePoint 2010 Search with custom database names

I’m more of a mitliple scripts guy for configuring my SharePoint 2010 farms than a 1 humongous script guy that does everything. I prefer to use one script for installing my binaries and creating/joining the farm and then several scripts for configuring specific service applications. I find it easier for troubleshooting.

Anyway, here is the script I created based on the AutoSPInstaller for configuring the Search Service Application using custom database names:


$SSADB = "SharePoint_ServiceDB_SearchAdmin"
$SSAName = "Search Service Application"
$SVCAcct = "CONTOSO\the_search_service_account"
$SSI = get-spenterprisesearchserviceinstance -local

# 1.Start Services search services for SSI
Start-SPEnterpriseSearchServiceInstance -Identity $SSI

# 2.Create an Application Pool.
$AppPool = new-SPServiceApplicationPool -name $SSAName"-AppPool" -account $SVCAcct

# 3.Create the SearchApplication and set it to a variable
$SearchApp = New-SPEnterpriseSearchServiceApplication -Name $SSAName -applicationpool $AppPool -databasename $SSADB

#4 Create search service application proxy
$SSAProxy = new-spenterprisesearchserviceapplicationproxy -name $SSAName"ApplicationProxy" -Uri $SearchApp.Uri.AbsoluteURI

# 5.Provision Search Admin Component.
set-SPenterprisesearchadministrationcomponent -searchapplication $SearchApp -searchserviceinstance $SSI

This will just create your required databases. From this point on you can configure the required crawl / query topologies using Central Admin.

Rename SharePoint 2010 Central Admin database

I had a post on this for SharePoint 2007 and needed to do the same thing for SharePoint 2010, but wanted to do this the powershell way instead of the stsadm way I used for MOSS. Not sure if that would even work…

turns out I didn’t need to reinvent the weel as Todd Klindt has already blogged about this here

The trick to all this is that for moving all site collections in a content database you would execute Get-SPSite with -contentdatabase parameter to get all the site collections for that content database and then pipe that to a Move-SpSite command. With the Central Admin content database the only way to get the site collections is to specify the GUID of the contentdatabase instead of the database name

In short, here are the commands:


#Create a new Content Database
New-SPContentDatabase -Name SharePoint_CentralAdmin -WebApplication http://sp2010:1000
#Get the Database GUIDs
get-spcontentdatabase -webapplication http://sp2010:1000
Id: d3d04cb1-b919-4262-b2d7-46733ef2c5df
Name : SharePoint_AdminContent_81476219-04f5-46b8-807f-31aa4afb4056
WebApplication : SPAdministrationWebApplication
Server : SP2010-DB
CurrentSiteCount : 2

Id : d8647aed-ef42-4052-814b-670b36fb8c1e
Name : SharePoint_CentralAdmin
WebApplication : SPAdministrationWebApplication
Server : SP2010-DB
CurrentSiteCount : 0

#Move the site collections
Get-SPSite -ContentDatabase d3d04cb1-b919-4262-b2d7-46733ef2c5df | Move-SPSite -DestinationDatabase d8647aed-ef42-4052-814b-670b36fb8c1e

Now do an IISRESET and check that the Central Admin site renders properly. If it does you can safely remove the content database with the GUID in it. Since I check the Central Admin site, I just delete the content database with the GUID from within the Central Admin Site

Updating User Profile pictures with powershell on SP2010

I finally had the chance to play around with user profiles. My customer asked me if it was possible to have the pictures of all employees show up in their respective user profiles in SharePoint and this without uploading the pictures themselves because they already had a dedicated website with all the pictures available. So the only thing to try to figure out was if it was possible to specify a link to the picture on a different website.

The customer was able to give me a CSV file with about 20K lines in it with 2 fields: Username + url of the picture. Worth mentionning was that the url of the user picture was not saved in any Active Directory property of the user object, sow e could not get it from there using the User Profile import process.

As it turns out the User profile actually has a property called PictureUrl which is completed by SharePoint when you upload your profile picture. So the task at hand was to write a script that could read the CSV file and update the user profiles. I started out with the script of Phil Childs and ended up with the following script:


$CSVFile = "C:\Scripts\pictureurls.csv"
$mySiteUrl = "http://people.contoso.com"

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

#Read CSV file and process each line
$csv = import-csv -path $CSVFile
foreach ($line in $csv)
{
$up = $profileManager.GetUserProfile($line.UserName)
if ($up)
{
$up["PictureURL"].Value = $line.PictureUrl
$up.Commit()
write-host $up.DisplayName," --> ", $line.PictureUrl
}
if (!$up) {
write-host $line.UserName, " --> no profile found"
}
}

Now, I’m not a powershell expert (yet) so this script can probably be optimized or improved.

For my customer, we are planning to have this script adapted to check if the pictureUrl field has already been populated and only add the value when it is not and have it run on a regular basis. Ultimately my customer is looking into saving this picture url in Active Directory afterwhich we can play around with FIM to have it popluate the user profiles that way.

Change Locale of Site Variation Label in MOSS

Since some time, my customer had a nasty issue for which I did not see a solution at first. My customer is running its Intranet for years now on MOSS and uses a customized Publishing Portal with Site Variations in 3 languages, English, Dutch and French. The only problem with these Site variations is that the source Variation Label was created with the wrong Locale setting. The variation label was created with a name EN, language English (United States) , but with locale Dutch (Belgium) instead of English (United states).

Now when the hierachy was created, the subsite EN was created with the wrong locale. No problem there because you can change the locale of that particular subsite in the Site Settings – Regional Settings.

The problem my customer was facing is that clients targeting the root site collection and thus the Variation root site, where redirected to the wrong subsite if their browser had the locale Dutch (Belgium) defined. These client all ended up on the EN subsite instead of the Variation NL that was created with locale Dutch (Belgium).

The solution for this problem is to change the Locale in the Variation Labels in the root site. Unfortunately you cannot modify this value once the Variation Label is created (the field is greyed out). A possible solution would be to delete the Variation Label and recreate it. Because of the fact that this was the corporate intranet with lots of content on it, I did not feel very comfortable deleting the Variation Label, because this means you would have to delete the subsite as well before being able to recreate the Variation Label after which yould have to restore the subsite’s contents, etc. Furthermore the Variations system in MOSS is already very fragile and this would certainly break some other things.

Now after searching for a while and snooping around in the content database, I found out that these labels are stored in a hidden list in the Root site called, you’ll never guess, … “Variation Labels”. Now my trick for accessing this a hidden list by just typing the URL like http://intra.contoso.com/Lists/Variation Labels/AllItems.aspx did not work.

Powershell to the rescue!

I was able to access the list and change the locale value for the specific Variation Label with the following set of powershell commands:

#First Load SharePoint
[void][System.reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

#Connect to SPSite object
$site = New-Object Microsoft.SharePoint.SPSite("http://intra.contoso.com/")

#Connect to root SPWeb
$web = $site.AllWebs |where -FilterScript { $_.Url -eq "http://intra.contoso.com"}

#Connect to Variation Labels list
$list = $web.Lists |where -FilterScript { $_.Title -eq "Variation Labels"}

#Get the List item for the Variation Label
$listitem = $list.Items |where -FilterScript { $_.Title -eq "EN"}

#Check the Value
$listitem["Locale"]

#Modify the value to English (United States)
$listitem["Locale"] = 1033
$listitem.Update()

#Dispose of objects
$listitem.Dispose()
$list.Dispose()
$web.Dispose()
$site.Dispose()

Now if you ever need to chaneg the locale value, then this script will help you out. The only thing you need to find out is the value for your specific language. What I did to find out the specific value was to create a new Variation Label on my test environment with teh locale I wanted and fetched that value with the exact same commands.