SharePoint 2007 Installation Service Accounts

Saturday, September 24, 2011


Figuring out what service accounts are needed to setup SharePoint can be pretty confusing.  There's a whole novella on MSDN with excruciating detail on all the different combinations of AD and SQL accounts you could use.  I had to scrape pieces of my brain off the walls after reading through that monstrosity.

But after doing a few buildouts, I've found that a basic setup is actually very simple.  And unless you have a specific reason to do otherwise (like having to satisfy a security requirement), sticking with the basic setup is the best way to stay sane.

There's a ton of information in the MSDN article about what permissions each account needs.  But, you really only have to worry about permissions for ONE account: the install account. The SharePoint setup and configuration wizards will automatically assign appropriate permissions for the rest of the service accounts!

I recommend creating a separate install account just for doing the SharePoint setup.  The install account must be a local Administrator on each SharePoint server, as well as the SQL server.  It should have sysadmin and dbcreator roles in SQL.  Run the SharePoint setup and config wizards under that account account.  In fact, it's a good idea to simply log in as the install account to do all your setup.

(On a side note, I've seen a lot of cases where people resolve permission issues by making the Farm account or other service accounts local Administrators. Only the install account should be a local Admin, and only for doing the initial setup! If you have to make other service accounts local Admin, there's probably something mis-configured.)

Once setup is complete, all administrative privileges for the install account can be revoked.

All in all, I typically use 1 install account, and 5 service accounts:

Account Description
Install Account This is the account I login to each server as to do the buildout. Before doing the setup, you have to manually make this account a local Administrator on each server. It also needs to have sysadmin and dbcreator roles in SQL.

After the initial setup of SharePoint, this account is no longer needed.
Farm Account Runs Central Admin app pool and SP Timer service.
SSP Account Runs SSP Admin app pool, as well as individual SSP app pools
Search Account Runs the Search services (Windows SharePoint Services Search service, and Office SharePoint Server Search service)
Crawl Account Default account used to crawl content
Web Application Account Runs web application app pool. I usually create a separate app pool account for each web application

Trick Restroom

Wednesday, September 14, 2011


We just moved to a new office this week with walls whiter than a toothpaste ad and sqeaky clean restrooms. An interesting observation about the restroom dawned on me today: there are no urinals.  All stalls.  I went back to the door, looked at the loo next door and saw this:

Hmm.  Went back, did my business, went out--took another look around.  I'd been going the left one all week long...

Blogger Post Summaries & Thumbnails, Part II

Monday, September 05, 2011


This is Part II on how to make Blogger display post summaries with thumbnail previews.  Part I goes over exactly what we're trying to accomplish and how the results will look.

The process described here should work on all the out-of-box Blogger templates.  Complications may arise if you're using a heavily customized template... Be sure to save a copy of your template before making any changes!

Edit Template

First, we have to open the blog template for editing.  On your blog's Administration page, go to Template, then click on Edit HTML:

Check Expand Widget TemplatesBefore continuing, save a copy of the full template just in case.

Insert Summary Generation Script

Next, we insert a piece of javascript to generate the summaries.  Search for the following tag in the template: <b:includable id="main" var="top">

Copy and paste the code in this file into the space circled in red above:

Update Post Body Template

Finally, we update the template that renders a post to invoke the summary creation script if the current page is the Home page.  If we're on an individual post page or a static page, then display the full post body as normal.

To do so, search for the following tag in the template: <b:includable id="post" var="post">.  Then, search for <data:post.body/> beneath that.  Note that there may be more than one <data:post.body/> in the template, and we specifically want the one under that first tag:

Replace the tag with the contents of this file:

That's it!  Save the template and you should start seeing post summaries on your blog. For reference, here's the entire default Simple template with the added code.

Working with Thumbnails

By default, the first image in post will be used as the thumbnail.  You can override this behavior on specific posts by setting the class attribute on its images (from the post editor's HTML view).  Note that the attributes are case-sensitive.

  • - To use an image other than the first as the thumbnail, set that image's class to preview
  • - To specifically prevent an image from being used as the thumbnail, set its class to noPreview
  • - To use a completely different thumbnail, add the thumbnail image to the post, and set its class to hiddenPreview.  This image will not be visible on the full post, but will be used as the thumbnail for the summary.  I'd recommend putting this at the very end of the post.

For instance, the update below would cause the second image to be used as the thumbnail:

The end!

Blogger Post Summaries & Thumbnails, Part I

Monday, September 05, 2011


So I stumbled on some Blogger templates and decided to give my poor, tired blog a makeover.  I fell hard for the pretty ones with the flyout menus, post summaries, thumbnails and all.  Unfortunately, like so many of my flirtations with pretty things, it ended only in despair and disappointment.  My blog ended up looking nothing like what the previews promised, mainly because:

  • - The thumbnail images were stretched to fit, instead of cropped.  They looked absolutely atrocious unless the first picture in all my posts happened to be square.
  • - The preview text was one big blob of text since HTML elements like line breaks, coloring, and bullet points were being stripped.
  • - I couldn't use an image other than the first in a post as the thumbnail preview

That can't fly!  I did some digging and cooked up a short script to generate summaries.  It should work with most Blogger templates, and for sure the out-of-box ones.  Here's how it looks applied to the default "Simple" template.  I can create posts with any formatting and images of any size.

The Home page shows the first few lines of each post, with a "Read More" link to the full post.  Note that formatting like linebreaks and bullets are preserved.  The 200 x 200 thumbnails are then cropped from the top left corner of the first image (unless otherwise specified) in the post.

Read Part II for how to implement this.


Monday, September 05, 2011


Found a new background for my windows phone!  This just makes my day :)  If I ever become a billionaire the first thing I'd do is build a collosus.  Oh... you drive a SUV?  *steps over SUV*  WHAT NOW??!

Filamente - Filtering List Items

Monday, September 05, 2011


Once in a while an irresistible urge to write code takes hold of me, and writing code is suddenly more important than breathing air.  Or eating food.  Or sleeping.

So despite flying to the east coast and back this week with babies inconsiderately bawling all out bloody murder and pillaging on the plane, I pounded out a long-overdue feature for Filamente: item filtering on SharePoint lists and libraries.

There are two limitations with SharePoint's filtering that really bug me.  You can't select more than one filter value per column, and can't filter freetext columns at all.  I hit that pretty much every time I need to filter something so I decided to implement support for both those scenarios in Filamente.

For instance, show all items with Priority P2 or P3:

Or, show files whose name contains the term "hyperion":

Pretty nifty, if I do say so myself  :P  We should be rolling out this feature in the next couple weeks.


Monday, September 05, 2011


I read a great article by Joel Marks on the New York Times Opinion Pages: The Confessions of an Ex-Moralist.  He hits on the crux of a big kink in my belief system. 

Coincidentally, vegetarianism was the flashpoint for both of us.  It made me realize that my general belief in utilitarianism / consequentialism doesn't really jive with my reasons for being vegetarian.  It's instead a gut -level conviction that some acts like the slaughter of animals or genocide are categorically morally wrong.  But my rational side has a hard time accepting that any act can be inherently wrong.

Mark's answer is that there's no morality at all and actions are neither right nor wrong.  Everything comes down to personal preference.  Some people enjoy coffee, some don't.  Some find beauty in nature, some don't.  In the same way, some people find goodness in compassion for animals, and some don't.  The "goodness" of treating animals humanely doesn't derive from any moral authority, divine or otherwise.  Its source is him, and me, and anyone who happens to share that preference.

I'm not sure what to make of this view... In a way it does resolve the disconnect (by saying the issue isn't even valid)  But an amoral world seems like a very scary place.  If it doesn't make sense to ask whether an act is moral or not, how would we know how to act?  I can't see a system existing in a complete vacuum.  Even math and physics are built on fundamental axioms that have not or cannot be proven.  Is a belief system without any fundamental assumptions about morality even a system?  Or just people doing whatever they want, whenever they want?

Debugging Sandboxed Solutions

Monday, September 05, 2011


This is a silly thing that took me about 30 minutes to realize... I was trying to debug a SharePoint 2010 Sandboxed solution by attaching to the w3wp.exe process, but none of the breakpoints were hitting.  It turns out for Sandboxed code you have to attach to SPUCWorkerProcess.exe instead.  *facepalm*


Monday, September 05, 2011


I was introduced today to SPDisposeCheck (, which checks your code for violations against the (absolute, sacred, and inviolable) Best Practices for disposing Sharepoint objects.  Probably old news to most SharePoint developers.  But I'm a nub.

SPDisposeCheck can run standalone or as a Visual Studio plugin. 

You can configure it to run automatically after every build and flag potential violations as errors or warnings.

I had a couple false positives, but pretty nifty tool overall.

A Small Elegy

Monday, September 05, 2011


This piece by Czech poet Jiri Orten is one of the most emotional poems I've read:

My friends have left. Far away, my darling is asleep.
Outside, it's as dark as pitch.
I'm saying words to myself, words that are white
in the lamplight and when I'm half-asleep I begin
to think about my mother. Autumnal recollection.
Really, under the cover of winter, it's as if I know
everything---even what my mother is doing now.
She's at home in the kitchen. She has a small child's stove
toward which the wooden rocking horse can trot,
she has a small child's stove, the sort nobody uses today, but
she basks in its heat. Mother. My diminutive mom.
She sits quietly, hands folded, and thinks about
my father, who died years ago.
And then she is skinning fruit for me. I am
in the room. Sitting right next to her. You've got to see us,
God, you bully, who took so much. How
dark it is outside! What was I going to say?
Oh, yes, now I remember. Because
of all those hours I slept soundly, through calm
nights, because of all those loved ones who are deep
in dreams---Now, when everything's running short,
I can't stand being here by myself. The lamplight's too strong.
I am sowing grain on the headland.
I will not live long.


The white words against the darkness, the recollection of a mother--herself living in the past, the false hope of sowing grain and the abruptness and finality of the closing line build up a sense of despair and isolation that's simply overwhelming.

I never had a wooden rocking horse.  I'm writing this on a sunny afternoon, with so many possibilities before me.  Yet, Orten's words bring me to the end of the road, where everything precious has been lost.  Like a madman who rages at nothing, I don't know what was lost--only that it was precious.

Eerily enough... according to Wikipedia, Orten died at age 22 after being struck by an ambulance and refused treatment at a hospital for being Jewish.

Sending data from codebehind to javascript

Monday, September 05, 2011


*Feb 2015 Edit: For a solution to the slightly more complex problem of asynchronously calling server-side code from Javascript, and sending back the results, check out my ICallbackEventHandler post.

A few days ago I had to implement a page that lets users apply filters to a dataset (from SharePoint) without reloading the page.  My initial thought was to either:

  1. Use an ajax UpdatePanel.  This would require a postback, but the user wouldn't notice it.
  2. Use jQuery to make a webservice call to the SharePoint search service, and update the page with the results.  This would happen completely on the client side.

    Unfortunately, for this particular project both ajax and the search service were off limits.  Also, the dataset was tiny (< 50 rows) so posting back or re-querying seemed like a waste.  Some research led to a very elegant third option:

    1. Get the entire dataset before the page renders (in codebehind)
    2. Serialize the dataset to JSON format
    3. Render the JSON dataset onto the page as a javascript variable so that it can be manipulated clientside

    Now the JSON data can filtered completely on the client side using jQuery or plain javascript.  This option doesn't require postbacks or hitting a webservice, and the JSON data can be manipulated in object oriented fashion.

    Here's an example with two simple datamodel classes, Company and Employee:

    Say we have a method GetAllCompanies() that returns an array of Companies, which we want to manipulate client side.  First we have to serialize the array into JSON.  Luckily, there there's a JavaScriptSerializer under the System.Web.Script.Serialization namespace that does exactly that.  Next we render the JSON string onto the page as a javascript variable:

    If you look at the page source after the page loads, there should be a script block with the JSON data that looks like something like this:

    Now the object oriented data in the 'companies' variable can be manipulated from javascript!

    Javascript blocks are processed top to bottom, so make sure the JSON script block appears above any script that uses that data.  Otherwise, the variable will be undefined.

    Accessing SharePoint Webservices behind Forms-based Authentication or ISA server

    Monday, September 05, 2011


    In the warm, fuzzy .Net world...

    Accessing webservices on a SharePoint site using FBA takes a little extra work.

    In .Net, it's pretty simple. In fact, there's a MSDN article with code samples and all on precisely how to do that. In summary, you first call the Login method on Authentication.asmx, and use the returned cookie in all future web service requests.

    Outside .Net

    One dark and stormy night, I ventured out into the non-Microsoft world.  No-man's land.  Without the .Net generated web service proxies, we were rolling our own SOAP messages to communicate with SharePoint webservices.

    Where's my cookie??

    Without the .Net proxy, you can't use CookieContainer as the MSDN article suggests. Authentication.asmx's description for Login shows the following SOAP response:

    The response XML simply contains the authentication cookie's name.  Where did the actual cookie go? GIMME MY COOKIE!!!

    Getting the cookie

    It turns out the cookie is sent in the SOAP header. If login is successful, the response's SOAP header will look something like this:

    The Set-Cookie field above gives us the FBA cookie called .ASPXAUTH, with value 987A98.......

    Using the cookie

    To use the cookie for web service requests, we need to include it in the SOAP request header by adding a Cookie field:

    You can include multiple cookies by separating the name/value pairs with semi-colons. Once the .ASPXAUTH cookie is set, you can send the request and a response should be returned as normal.

    No-man's land behind ISA lines

    SharePoint sites behind an ISA server with Forms authentication can be handled similarly. The difference is that we have to get the authentication cookies from the ISA server instead of SharePoint. That can be done by POSTing to the /CookieAuth.dll?Logon url. I won't go over the details, but it shouldn't be hard to figure out the appropriate url and querystring to use.

    A Bad Analogy

    Monday, September 05, 2011


    I love poetry and bad analogies. I especially love when those two things come together: limericks!  All kinds of random analogies germinate on my drive home from work. Most are abominations.

    I came across the cutest tabby cat napping in a used book store the other day... which resulted in this:

         There was a young man who'd often pine
         For a feline so sinuous and fine
         On the books 'neath the sign
         It reclined, quite supine
         Like fat cones on a thick bough of pine