Friday, December 23, 2011

Trying to configure FAST search and SharePoint Search to work on the same web application

I have been trying to run FAST search for my content and standard SharePoint Search for people search. I know FAST can do people search, but a third party application is forcing my hand.
I believe I have run into a wall as it appears that the OOTB search web parts do not allow you to pick one search over the other and the Configure Service Application Associations only lets you pick down to the granularity of the service application.
Incidentally, if I do not have FAST Search Query Service Application set as default in my Configure Service Application Associations, my FAST Search Center will return an error "The search request was unable to connect to the Search Service"

Oh well, time to give up and move on.

Monday, November 28, 2011

ec2-describe-instances filter definitions must have format 'name=value'

I wanted to get a list of my Amazon instances with a particular filter, so I tried something simple as suggested in the ec2-describe-instances documentation: 
ec2-describe-instances --filter "instance-type=m1.small"

However, this returns the following error:
Filter definitions must have format 'name=value', but found 'instance-type'

After a bit of frustration, I finally realized that you have to pass in the quotes in the argument. This means that you need to escape the quotes in Powershell like so:
ec2-describe-instances --filter "`"instance-type=m1.small`""

Thursday, November 17, 2011

PostSetupConfigurationTaskException - Failed to upgrade SharePoint Products

I just upgraded a SharePoint 2010 site from the RTM load to SP1 (KB2460045) + June 2011 CU (KB2536599). Running the Products Configuration Wizard (psconfig) ended with the following error:
Task upgrade has failed with a PostSetupConfigurationTaskException An exception of type Microsoft.SharePoint.PostSetupConfiguration.PostSetupConfigurationTaskException was thrown.  Additional exception information: Failed to upgrade SharePoint Products.

File that under useless error message.

Then I found this post: http://sharepoint.stackexchange.com/questions/16104/sharepoint-server-2010-sp1-psconfig-issue/21031#21031 which suggested to Run As Administrator on the Products Configuration Wizard. That worked.

Tuesday, November 15, 2011

Access is denied when crawling despite account having access - using basic authentication

I had just set up a content source and ran a full crawl of one of my sites. However, this is what I got in the crawl log:

Access is denied. Verify that either the Default Content Access Account has access to this repository, or add a crawl rule to crawl this repository. If the repository being crawled is a SharePoint repository, verify that the account you are using has "Full Read" permissions on the SharePoint Web Application being crawled

I doublechecked that my Default Content Access Account indeed has rights to the entire site by logging in from the server as that account and browsing around. I also had DisableLoopbackCheck set (don't worry, this is not a production machine).

So, I looked at the IIS logs to see what is going on. However, there were no access attempts recorded. Given that the machine is accessible I concluded that this was an authentication issue.

Then I came across this Crawl Rule configuration. If you go into Crawl Rules under your search service application's management screen you can set Crawl Configuration to "Include all items in this path". Then, the Specify Authentication section will become available. Pick "Specify a different content access account" and you can specify different login credentials, but can also uncheck "Do not allow Basic Authentication" (which was my problem).

(Oh, and if you go back to reading the error message, it does suggest creating a crawl rule).

Wednesday, November 9, 2011

PSSecurityException AuthorizationManager check failed on FAST installation

I just came across the following error when running the configuration wizard of the FAST installation:
Script execution failed System.Management.Automation.PSSecurityException: AuthorizationManager check failed.
It turns out that I had my Powershell ExecutionPolicy set to AllSigned instead of RemoteSigned.
Just the following simple command did the trick
Set-ExecutionPolicy RemoteSigned
Then I reran the wizard.

Friday, October 28, 2011

The located assembly's manifest definition does not match the assembly reference

I installed some WSPs and came across these errors when trying to add some web parts:
The located assembly's manifest definition does not match the assembly reference


Error replacing my site web parts. You may need to perform this task manually. Microsoft.SharePoint.ApplicationRuntime.SafeControls+UnsafeControlException: A Web Part or Web Form Control on this Page cannot be displayed or imported. The type is not registered as safe


There are many references to this everywhere. Typically this refers to a mismatch of a SafeControls directive in web.config and the actual DLLs loaded into the GAC, but in this case, they all match.

It turns out that my WSPs came from a ZIP file that was downloaded from the internet. As such, they were marked as unsafe. This caused DLLs to be marked as unsafe and were probably not loaded into the GAC properly. To work around this, unblock the zip file (or run streams to remove the blocks), uninstall the WSPs and then reinstall.

Monday, October 24, 2011

Changing welcome page without Publishing Feature enabled

I needed to change the welcome page on a site that did not have the Publishing feature enabled. Since that feature was not enabled, there was no Welcome Page option under Look and Feel. Rather than enabling and disabling the feature, I decided to do this through Powershell.

There are many references on how to do this including this forum post on "Change welcome page of a site collection using PowerShell"


$web = Get-SPWeb <my url>
$rootFolder = $web.RootFolder
$rootFolder.WelcomePage = "<my welcome page>"
$rootFolder.Update()

I tried to shorten it by doing the following
$web.RootFolder.WelcomePage = "<my welcome page>"
$web.RootFolder.Update()

Of course this didn't work because Update() will only work on an instance of RootFolder. It took me a while, but eventually I got it.

Saturday, October 22, 2011

Missing FAST Administration Links

I just upgraded some of my sites to SP1 + June CU and the Administration Links for FAST disappeared. Very simple fix described here: Updating SharePoint Server 2010 from RTM to December or later Cumulative Update disables FAST Search links in site collection administration (KB2521577)

Monday, October 17, 2011

Unable to install Hotfix for Microsoft Windows (KB976462)

While installing FAST Search for SharePoint, I came across this error:
Error: The tool was unable to install Hotfix for Microsoft Windows (KB976462). If Hotfix for Microsoft Windows (KB976462) is already installed you may need to uninstall it and run prerequisite installer again.

It turns out all I have to do is run the installer again since I was running Windows 2008 R2 SP1 which already has the necessary fixes.

Reference: KB2581903

Saturday, October 8, 2011

Formally learning SharePoint 2010

It's been a little over a year since I have started on SharePoint 2010. It was my first real exposure to SharePoint in any real depth (Yes, I have dabbled with SharePoint since STS, but never to an appreciable degree). Now I am planning to formalize some of my learning by taking a course and getting a certification. I figure the one I will go for is 70-667 TS: Microsoft SharePoint 2010, Configuring. Looking at the various offerings, it looks like the in class 10174 course is overkill (5 days, 9-5, $2000-3000). So, I have decided on the online collection 10278: Microsoft SharePoint 2010, Configuring course and supplement with various technet resources, virtual labs, other people's experiences such as How I passed SharePoint 2010 exam 70-667, and SharePoint 2010 Configuring 70-667 Exam Passed!.

Determining who has an open file handle on DLLs in the GAC

I recently needed to update a solution in my SharePoint farm however:
  1. The update required administration and connection permissions to the User Profile Service Application (UPA)
  2. Some assemblies in our solution was causing the the UPA to be inaccessible

So, my code is broken and needed update, my update is broken because it can't access UPA, my UPA is broken because of my code ... argh!

Then, I had this idea, figure out which DLLs were breaking the UPA and update those directly in the GAC, hoping that it will at least free up the UPA so the update. I figured my DLLs were reasonably compatible over the different versions. So this is what I did:
  1. Grab my updated WSPs
  2. Use 7-zip to open the WSPs and extract the DLLs I needed
  3. Open up the GAC (C:\Windows\Assembly)
  4. Copy the DLLs I need into the GAC
  5. Verify, by version number, that my DLLs were indeed copied into the GAC (I have seen cases where the copy seems to work, but nothing actually happens)
  6. iisreset
  7. restart owstimer
  8. Run my installer to update my code as normal.

This worked very well for me, but when a colleague tried it, he found that he was unable to get step 4 working. He kept getting access denied issues. It turns out that he had UAC turned on and some processes (not just iisadmin) had an open file handle on the very DLLs he needed to update. Getting around the UAC issue is just a matter of running things as administrator. To solve the file handle issue, we used Handle from Sysinternals

Now it was simply a matter of opening up a command prompt and doing something like this:
Handle.exe c:\Windows\assembly\gac_msil\<your DLL name>

Handle will also recurse into subdirectories for you! Now it's just a matter of stopping those processes and continuing on.


Friday, September 16, 2011

KB2560890 update without SharePoint SP1

It appears that the Security Update for Microsoft SharePoint Server 2010 (KB2560890) breaks the User Profile Service Application if you don't have SP1 installed for SharePoint 2010. The error I am seeing is:
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.ResourceManagement, Version=4.0.2450.34, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified
According to UserProfile not working after security update KB2560890, it seems like others are having the same issue.

The file list for KB2560890 refers to version 4.0.2450.34 of various Microsoft.resourcemanagement.* files, but does not specifically list Microsoft.ResourceManagement.dll.

In my GAC, I see the following:
Microsoft.ResourceManagement 4.0.2450.5

Microsoft.ResourceManagement.Service 4.0.2450.11

The machine had rebooted from the Windows Update. So, on a whim I decided to try shutting down and restarting the User Profile Service and the User Profile Synchronization Service (remember to iisreset if Central Administration is on the same machine).

I then checked back in my GAC and now I see the following:
Microsoft.ResourceManagement 4.0.2450.5
Microsoft.ResourceManagement 4.0.2450.34
Microsoft.ResourceManagement 4.0.2450.11
Microsoft.ResourceManagement.Service 4.0.2450.34
Microsoft.ResourceManagement.Service 4.0.2450.11

I can also manage my User Profile Service Application!

There's some sort of voodoo here, but as far as I can tell it works. Perhaps there was a continuation task after the Windows Update reboot that required yet another reboot. Who knows?!

Argh! Spoke too soon. If I go to Setup My Sites, I now get the following:
Cannot create an object of type 'Microsoft.SharePoint.Portal.WebControls.LocStringId' from its string representation 'SiteAdminPersonalSite_SocialSecurityTrimmerEnabledSectionTitle_Text' for the 'TitleLocId' property.

Time to give up and just do SP1 sometime in the future.

Thursday, September 15, 2011

SharePoint default members group

I recently had to try to determine the SharePoint Default Members Group of a particular site. In Site Actions->Site Permissions, you can go to a group and then click Make Default Group. What's bizarre is that there is no indication which group is default, at least not in the UI. The only way I could find is in PowerShell as follows:
$web = Get-SPWeb <myurl>
$web.AssociatedMemberGroup

or you can get the ID through the property bag at
$web.Properties["vti_associatemembergroup"]

Not sure which way is better, but either works for me so far. It would also be nice to see it in the UI.

Tuesday, September 13, 2011

Locking down web part zones

One use case in my SharePoint demo environment is to show that certain web part pages have mandatory web parts while others can be customized by the end user. The way to accomplish this is to put the web parts in different zones. Then add the following properties to the <WebPartPages:WebPartZone> element: AllowCustomization="False" AllowPersonalization="False" AllowLayoutChange="False"
Simple! Or you could do this using SharePoint Designer.

Saturday, August 27, 2011

Installing Office Web Apps

I have a single server farm that I use for demos and need Office Web Apps on it. The instructions can be found on TechNet: Deploy Office Web Apps (Installed on SharePoint 2010 Products) and are fairly straightforward. The only issue is that it is not supported on a domain controller which is the demo environment I have.

When I try to load any Word document, I get an error: Word Web App cannot open this document for viewing because of an unexpected error. To view this document, open it in Microsoft Word. There is some Error Id that I can't seem to correlate to anything.

Fortunately, there is a blog entry by Jie Li on Installation Notice for SharePoint 2010 Public Beta that describes steps to make this work:

Step 10 applies because I am running SharePoint on a domain controller. Here is the script from the blog. 
$acl = Get-Acl HKLM:\System\CurrentControlSet\Control\ComputerName
$person = [System.Security.Principal.NTAccount]"Users"
$access = [System.Security.AccessControl.RegistryRights]::FullControl
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]::None
$type = [System.Security.AccessControl.AccessControlType]::Allow
$rule = New-Object System.Security.AccessControl.RegistryAccessRule($person, $access, $inheritance, $propagation, $type)
$acl.AddAccessRule($rule)
Set-Acl HKLM:\System\CurrentControlSet\Control\ComputerName $acl
From what I can tell, all this is doing is allowing Full Control for all authenticated users on the HKLM:\System\CurrentControlSet\Control\ComputerName registry key. I'm not sure what this has to do with things, but oh well ...

Step 11 has some Powershell script for that appears to disable Sandboxed Solutions for the Office Web Apps service applications. Once again, I don't really know why, but it appears to work.
$e = Get-SPServiceApplication | where {$_.TypeName.Equals("Word Viewing Service Application")}
$e.WordServerIsSandboxed = $false

For the following commands, you will need to enter "Y" to confirm execution of each command
Get-SPPowerPointServiceApplication | Set-SPPowerPointServiceApplication -EnableSandboxedViewing $false
Get-SPPowerPointServiceApplication | Set-SPPowerPointServiceApplication -EnableSandboxedEditing $false

Then edit C:\Windows\system32\inetsrv\config\applicationHost.config and add the following line at the end of the <dynamicTypes> element.
<add mimeType="application/zip" enabled="false" />

Finally, do an iisreset 

I don't really know why all of this works. It looks like all we are doing is enabling Sandboxed Solutions Architecture only then to disable it on the Office Web Apps solutions. I would like to if anybody can explain it.

Friday, August 19, 2011

Search and replace text with Powershell

Just a Powershell newbie post: I am trying to search and replace text in a file using Powershell.

Get-Content <source-file> | ForEach-Object {$_ -replace <original-text>, <replacement-text>} | Set-Content <destination-file>

Thursday, July 14, 2011

import-csv with accented characters

I was trying to import some users into AD. The users are international and hence have some special characters in their names (such as French accents: é, ê, è). For some reason import-csv does not handle this properly and screws up the characters. Searching around, I found a post "Vista - import-csv missing charakters".

It turns out that I had to convert my original file to ASCII which can be done simply by:
cat file.csv > asciifile.csv

Then import-csv worked.

By the way, import-csv does not take pipeline input the way one would expect so you can't to something like get-content file.csv | csv-import


Monday, July 11, 2011

The located assembly's manifest definition does not match the assembly reference

I got the following error when I tried to access my manage my service application after changing my web application from NTLM to Basic authentication:
The located assembly's manifest definition does not match the assembly reference

It turns out all I needed to do was an iisreset and all is good again

Sluggish site, multiple authentication prompts - caused by stack overflow in IIS application pool worker process

On one of my servers, users were reporting:
  • Site was sluggish
  • Sometimes several authentication prompts

I check the site, and here is what I found:
In the ULS log, some messages logged by mssdmn.exe including:
CSTS3Accessor::Init: InitRequest failed for URL http://my-server/clientxyz/Pages/Home.aspx Return error to caller, hr=80041204  [sts3acc.cxx:546]  d:\office\source\search\native\gather\protocols\sts3\sts3acc.cxx

In the System log, regular Warning events logged by WAS, ID 5011 with the message:
A process serving application pool 'SharePoint - [my-server]80' suffered a fatal communication error with the Windows Process Activation Service. The process id was '12028'. The data field contains the error number.

In the Application log, regular Information events logged by Windows Error Reporting, ID 1001 with the message:
Fault bucket , type 0
Event Name: CLR20r3
Response: Not available
Cab Id: 0

Problem signature:
P1: w3wp.exe
P2: 7.5.7601.17514
P3: 4ce7afa2
P4: Microsoft.SharePoint
P5: 14.0.0.0
P6: 4bad8a7a
P7: 5cc9
P8: 0
P9: System.StackOverflowException
P10: 

Attached files:

These files may be available here:
C:\ProgramData\Microsoft\Windows\WER\ReportQueue\AppCrash_w3wp.exe_69fc9436e8b5896ded626b3ecf45dce746b517_3ed230ba

Analysis symbol: 
Rechecking for solution: 0
Report Id: 245f9c35-aaa0-11e0-96d0-f4ef7acc1a53
Report Status: 4

These all happened every 15 min - coincidentally the frequency of my incremental crawls

What can I conclude from this evidence? The W3WP is crashing. This would explain the users' various reports of sluggish behaviour and repeated authentication prompts. Now to figure out why the application pool process is crashing.

Some searching and I find this TechNet article Event ID 5011 - IIS Application Pool Availability under Troubleshoot Windows Server 2008 R2. So, I go ahead and download and install Debug Diagnostics x64. So far so good, but for some reason it runs only in Analyze Only mode. The documentation and help screens don't match the application. So, I thought I'd try the 32-bit one. This one matched the documentation, but is unable to attach to my w3wp.exe processes. Searching some more, I find that Debug Diagnostics is not supported on Windows 2008 R2 (major WTF moment!) and to follow How To: Collect a Crash dump of an IIS worker process on IIS 7.0 (and above) instead. So, I am now looking for WERCON. Well, of course this doesn't exist either, but I can read the .wer file with Notepad and this didn't give me much more information than the Application Log.

Frustrated, I give up on the diagnostics and try to do a little more experimenting. Is my FAST search crawler overloading the application pool? I create a Crawler Impact Rule to limit the crawler to one document request at a time. Still, this did not help.

Even more frustrated, I decide to see how much of an impact the crawl has. I go back to the ULS log and look at the URLs and try them out in a browser. Jackpot! The very first address I tried crashed the worker process. I try it a few more times and each time I got the same crash. 

Curious, I did more digging. The site was created at roughly the same time the WAS warning messages started showing up in the System log.

So, it turns out that one of my sites was causing the W3WP to crash and whenever the search crawler runs, it tries to crawl that site causing the crash. To workaround the problem, I added a new Crawl Rule to exclude the culprit site. This appears to have worked.


Saturday, June 25, 2011

"Windows server features or role services required by this product are not enabled" when installing Office Web Apps

I was trying to install Office Web Apps on my SharePoint server farm and came across this error when I launched the installer: "Windows server features or role services required by this product are not enabled"

I checked all the prerequisites listed under the Hardware and Software Requirements (SharePoint Server 2010) and they are all there.

After a bit of head scratching, I decided to launch Server Manager and see what roles and features were installed. I clicked on Add Feature and it complained that another user was still configuring a role. It turned out that when I was enabling the Desktop Experience Feature using a different account, however that required a reboot and was waiting for that account to login again in order to continue the installation of Ink and Handwriting Services. Once I logged in, that feature was successfully enabled.

Then the prerequisite check succeeded.

Thursday, June 16, 2011

Listing sites, their creators, template and date created

Just a simple Powershell script using the splat operator (which is quite new to me).


(Get-SPSite myurl).AllWebs | Select-Object url, @{label="Creator"; Expression={$_.Author}}, @{label="Template"; Expression={$_.WebTemplate}}, @{label="Date Created"; Expression={$_.Created}} | Format-Table -AutoSize


This returns a table of URL, Creator, Template and Date Created of each site in the site collection specified by myurl. Note that your screen needs to be wide enough to see the whole table otherwise some columns may not display.

Sunday, May 22, 2011

Host name validation failed when configuring FAST Search Server 2010 for SharePoint

This was extremely frustrating while trying to figure it out. Now that I have it is pretty obvious. I was configuring a FAST Search Server 2010 for SharePoint. In the Configuration Wizard at the Server settings screen, it asks for a Server name. The documentation says that this is the FQDN of the server. All my servers have their own name but also have an alias pointing to them. Of course, I always refer to these servers via their alias. So when it asked me for the server name, I naturally entered the alias. The wizard rejects this with a dialog box "Host name validation failed - Please provide a valid server name". I checked firewall settings, event logs and found nothing. It finally dawned on me to actually use the FQDN (easiest way to confirm this is to right click My Computer and select Properties) and it worked.

The strange thing is that if the wizard is able to determine an incorrect FQDN, then why couldn't it just set that value?

Tuesday, May 17, 2011

Cannot open database User Profile Service Application_SyncDB ... The login failed

Some of my servers were mysteriously no longer synchronizing the user profiles after some time. Upon further investigation this appeared to happen after a server reboot. Here is an error found in the Application Log with a source of Forefront Identity Manager:


.Net SqlClient Data Provider: System.Data.SqlClient.SqlException: Cannot open database "User Profile Service Application_SyncDB_35eb65afa42c4f8e9ece6a33e9348849" requested by the login. The login failed.
Login failed for user '[my user]'.
   at Microsoft.ResourceManagement.Data.Exception.DataAccessExceptionManager.ThrowException(SqlException innerException)
   at Microsoft.ResourceManagement.Data.DatabaseConnection.Open(SqlConnection connection)
   at Microsoft.ResourceManagement.Data.DatabaseConnection.Open(DataStore store)
   at Microsoft.ResourceManagement.Data.TransactionAndConnectionScope..ctor(Boolean createTransaction, IsolationLevel isolationLevel, DataStore dataStore)
   at Microsoft.ResourceManagement.Data.TransactionAndConnectionScope..ctor(Boolean createTransaction)
   at Microsoft.ResourceManagement.Data.DataAccess.RegisterService(String hostName)
   at Microsoft.ResourceManagement.Workflow.Hosting.HostActivator.RegisterService(String hostName)
   at Microsoft.ResourceManagement.Workflow.Hosting.HostActivator.Initialize()
   at Microsoft.ResourceManagement.WebServices.ResourceManagementServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses)
   at Microsoft.ResourceManagement.WindowsHostService.OnStart(String[] args)

A few seconds later in the log

Starting up database 'User Profile Service Application_SyncDB_35eb65afa42c4f8e9ece6a33e9348849'.

So, it looks like the Forefront Identity Manager Service is starting up before SQL has started the necessary databases. This appears to cause it to crash. Now that I figured out the problem, I do a search to figure out how to delay the start of the FIM Service and find this article: Troubleshoot User Profile Synchronization Service start issues (SharePoint Server 2010). Scrolling down to the bottom, there is a section titled "User Profile Synchronization service cannot start after a server restart" This suggests using the Services Manager to change the startup of the FIM services to "Delayed Start". (Note that this contradicts the Important note at the top of the article stating "Starting the FIM services manually or changing the FIM service configuration is not supported.").

Friday, May 13, 2011

Managed Service Accounts not supported by SQL Server

I have been setting up a new Active Directory Domain Services running in Windows Server 2008 R2 functional level. According to the documentation What's New in Services Accounts in Windows Server 2008 and Windows 7: "The managed service account is designed to provide crucial applications such as SQL Server and IIS with the isolation of their own domain accounts, while eliminating the need for an administrator to manually administer the service principal name (SPN) and credentials for these accounts." So I create an account to run the SQL services and install SQL server. However, when I try to pick the service account, my SQL user will not show up in the picker at all. Searching around some more, I come across the Managed Service Accounts Frequently Asked Questions (FAQ). It states: "The use of managed service accounts with Microsoft SQL Server is not supported." Argh!

Wednesday, May 11, 2011

Using Alternate Access Mappings to "change" the host header of a SharePoint web application

It looks like there is no easy way to change the host header of a SharePoint web application. This is unfortunate as I want to create many virtual instances of SharePoint and have precanned data for demo purposes. To get around this, I figured I can create the initial copy and then use Alternate Access Mappings (AAM) to provide another way to access my SharePoint sites. It looks like all I have to do is the following:
  1. Go to Central Administration->System Settings->Configure Alternate Access Mappings
  2. Select Edit Public URLs
  3. Change the default setting to the new URL using the new host header
  4. Go to IIS Manager
  5. Locate the IIS web site that has the binding for the old host header
  6. Add a new binding with the new host header
  7. Go to Central Adminstration->Application Management->Manage Service Applications
  8. Manage User Profile Service Application
  9. Click Setup My Sites
  10. Change the My Site Host location using the new host header
That seems to do do the trick. I hope I am not missing anything.

Here are some references:

MSDN Video: Microsoft SharePoint 2010: Alternate Access Mappings (Level 200)
What every SharePoint administrator needs to know about Alternate Access Mappings (Part 1) (Part 2) (Part 3)

Thursday, April 28, 2011

Receiving (401) Unauthorized when accessing SharePoint server using webclient

I was trying to build a quick script to check on the status of a bunch of SharePoint servers. This is the code I was using:


$webclient = New-Object System.Net.WebClient
$webclient.Headers.Add("user-agent", "Powershell webclient")
$webclient.Credentials = New-Object System.Net.NetworkCredential("usernam", "password", "domain")
$webclient.DownloadString("http://MySharePointServer.com")

However, this is the error I got:

Exception calling "DownloadString" with "1" argument(s): "The remote server returned an error: (401) Unauthorized."
At line:1 char:26
+ $webclient.DownloadString <<<< ("http://MySharePointServer.com")
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

I searched high and low but found nothing useful. Then out of the blue I thought I would try


$webclient.DownloadString("http://MySharePointServer.com/default.aspx")


and lo and behold, the page loaded. I guess there must be something going on where webclient does not handle the default document or something to do with how I setup my SharePoint site. I don't have time to dig deeper into the root cause, but problem solved, moving on.

Wednesday, April 20, 2011

Resizing Amazon EC2 Windows drives

The disk sizes that come with the Amazon Windows AMIs are a little small (35GB for a Windows 2008 R2). Since I am running demo servers I have not really been paying too much attention to laying out the disks properly. However, the 35GB disk is simply not enough so I had to resize it. This turned out to be surprisingly easy:
  1. Stop the instance
  2. Create a snapshot of the volume
  3. Create a new volume from that snapshot, specifying the new size
  4. Detach old volume from the instance
  5. Attach new volume to the instance
  6. Restart the instance
  7. Run diskpart and enter the following commands
    • select disk <disk number>
    • select volume <volume number>
    • extend
  8. Delete the old volume (unless you want to keep it as a backup)
Simple!

Sunday, April 17, 2011

Amazon EC2 Powershell environment setup

I always keep forgetting these so I figured I put them here:

$env:JAVA_HOME = 'C:\Program Files\Java\jre6'
$env:EC2_HOME = 'C:\Program Files\Amazon\ec2-api-tools'
$env:EC2_PRIVATE_KEY = '<path to private key>'
$env:EC2_CERT = '<path to cert>'
$env:Path = $env:Path + ";C:\Program Files\Amazon\ec2-api-tools\bin"

Resizing an Amazon EC2 instance

We had overbuilt some of our Amazon instances because we were not sure of the performance requirements. This was costing us lots of money so we recently started downsizing some of these instances. This is how I was doing it:

  1. Confirm that Ec2SetComputerName is disabled
  2. Stop the instance
  3. Launch a new instance in the same zone
  4. Stop the new instance
  5. Attach the volumes from the old instance to the new one
  6. Start the new instance
  7. Terminate the old instance
  8. Delete the volume that came with the new instance
  9. Reassociate the Elastic IP address


Wow, that was rather cumbersome, but that is the only way to do this via the EC2 console. Looking at the API, I found the following Powershell command that replaces steps 3 to 8:
ec2-modify-instance-attribute <instance-id> --instance-type <new-instance-type>

That's it! I can't believe I did it the hard way that many times.

Thursday, April 14, 2011

Changing the master page

I needed to change a master page today. It looks like if you want to do this through the web UI you first need to enable SharePoint Server Publishing Infrastructure site collection feature and the SharePoint Server Publishing site feature. Then there will be a link to Master Page Settings under Site Settings->Look and Feel. On top of that I found lots of complaints about the Top Link Bar disappearing after deactivating the publishing features. Sounds like a pain in the ass.

Well, instead of doing that through the Web UI, here's how you would do that through Powershell:
$web = Get-SPWeb "<site url>"
$web.MasterUrl = "<relative url to your master page>"
$web.Update()

Done! That's it. No screwing around with temporarily enabling features. Now, why doesn't the UI make it as easy? Who knows.

Wednesday, April 13, 2011

Parsing IIS logs with Powershell (because logparser not supported on Windows 2008)

I was very disappointed to find out that logparser is not supported on Windows 2008. So, I started to look for an alternative and found a TechNet post by Nick Goude on how to use Powershell to parse IIS logs.

I have, for the most part, simply lifted the code:


# Location of IIS LogFile
$File = "C:\inetpub\logs\LogFiles\W3SVC25824252\u_ex1104*.log"


# Get-Content gets the file, pipe to Where-Object and skip the first 3 lines.
$Log = Get-Content $File | where {$_ -notLike "#[D,S-V]*" }


# Replace unwanted text in the line containing the columns.
$Columns = (($Log[0].TrimEnd()) -replace "#Fields: ", "" -replace "-","" -replace "\(","" -replace "\)","").Split(" ")


# Count available Columns, used later
$Count = $Columns.Length


# Strip out the other rows that contain the header (happens on iisreset)
$Rows = $Log | where {$_ -notLike "#Fields"}


# Create an instance of a System.Data.DataTable
#Set-Variable -Name IISLog -Scope Global
$IISLog = New-Object System.Data.DataTable "IISLog"




# Loop through each Column, create a new column through Data.DataColumn and add it to the DataTable
foreach ($Column in $Columns) {
  $NewColumn = New-Object System.Data.DataColumn $Column, ([string])
  $IISLog.Columns.Add($NewColumn)
}


# Loop Through each Row and add the Rows.
foreach ($Row in $Rows) {
  $Row = $Row.Split(" ")
  $AddRow = $IISLog.newrow()
  for($i=0;$i -lt $Count; $i++) {
    $ColumnName = $Columns[$i]
    $AddRow.$ColumnName = $Row[$i]
  }
  $IISLog.Rows.Add($AddRow)
}


$IISLog

Now, if you save this to a file such as iislog.ps1, then you can run commands like:

.\iislog.ps1 | Select-Object csusername | Sort-Object -Property csusername | Get-Unique -AsString


Note, there are some glaring deficiencies:

  1. Parameterize the specification of log files
  2. Handle column name changes
  3. Handle extra headers (these are saved upon iisreset) - done
  4. Stream results back out so that they can be used in a pipeline

I hope to fix these soon, but need to get to sleep.

Monday, April 11, 2011

SPNavigationNode object won't take title

I was trying to script the creation of Quick Launch links. This appears to be quite straightforward. Here is the Powershell:
$SPSite = Get-SPSite "<some URL>"
$OpenWeb = $SPSite.OpenWeb()
$QuickLaunch = $OpenWeb.Navigation.QuickLaunch



$node = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Some Title", "<some URL", $true)

At this point I was curious to see what was in the $node object. So, I took a look and it looks something like this:


Title                  :
TitleResource          :
IsVisible              :
IsExternal             : True
Id                     : 0
ParentId               : 0
Parent                 :
Navigation             :
Url                    : <some URL>
LastModified           : 1/1/0001 12:00:00 AM
Children               : {}
Properties             :
TargetSecurityScopeId  : 00000000-0000-0000-0000-000000000000
TargetParentObjectType : Web

So, why is the Title blank? I tried a whole bunch of things with no luck. Then I read the documentation of SPNavigationNode more carefully. In the Remarks section, it states: "The new SPNavigationNode object is not completely initialized until it has been added to a collection. For more information, see the SPNavigationNodeCollection class."

Are you kidding me? Creating an object through a constructor does not fully create the object. You have to add it to some kind of collection and that has the side effect of filling in the rest of the properties. IMHO, that is very poor design.

Oh well, so I continued with adding the node with the following Powershell and all is good:
$QuickLaunch.AddAsLast($node)





Wednesday, March 30, 2011

Repeated "Request for install time of Application Server Role, Web Server (IIS) Role" messages

I was installing SharePoint prerequisites and it seemed to hang at the first step "Configuring application server role, Web Server (IIS) Role". The PrerequisiteInstaller process seems to stall there forever. Looking at the installation log at \AppData\Local\Temp\2 under my profile, I saw over 2500 instances of the message: "Request for install time of Application Server Role, Web Server (IIS) Role". In the System event log, there are thousands of events "Windows Servicing successfully set package <some-package>(<some-status>) to <some-status>(<some-status>). There are also many repeats of the same package and status (eg: update, installed, staged).

I don't really know why it took so long. However, the simple solution was to just wait it out and eventually the task succeeded. In the end, the prerequisite installation took 1h 15min.

Wednesday, March 9, 2011

Disabling automatic naming of machines in Amazon EC2

I run SharePoint 2010 in my Amazon EC2 instances. As a result, I do not want my machines automatically renamed by the EC2Config service when I stop / start them. This would totally screw up SharePoint as it does not behave well with machine name changes. Fortunately, Amazon EC2 has a way to do this via the EC2Config Service Settings executable or by directly editing C:\Program Files\Amazon\Ec2ConfigSetup\config.xml and changing the Ec2SetComputerName value to Disabled. The latter is quite handy as I had to stop and restart instances recently due to some deadlock issues.

Tuesday, March 8, 2011

Loading and modifying the registry of a dead Amazon EC2 instance

In a recent post, I had to troubleshoot an issue with an Amazon EC2 instance not accessible via RDP after Windows Update and reboot. Back then, I didn't realize that I could have edited the registry of the unresponsive instance. Here is how to do it (Thanks to Nick Greising at Amazon for providing me with the steps). You will first need a repair instance in the same zone.
  1. Note down instance information such as instance ID, attached block devices (volumes), private IP address, associated elastic IP address
  2. Stop the instance
  3. Detach the root volume
  4. Attach the volume to repair instance 
  5. Login to the repair instance
  6. Bring the disk online (eg: drive E)
  7. Run regedit
  8. Go to HKLM
  9. Select File->Load Hive
  10. Browse to E:\Windows\System32\config
  11. Open the hive you want (eg: SYSTEM)
  12. Pick a Key Name (eg: System_old)
  13. Make whatever changes you need
  14. Select the root of the hive you just loaded and modified (eg: HKLM\System_old)
  15. Select File->Unload Hive
  16. [Optional: Note if you are running SharePoint you may need to set Ec2SetComputerName to Disabled so the machine does not change names on restart]
  17. Take the disk offline
  18. You can now logoff or close the connection to the repair instance
  19. Detach the volume from the repair instance
  20. Attach volume to original instance
  21. Start instance
  22. You will also need reconfigure your security groups as the internal IP address would have changed and to reassociate the Elastic IP Address.
Now, I could just plop in the steps from Amazon EC2 instance not accessible via RDP after Windows Update and reboot into step 13 and I can repair those unresponsive instances. Note that when the hive is loaded, there won't be a CurrentControlSet. However, you can look at the value of HKLM\System_old\Select\Current to determine which ControlSet to use. See the knowledgebase article What are Control Sets? What is CurrentControlSet? for details.


Thursday, February 17, 2011

Limiting the People Picker in SharePoint

We have multiple SharePoint environments that share the same Active Directory. However, there are cases where we need to keep the various groups of users separated. Normally the People Picker will return results from the entire Active Directory.

Doing some quick research I found that some settings available through stsadm that control how the People Picker behaves. This is described in the Microsoft TechNet article on Configure the People Picker. In particular we were interested in 2 properties


  • peoplepicker-Peopleeditoronlyresolvewithinsitecollection - To force People Picker to only return users who have permissions in the site collection when the Check Names button is clicked
  • peoplepicker-onlysearchwithinsitecollection - To force People Picker to only return users who have permissions in the site collection when the Select People and Groups dialog box is used

It appears that the phrase "have permissions in the site collection" did not mean what I expected. I would have expected that this would include anybody who has security permissions to the site. Instead, it means that a permission is set. That is the user is in the SPWeb.AllUsers collection (ie: has accessed the system).

Furthermore, the Check Names button has more than one function. If you enter an exact match, then Check Names verifies the name you entered. If you enter a partial match, it actually does a search which is controlled by the peoplepicker-onlysearchwithinsitecollection property.

Clear as mud? 



Wednesday, February 16, 2011

Amazon EC2 instance not accessible via RDP after Windows Update and reboot

For the last couple of days, I have been running into a problem where my Amazon EC2 instance is no longer accessible via remote desktop after a Windows Update and a reboot.

My process for setting up these servers is pretty straightforward: Install SQL 2008, Install SharePoint 2010 Prerequisites, Install SharePoint 2010, run Windows Update. I have done this a couple of dozen times now without any problems. Just a couple of days ago, I was finding that after the Windows Update and ensuing reboot, the server comes up, status is active, but it is not accessible via RDP or HTTP (just times out).

My first thought was that one of the more recent Windows Updates is incompatible Amazon EC2. Comparing my last successful installation with the latest Windows Update packages, I found that the following might be the culprit:


  • Cumulative Security Update for Internet Explorer 8 for Windows Server 2008 x64 Edition (KB2482017)
  • Platform Update Supplement for Windows Server 2008 x64 Edition (KB2117917)
  • Security Update for Windows Server 2008 x64 Edition (KB2393802)
  • Security Update for Windows Server 2008 x64 Edition (KB2479628)
  • Security Update for Windows Server 2008 x64 Edition (KB2483185)
  • Security Update for Windows Server 2008 x64 Edition (KB2485376)
  • Update for Windows Server 2008 x64 Edition (KB971029)
  • Windows Malicious Software Remove Tool x64 - February 2011 (KB890830)

So, I'd figure I would try again and leave out these specific updates, but upon reboot, my new instance would also be unaccessible via RDP or HTTP.

Perplexed and after a lot of searching, swearing, hair pulling, I came across this post: Avoiding RDP connectivity issues when running SharePoint 2010 on Amazon EC2. In particular, it mentions the Microsoft Article KB2379016: A computer that is running Windows Vista or Windows Server 2008 stops responding at the "Applying User Settings" stage of the logon process which describes the problem as being a deadlock in the Service Control Manager database. To break the deadlock, it is just a matter of forcing HTTP.sys depend on CryptSvc. This can be accomplished as follows:
  1. Run regedit
  2. Locate and the registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP
  3. Create a New, Multi-string Value: DependOnService
  4. Set a single value CRYPTSVC
So far so good. Maybe I'll get some sleep tonight.
 




Wednesday, February 9, 2011

Visual Studio 2010 setup

I had been working with Visual Studio 2003 / 2005 / 2008 and now have 2010. As usual there are some little things to do with the initial setup so that I can be functional again.

Running without a local SharePoint environment
When I try to create a new solution using any of the SharePoint templates, I got the error: A sharepoint server is not installed on this computer is not installed on this computer
It seems like in order to do SharePoint development on VS 2010 I need to have a local SharePoint environment. Unfortunately, I don't have enough horsepower to run SharePoint on my local machine so I have to go with a workaround. I know that this is not ideal, but I don't have a choice at the moment. Searching around, I came across this thread: A SharePoint server is not installed on this computer. One of the posts describes a workaround which is to essentially copy the whole registry tree of the 14 hive. So I went to my SharePoint 2010 server and exported the following [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0] and imported into my development machine. I then restarted Visual Studio and magically I am now able to create SharePoint solutions.

Adding assemblies
Another consequence of not having SharePoint on my local machine, I don't have all the assemblies in the right place. The easy workaround is as follows:

  1. Copy C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI from your SharePoint Server
  2. Paste it into your local machine keeping the same folder hierarchy to be consistent
  3. Run regedit
  4. Add the key [HKLM]\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\SharePoint 2010 Assemblies. (Not sure if it's a Windows 7 change, but I now need to add this key instead: [HKLM]\SOFTWARE\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\SharePoint 2010 Assemblies).
  5. Set the default value to C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI

References: How to display an assembly in the "Add Reference" dialog boxHow to display your assembly "Add References" dialog.



Adding Create GUID
One of the tools I find useful is a GUID generator. For some reason this is not installed by default in VS 2010. The good thing is that it is very easy to do as described in the article: How to enable "Create GUID" option in Visual Studio 2010. The steps are as follows:

  1. Go to Tools->External Tools
  2. Click Add
  3. Enter a title (such as Create GUID)
  4. In the command box, browse to C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\guidgen.exe
  5. Click OK

Thursday, January 27, 2011

SharePoint PrerequisiteInstaller log file location

After running the PrerequisiteInstaller you sometimes want to check the log file. At first it wasn't obvious to me where this would be stored. However, with a bit of searching I found out that it's simply stored in the %temp% directory. (duh!)

So just cd %temp% and look for the PrerequisiteInstaller.*.log files.

Sunday, January 23, 2011

Moving the User Profile Service Application Synchronization Database

So, the problems with my Sync DB as I mentioned in a previous post finally caught up to me. Running low on disk space, we decided to add another block of disk space to the server and move the Sync DB over there.

Adding the volume on Amazon EC2 was very straightforward. It was just a matter creating a new volume, attaching it to the server, enabling and then formatting the drive. This is covered quite nicely in Attaching an EBS Volume to EC2.

Now with the drive ready, I needed to move the DB files over. The instructions for Moving User Databases are pretty straightforward. However, I ran into some hiccups - I had open connections to the database (from when I was troubleshooting the database size :-) ) and the command to take the database offline simply waits until those connections are closed and you're none the wiser. Also, the new files / locations need to have the right permissions otherwise you can't bring the database back online. So, here are my updated steps.

  1. Close all connections to your database. You can check for open connections by executing an sp_who2
  2. Take the database offline by running the following:
    ALTER DATABASE [Sync DB] SET OFFLINE
  3. Move the files to the new location
  4. Update the new location in the system catalog as follows (make sure you use your own location!)
    ALTER DATABASE [Sync DB] MODIFY FILE ( NAME = 'Sync DB', FILENAME = 'E:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\Sync DB.mdf' );
    ALTER DATABASE [Sync DB] MODIFY FILE ( NAME = 'Sync DB_log', FILENAME = 'E:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\Sync DB_log.LDF' );
  5. Make sure that the database user has the correct permissions to the database files. I just copied the original settings which is giving the SQLServerMSSQLUser group full control access to the DATA folder (and the new database files). 
  6. Bring the database back online by running the following:
    ALTER DATABASE [Sync DB] SET ONLINE
  7. Verify the file change by running the following:
    SELECT  name, physical_name FROM sys.master_files WHERE sys.master_files.database_id = DB_ID(N'Sync DB')
I still haven't gotten to the root cause of the database file being so large. However, I just needed to buy some time for now.


PowerTab

The tab autocompletion in Powershell has, by default, the same annoying behaviour as cmd. Fortunately, Powershell has a TabExtension function. The nice folks at PowerTab have written a richer tab extension similar to the intellisense found in Visual Studio.

I just grab the latest copy of the module and put it into C:\Windows\System32\WindowsPowerShell\v1.0\Modules. This way it always loads for every user. In the first startup I just took the default settings in the configuration wizard. It took a couple of minutes to build and that was it.

Friday, January 21, 2011

User Profile Service Application Synchronization DB size

I have a SharePoint instance that is running out of disk space. Doing some poking around, I found that the User Profile Service Application Sync_DB has grown to almost 7GB. So, I ran the following SQL query to get more insight into what is going on:
exec sp_MSforeachtable @command1="EXEC sp_spaceused '?'"
Looking through the results I see that the culprits are as follows:

namerowsreserveddataindex_sizeunused
ObjectsInternal31566182089728 KB800296 KB1288776 KB656 KB
InstanceData1779974698144 KB4697048 KB296 KB800 KB

I decided to take a peek inside these tables and it looks like there are thousands of objects created every day. So what are these and do they get cleared out any time?

I found a similar question asked: User Profile Service Application SyncDB Database Size. There is an response that is marked as an answer, but it merely leads us to recommended provisioning sizes of these databases to be medium to large (100GB to 1TB). There is no explanation why. This is quite bogus as I only have 75 profiles.

Argh!

I have posted a followup here: Moving the User Profile Service Application Synchronization Database

Wednesday, January 19, 2011

Automated or remote installation of components on an Amazon instance

I am trying to figure out a way to either have an Amazon instance install various software components automatically right after launch or to execute commands to do those installations remotely.

I have done some searching and so far have found the following references.

AMAZON EC2 - Launch command on remote Windows machine, given admin credentials

Unattended Amazon EC2 Install Script - Unfortunately, this is for Linux. I would have to figure out how to write a Windows equivalent, if at all possible

Perhaps the Invoke-Command Powershell cmdlet would help.



Unfortunately, I don't have time to investigate further so I will have to come back to this later.

Thursday, January 13, 2011

Insufficient winsock resources available to complete socket connection initiation / tcp error code 10048

I have been trying to track down this problem for some time. Here are the symptoms I have seen.
There are a bunch of "TCP error code 10048: Only one usage of each socket address (protocol/network address/port) is normally permitted" messages in the Application Log
There are a bunch of "Insufficient winsock resources available to complete socket connection initiation"
I cannot connect to my SharePoint site or sometimes cannot even open central administration
Running netstat and TCPView results in thousands of connections in TIME_WAIT

I am running Windows 2008 x64 R2. According to KB929851 The default dynamic port range for TCP/IP has changed in Windows Vista and in Windows Server 2008, the number of ports has been bumped from a default range of 1025-5000 to a range of 49152-65535. So, bumping up the value to  HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort does not help at all.

Also, these sockets are stuck in TIME_WAIT. By default the TIME_WAIT delay HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TCPTimeWaitDelay is 240 so these should have been cleaned up after 4 minutes anyway. So, why are they not being cleaned up?

Anyone who has an idea of what's going on, please feel free to comment. In the meantime, I'm just going to reboot.

Another reference: Hurry Up and TIME_WAIT

Wednesday, January 12, 2011

Generating XML file from SQL SELECT statement

I needed to generate an OPML (XML) file from data from a SQL Server 2008 SELECT statement. It's a bit of a hack job, but this is pretty much what I did:

/* Generate part of the OPML file from the database */
/* Make sure max characters is 8192 */
/* Send results to text or to file */
/* Need to manually merge the rows back together */
SELECT
'<?xml version="1.0" encoding="utf-8"?><opml><head />'
+ (SELECT [col1] as text
      ,[col2] as title
      ,[col3] as type
      ,[col4] as xmlUrl
      ,[col5] as htmlUrl
  FROM [mydb1].[dbo].[mytable1] t1
  inner join [mydb1].[dbo].[mytable2] t2 on t1.id = t2.id
        for xml raw ('outline'), root ('body'))
+ '</opml>'

Reference: Constructing XML Using FOR XML.

Sunday, January 9, 2011

User Profile Service Application stuck in Synchronization state

I had a User Profile Synchronization job stuck in the Synchronizing state. Clicking Stop did nothing. I also tried stopping the User Profile Synchronization Service, but got the following error:

An update conflict has occurred, and you must re-try this action. The object UserProfileApplication Name=User Profile Service Application was updated by [farm admin id], in the OWSTIMER (7292) process, on machine [machine name].  View the tracing log for more information about the conflict.
I didn't see anything more helpful in the ULS logs, but I did see the same errors in the Application Log (Event Viewer)

Apparently, this is due to a well known problem with the cache in SharePoint 2010 (although it would be nice to know the cause). In any case, here's how you would fix it (as described in An update conflict has occurred, and you must re-try this action, but adapted to SharePoint 2010).
  1. Stop the timer service by doing the following:
    1. Click Start->Administrative Tools->Services
    2. Right click SharePoint 2010 Timer, select Stop
  2. Delete the contents of the folder: C:\ProgramData\Microsoft\SharePoint\Config\<some GUID>
  3. Start the timer service by doing the following
    1. Click Start->Administrative Tools->Services
    2. Right click SharePoint 2010 Timer, select Start
Once the timer is restarted, the cache folder will rebuild itself.

I was then able to go back into Manage my User Profile Service Application and stop the running sync job. 

Saturday, January 8, 2011

Language packs

I needed to setup a demo site, en francais. A couple of simple searches and it all seemed very straightforward. Well, there's one catch. For some reason, I didn't clue in to the fact that the instructions I found for SharePoint Foundation, which came up first in my search, were not for me. It's all obvious now - I needed My Site Host which is a feature in SharePoint Server. Therefore I should have used the instructions for SharePoint Server. Actually, the instructions are exactly the same except that the language packs they refer to are different.

In any case, if you need other languages, make sure you get the right language packs and instructions for your installation - either for SharePoint Foundation or SharePoint Server. If you need to know the differences between the two editions go to this blog entry to Compare SharePoint Editions.

Here are a few exceptions found in the ULS log - reformatted for easier reading or in case a search got you here :-)

Failed to create personal site ([username], [personal site URL]): System.ArgumentException: File or arguments not valid for site template 'SPSPERS#0'.  Parameter name: WebTemplate
     at Microsoft.SharePoint.SPWebTemplateCollection.get_Item(String strKey)
     at Microsoft.SharePoint.SPWeb.ApplyWebTemplate(String strWebTemplate)
     at Microsoft.SharePoint.Administration.SPSiteCollection.Add(SPContentDatabase database, SPSiteSubscription siteSubscription, String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String secondaryContactLogin, String secondaryContactName, String secondaryContactEmail, String quotaTemplate, String sscRootWebUrl, Boolean useHostHeaderAsSiteName)
     at Microsoft.SharePoint.SPSite.SelfServiceCreateSite(String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String contactLogin, String contactName, String contactEmail, String quotaTemplate, SPSiteSubscription siteSubscription)
     at Microsoft.Office.Server.UserProfiles.UserProfile.<>c__DisplayClass2.<CreateSite>b__0()


My Site creation failure for user '[username]' for site url '[site URL]'.  The exception was: Microsoft.Office.Server.UserProfiles.PersonalSiteCreateException: A failure was encountered while attempting to create the site.  ---> System.ArgumentException: File or arguments not valid for site template 'SPSPERS#0'.  Parameter name: WebTemplate
     at Microsoft.SharePoint.SPWebTemplateCollection.get_Item(String strKey)
     at Microsoft.SharePoint.SPWeb.ApplyWebTemplate(String strWebTemplate)
     at Microsoft.SharePoint.Administration.SPSiteCollection.Add(SPContentDatabase database, SPSiteSubscription siteSubscription, String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String secondaryContactLogin, String secondaryContactName, String secondaryContactEmail, String quotaTemplate, String sscRootWebUrl, Boolean useHostHeaderAsSiteName)
     at Microsoft.SharePoint.SPSite.SelfServiceCreateSite(String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String contactLogin, String contactName, String contactEmail, String quotaTemplate, SPSiteSubscription siteSubscription)
     at Microsoft.Office.Server.UserProfiles.UserProfile.<>c__DisplayClass2.<CreateSite>b__0()
     --- End of inner exception stack trace ---
     at Microsoft.Office.Server.UserProfiles.UserProfile.<>c__DisplayClass2.<CreateSite>b__0()
     at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.<RunWithElevatedPrivileges>b__2()
     at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
     at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param)
     at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode)
     at Microsoft.Office.Server.UserProfiles.UserProfile.CreateSite(String strRequestUrl, Boolean bCollision, Int32 lcid)


Exception while creating personal site for 'EASTCLOUD\administrator': Microsoft.Office.Server.UserProfiles.PersonalSiteCreateException: A failure was encountered while attempting to create the site. ---> System.ArgumentException: File or arguments not valid for site template 'SPSPERS#0'.  Parameter name: WebTemplate
     at Microsoft.SharePoint.SPWebTemplateCollection.get_Item(String strKey)
     at Microsoft.SharePoint.SPWeb.ApplyWebTemplate(String strWebTemplate)
     at Microsoft.SharePoint.Administration.SPSiteCollection.Add(SPContentDatabase database, SPSiteSubscription siteSubscription, String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String secondaryContactLogin, String secondaryContactName, String secondaryContactEmail, String quotaTemplate, String sscRootWebUrl, Boolean useHostHeaderAsSiteName)
     at Microsoft.SharePoint.SPSite.SelfServiceCreateSite(String siteUrl, String title, String description, UInt32 nLCID, String webTemplate, String ownerLogin, String ownerName, String ownerEmail, String contactLogin, String contactName, String contactEmail, String quotaTemplate, SPSiteSubscription siteSubscription)
     at Microsoft.Office.Server.UserProfiles.UserProfile.<>c__DisplayClass2.<CreateSite>b__0()
     --- End of inner exception stack trace ---
     at Microsoft.Office.Server.UserProfiles.UserProfile.<>c__DisplayClass2.<CreateSite>b__0()
     at Microsoft.SharePoint.SPSecurity.<>c__DisplayClass4.<RunWithElevatedPrivileges>b__2()
     at Microsoft.SharePoint.Utilities.SecurityContext.RunAsProcess(CodeToRunElevated secureCode)
     at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(WaitCallback secureCode, Object param)
     at Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges(CodeToRunElevated secureCode)
     at Microsoft.Office.Server.UserProfiles.UserProfile.CreateSite(String strRequestUrl, Boolean bCollision, Int32 lcid)
     at Microsoft.Office.Server.UserProfiles.UserProfile.CreatePersonalSite(Int32 lcid)



What I do find annoying is why Microsoft keeps changing the edition naming conventions with every release:

  • SharePoint Team Services (STS) / SharePoint Portal Server (SPS)
  • Windows SharePoint Services (WSS) / Microsoft Office SharePoint Server (MOSS)
  • SharePoint Foundation / SharePoint Server

What's next?

Thursday, January 6, 2011

Creating predefined groups in site collection created by Powershell

Here's another discrepancy between what the UI does and what the Powershell scripts seem to do. As I'm in the process of scripting a manual creation process, one of the things I want to do is create a site collection. Looking at Technet you get instructions to Create a site collection (SharePoint Server 2010).

However, doing it via Central Administration vs via Powershell has a slight difference. If you create your site collection via the web UI you get a handful of SharePoint groups automatically created, but not if you create it via Powershell.

With the Powershell approach, there are "No predefined Groups in sitecollection created with Powershell". All you need to do is to call the CreateDefaultAssociatedGroups() method of the SPWeb object.

Here's the code I used:

New-SPSite -Url $sp_sc_url -Name $sp_sc_name -Template $sp_sc_template -OwnerAlias $sp_sc_owner -SecondaryOwnerAlias $sp_sc_owner2 -Language $sp_sc_language
$sp_web = Get-SPWeb $sp_sc_url
$sp_web.CreateDefaultAssociatedGroups($sp_sc_owner, $sp_sc_owner2, "")


Wednesday, January 5, 2011

Adding site collection administrators via Powershell

I was setting up a SharePoint server using Powershell scripts. Since my team manages the server I wanted to add them all as Site Collection Administrators on the top site, My Site and the Search Center. This turned out to be fairly straightforward but searching for a reference proved quite frustrating.

What I wanted to do is to use Powershell to do the equivalent of going to Site Actions->Site Settings,
Users and Permissions: Site collection administrators and then adding my team members to that list. If you are following along with your installation you will see that it does indeed call these users "Site Collection Administrators". However, do any search and you will come across articles such as "Add or remove site collection administrators (SharePoint Server 2010)" or "Add or remove site collection administrators (SharePoint Foundation 2010)" both of which clearly state "A site collection can only have two administrators ...".

Major head scratching commences. Lots of searching, swearing ...

Then I figured why not look at how the web UI does it. You will notice that the page that manages this is /_layouts/mngsiteadmin.aspx. Looking carefully I couldn't help but wonder why it's called Manage Site Admin. Subtle, but it's a clue.

Doing some searching and poking around I found that the SPWeb object has a SiteAdministrators property which as an Add() method. So, I tried calling SiteAdministrators.Add() with a user reference. There was no error, but nothing happened. So, I did more searching and eventually I came across this post: Adding more than two site collection administrators programmatically. Bingo!

Here's my code:
$sp_web = Get-SPWeb <URL>
$sp_web.AllUsers.Add("<username-1>", "<email-1>", "<name-1>",  "<notes-1>")
$sp_web.AllUsers.Add("<username-2>", "<email-2>", "<name-2>",  "<notes-2>")
...
$sp_web.AllUsers | where { "<username-1>", "<username-2>", ... -contains $_.UserLogin } | foreach { $_.IsSiteAdmin = "True"; $_.Update() }

Here's the lesson learned. What Microsoft has been calling Site Collection Administrators really has 2 meanings:
  1. Site Owners and Secondary Owners
  2. Site Administratrators
These are quite different and a good post that describes it is: Difference between Site Administrators and Site Collection Administrators and Site Collection Owners.


So clear now! What I was really trying to do is to add Site Administrators.