<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Build on SharePoint</title><subtitle type="html">The blog of Sam Betts on SharePoint application development - full of lot&amp;#39;s of useful info, guides, and various cats.</subtitle><id>http://blogs.msdn.com/b/sambetts/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/sambetts/atom.aspx" /><generator uri="http://telligent.com" version="5.6.50428.7875">Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><updated>2012-04-19T16:55:18Z</updated><entry><title>Set SharePoint Content Database in Read-Only Mode</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2013/05/06/set-sharepoint-content-database-in-read-only-mode.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2013/05/06/set-sharepoint-content-database-in-read-only-mode.aspx</id><published>2013-05-06T18:23:56Z</published><updated>2013-05-06T18:23:56Z</updated><content type="html">&lt;p&gt;This a quick &amp;amp; easy one; I couldn’t find any MSFT material on how to do this as easily as I thought I might, hence this article. &lt;/p&gt;  &lt;p&gt;A simple question: how do you set a SharePoint content database to read-only? You may’ve seen the setting “Read-Only” in Central Administration and wondered “how do I make it say ‘yes’?”. Well the answer is surprisingly simple – you set it as read-only in SQL Server - SharePoint then picks up on this change and then disables any operations that would allow users anything more than read access to that content databases – for all sites in it.&lt;/p&gt;  &lt;p&gt;The following is supported in all versions of SharePoint from 2007 service-pack 2 (SP3 is the only currently supported patch-level at the time of writing) to SharePoint 2013.&lt;/p&gt;  &lt;h1&gt;Setting a Content DB to Read-Only&lt;/h1&gt;  &lt;p&gt;Here we have a typical content database, in read-write mode as we’re accustomed to.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6318.image_5F00_00DDF880.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="Sam Betts SP14 - test content DB" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5327.image_5F00_thumb_5F00_3F634626.png" width="635" height="309" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Let’s change that in SQL Server Management Studio. Right-click on the database in question &amp;amp; go-to the options section:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3757.image_5F00_68F71159.png"&gt;&lt;img title="image" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="Sam Betts SP14 - test content DB in SSMS" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3348.image_5F00_thumb_5F00_2E2F6883.png" width="627" height="444" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Change this property to “True” and select OK. You’ll be prompted with this message:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8547.image_5F00_1E4023BF.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6472.image_5F00_thumb_5F00_195D7003.png" width="578" height="121" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is warning you any open connection will be dropped. SharePoint &lt;em&gt;should&lt;/em&gt; be fine as it’ll just reconnect transparently thanks to some ADO.Net SQL connection abstraction trickery but as SQL Server doesn’t know this so it’s warning you just in case. If you’re worried about this, change the read-only property in a maintenance window.&lt;/p&gt;  &lt;p&gt;Confirm the change; SQL won’t restart, neither will SharePoint (although there’ll be a very small pause as SharePoint re-establishes new connections to SQL Server). That’s it, you’re done!&lt;/p&gt;  &lt;p&gt;Just for the record, if you don’t have SSMS installed you can just run the same in a direct command of course:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;ALTER DATABASE&lt;/font&gt; [WSS_Content] &lt;font color="#0000ff"&gt;SET READ_ONLY&lt;/font&gt; WITH &lt;font color="#0000ff"&gt;NO_WAIT&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;GO&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h1&gt;Checking Read-Only Mode&lt;/h1&gt;  &lt;p&gt;You should now see this in Central Admin:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4426.image_5F00_1C2324F6.png"&gt;&lt;img title="image" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3733.image_5F00_thumb_5F00_7A574C64.png" width="654" height="433" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;That’s pretty much it. SharePoint will now disable anything that’s related to modifying the database on any sites in that content database. More info on exactly what happens to a site in read-only mode can be found @ &lt;a title="http://technet.microsoft.com/en-us/library/dd793608.aspx" href="http://technet.microsoft.com/en-us/library/dd793608.aspx"&gt;http://technet.microsoft.com/library/dd793608.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2766.image_5F00_588B73D3.png"&gt;&lt;img title="image" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2251.image_5F00_thumb_5F00_768981C7.png" width="650" height="414" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Cheers!&lt;/p&gt;  &lt;p&gt;// Sam Betts&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10416415" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author><category term="read-only" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/read_2D00_only/" /><category term="sharepoint foundation" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/sharepoint+foundation/" /><category term="content db" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/content+db/" /><category term="sql server" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/sql+server/" /></entry><entry><title>My Sites Error - HTTP 403 (forbidden) on EditProfile.aspx</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2013/04/26/my-sites-error-http-403-forbidden-on-editprofile-aspx.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2013/04/26/my-sites-error-http-403-forbidden-on-editprofile-aspx.aspx</id><published>2013-04-26T10:09:25Z</published><updated>2013-04-26T10:09:25Z</updated><content type="html">&lt;p&gt;Just a quick one as I had this error occur on a test environment and couldn’t find much about it online.&lt;/p&gt;  &lt;p&gt;If you get the error HTTP 403 when you try and edit a profile in My Sites (/_layouts/EditProfile.aspx?accountname=[account]&amp;quot;) then fear not, it’ll most likely be because you’ve set the ‘portalsuperreaderaccount’ and ‘portalsuperuseraccount’ properties for the web-application and you’ve not given these accounts access to the My Sites web-application.&lt;/p&gt;  &lt;p&gt;In the ULS logs of the web-front-end in question you’ll probably see errors like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2642.image_5F00_2283F121.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7838.image_5F00_thumb_5F00_1A201BCA.png" width="669" height="281" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;The Fix&lt;/h2&gt;  &lt;p&gt;Add the users you’ve set for these properties to the web-application “User Policy&amp;quot; with “full-read” and “full control” rights as appropriate.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0160.image_5F00_381E29BE.png"&gt;&lt;img title="image" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1145.image_5F00_thumb_5F00_0475BD60.png" width="558" height="349" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;That’s it – no restarts or anything required – hit F5 and you’re good to go!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10414195" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author><category term="profiles" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/profiles/" /><category term="my sites" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/my+sites/" /><category term="error" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/error/" /></entry><entry><title>SharePoint 2013 and SQL Server AlwaysOn - High Availability SharePoint</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2013/04/24/sharepoint-2013-and-sql-server-alwayson-high-availability-sharepoint.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2013/04/24/sharepoint-2013-and-sql-server-alwayson-high-availability-sharepoint.aspx</id><published>2013-04-24T16:10:10Z</published><updated>2013-04-24T16:10:10Z</updated><content type="html">&lt;h1&gt;What is AlwaysOn and why use it for SharePoint?&lt;/h1&gt;  &lt;p&gt;AlwaysOn is a great new feature to SQL Server 2012 that allows consuming clients to have a mirroring and failover database solution all transparently for a single named instance. SharePoint is one such consumer of SQL and depends on having a solid connectivity to run. If SQL goes down, so does SharePoint so it’s well within our interests to configure a bullet-proof SQL Server solution that just won’t die.&lt;/p&gt;  &lt;p&gt;In this blog post we’ll set up an AlwaysOn cluster for a SharePoint 2013 farm in the following stages:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create SharePoint databases.&lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;Configure a SQL alias for a consistent SQL instance name.&lt;/li&gt;      &lt;li&gt;Create farm on SQL instance/replica 1, creating all databases needed (service-apps &amp;amp; web-apps).&lt;/li&gt;      &lt;li&gt;Stop SharePoint so databases remain static during migration to an AlwaysOn cluster.&lt;/li&gt;   &lt;/ol&gt;    &lt;li&gt;Create AlwaysOn high-availability group.&lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;Restore all the DBs onto SQL replica 2 (with NORECOVERY).&lt;/li&gt;      &lt;li&gt;Create AlwaysOn availability group &lt;/li&gt;      &lt;li&gt;Join the replica 2 databases to availability group.&lt;/li&gt;      &lt;li&gt;Create listener.&lt;/li&gt;   &lt;/ol&gt;    &lt;li&gt;Migrate SharePoint onto AlwaysOn on cluster &lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;Reconfigure SQL alias for new listener.&lt;/li&gt;      &lt;li&gt;Restart SharePoint services with updated alias.&lt;/li&gt;   &lt;/ol&gt;    &lt;li&gt;Test failover and that SharePoint can survive it.&lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;The failover process in action&lt;/li&gt;      &lt;li&gt;Why SharePoint doesn’t survive the 1&lt;sup&gt;st&lt;/sup&gt; time.&lt;/li&gt;   &lt;/ol&gt; &lt;/ol&gt;  &lt;h1&gt;Test Environment Details&lt;/h1&gt;  &lt;p&gt;For this demonstration I’ll be using a “super-cluster” configuration just because it’s the mother of all high-availability solutions. Each member for the AlwaysOn cluster will itself be a failover cluster with shared disks rather than a standalone machine. Why? That way we have instance redundancy &lt;em&gt;and&lt;/em&gt; data redundancy too, all for the same logical SQL Server instance. Normally the two instances will be mirroring each others’ data but if one replica &lt;u&gt;node&lt;/u&gt; goes offline the affected replica will live on no worries, and even if a whole replica (both nodes) does goes offline we can just failover to the other. The two replica members for this cluster will be:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;SQL cluster 1&lt;/b&gt; (primary replica) - SQL-SP2013\SP15&lt;/li&gt;    &lt;li&gt;&lt;b&gt;SQL cluster 2&lt;/b&gt; (secondary replica) - SQL2-SP2013\SP15B&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Both these instances are also on their own subnet so we’re covered for a whole bunch of doomsday scenarios – that being the whole point of this setup and blog-post. The parent cluster uses a file-share witness on a 3rd subnet to verify connectivity out of the subnet, or a routing failure.&lt;/p&gt;  &lt;p&gt;To span both subnets we’re going to create a single logical SQL Server instance with IPs in both subnets 1 &amp;amp; 2, for SharePoint to connect to. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8357.image_5F00_106C6EDB.png"&gt;&lt;img title="image" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8357.image_5F00_thumb_5F00_5610F8F9.png" width="542" height="357" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is the SQL backend we’re aiming for in this example – it’s a cluster of clusters! Please note and to reiterate; for AlwaysOn to work this “cluster-of-clusters” setup isn’t required; you can setup an AlwaysOn cluster with just x2 standalone SQL Servers too, it’s just a single node failure would result in loss of mirroring whereas both replicas being failover clusters themselves allows us to survive&lt;strong&gt; up-to 3 simultaneous machine failures&lt;/strong&gt; in our SQL Server cluster without breaking into a sweat! And that’s the goal here; a zombie SQL setup that just won’t die, for a SharePoint farm to lean on.&lt;/p&gt;  &lt;h1&gt;Create a SharePoint Farm on an AlwaysOn Cluster&lt;/h1&gt;  &lt;p&gt;Before we create a farm let’s connect to our two instances that’ll make up the replicas in the AlwaysOn cluster.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8357.clip_5F00_image004_5F00_49A2D5D0.jpg"&gt;&lt;img title="clip_image004" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="clip_image004" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2061.clip_5F00_image004_5F00_thumb_5F00_7A55DD7B.jpg" width="262" height="355" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Both SQL clusters instances are ready and empty.&lt;/p&gt;  &lt;h2&gt;Create SharePoint Databases&lt;/h2&gt;  &lt;h4&gt;Prepare SQL Alias&lt;/h4&gt;  &lt;p&gt;We need to fool SharePoint into thinking the SQL server where we'll create the configuration database is called something else. That’s because when you create a farm, whatever destination server you use during the “create new farm” stage isn’t forgotten (to simplify), so first thing’s first let’s create fake alias for our SQL “server” – “SP15” as it’s SharePoint 2013 that’ll use it (version 15). As far as SharePoint needs to know everything is going into a SQL box called 'SP15'.&lt;/p&gt;  &lt;p&gt;Now assuming you don’t have SQL Server tools installed (which you shouldn’t if it’s on production!) you’ll need to use a tool called “cliconfg.exe” to create a SQL alias. Run it; click the “Alias” tab, and the Add button.&lt;/p&gt;  &lt;p&gt;Add a name – &lt;b&gt;SP15&lt;/b&gt; for the alias name, but it can be anything - instead of referencing a server-name we’ll reference the name of the alias which will transparently redirect traffic to the alias destination instead. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8764.clip_5F00_image005_5F00_58F637DF.png"&gt;&lt;img title="clip_image005" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="clip_image005" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0312.clip_5F00_image005_5F00_thumb_5F00_69FA65C2.png" width="363" height="194" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Install &amp;amp; Configure Farm&lt;/h4&gt;  &lt;p&gt;The next thing we need to do is create all the databases we’ll need on the farm. For this example I’ll use a standard, home-baked script to create my basic services, accounts, and applications – and their corresponding databases:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Farm (1 database; SharePoint configuration)&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Service Apps:&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;User-profiles (3 databases; profiles; social; sync)&lt;/li&gt;        &lt;li&gt;Enterprise search (4 databases;&lt;/li&gt;        &lt;li&gt;State service (1 database)&lt;/li&gt;        &lt;li&gt;Usage &amp;amp; health service (1 database)&lt;/li&gt;     &lt;/ul&gt;      &lt;li&gt;Content apps:&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;Default port-80 web-application (1 database)&lt;/li&gt;     &lt;/ul&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;We’re not so worried about having the perfect configuration at the moment so much as just getting the databases created.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4520.clip_5F00_image007_5F00_5D8C4299.jpg"&gt;&lt;img title="clip_image007" style="display: inline; background-image: none;" border="0" alt="clip_image007" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6761.clip_5F00_image007_5F00_thumb_5F00_2DEE240D.jpg" width="597" height="268" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The PowerShell script, doing the business. Notice the “database server” name is our faked alias and yet there’s no problem; aliases are very useful for this.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4604.clip_5F00_image008_5F00_6149E769.png"&gt;&lt;img title="clip_image008" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="clip_image008" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6354.clip_5F00_image008_5F00_thumb_5F00_640F9C5C.png" width="224" height="456" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;SQL instance 1 now with all the databases we’re now going to add to a High-Availability (HA), AlwaysOn group.&lt;/p&gt;  &lt;h4&gt;Stop SharePoint so databases remain static during migration&lt;/h4&gt;  &lt;p&gt;We now have everything we need to create the single SQL point of access. First thing’s first though, let’s stop any updates happening to any SharePoint database happening until we're all setup by shutting the SharePoint services down – IIS, SharePoint timer are the important ones. We’ll restart them once we’ve updated the alias to use the AlwaysOn group and SharePoint will be none the wiser.&lt;/p&gt;  &lt;p&gt;And we’re done with SharePoint for now.&lt;/p&gt;  &lt;h2&gt;Create SQL Server AlwaysOn Group&lt;/h2&gt;  &lt;h4&gt;Restore all the DBs onto SQL instance 2 (with NORECOVERY)&lt;/h4&gt;  &lt;p&gt;Next thing we need to do is copy the databases to the 2&lt;sup&gt;nd&lt;/sup&gt; instance. Part of the AlwaysOn wizard can do this automatically for you if both instances have exactly the same database file locations however we can't do this as each failover replica has its own shared cluster-disk for its’ data files, and each disk has its’ own drive letter, therefore the paths will never match-up. And that’s a shame, but we have to do this the hard way.&lt;/p&gt;  &lt;p&gt;To join the 2&lt;sup&gt;nd&lt;/sup&gt; replica we need to run a full backup of all the databases on replace 1 but for now we’ll start with just the Central Administration content DB. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4101.clip_5F00_image010_5F00_775052FB.jpg"&gt;&lt;img title="clip_image010" style="display: inline; background-image: none;" border="0" alt="clip_image010" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6648.clip_5F00_image010_5F00_thumb_5F00_2EB6642A.jpg" width="431" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Take a full backup. Copy to destination server. Restore.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3000.clip_5F00_image012_5F00_745AEE48.jpg"&gt;&lt;img title="clip_image012" style="display: inline; background-image: none;" border="0" alt="clip_image012" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1033.clip_5F00_image012_5F00_thumb_5F00_64D7DC79.jpg" width="429" height="356" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;No need to create a new empty database. Just directly restore &amp;amp; SQL will create the necessary bits &amp;amp; pieces for you.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1018.clip_5F00_image014_5F00_11809653.jpg"&gt;&lt;img title="clip_image014" style="display: inline; background-image: none;" border="0" alt="clip_image014" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1018.clip_5F00_image014_5F00_thumb_5F00_01FD8484.jpg" width="488" height="406" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Important&lt;/b&gt;: the restore needs to be done with the NORECOVERY option. If this isn’t done, AlwaysOn can’t use the database.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3678.clip_5F00_image015_5F00_758F615A.png"&gt;&lt;img title="clip_image015" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="clip_image015" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7457.clip_5F00_image015_5F00_thumb_5F00_74B6FB70.png" width="240" height="127" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Once successful, the database will stay in the “restoring” state. Don’t worry about this – it’s just SQL is basically saying the DB isn’t usable from this instance, for now.&lt;/p&gt;  &lt;h4&gt;Create AlwaysOn availability group on one database&lt;/h4&gt;  &lt;p&gt;Next, we’re going to create our AlwaysOn instance. We’re going to only add the Central Admin content DB to the group for now…it’ll be clear later why.&lt;/p&gt;  &lt;p&gt;On the primary server (SQL-SP2013 in this example), expand “AlwaysOn High Availability” (this requires you to enable AlwaysOn in the SQL Server Configuration Manager) and click “New Availability Group Wizard…”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7457.clip_5F00_image017_5F00_33A87C0C.jpg"&gt;&lt;img title="clip_image017" style="display: inline; background-image: none;" border="0" alt="clip_image017" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6864.clip_5F00_image017_5F00_thumb_5F00_645B83B7.jpg" width="406" height="374" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Add name. This will be the name of the role added to the parent cluster. Click “Next”.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7848.clip_5F00_image019_5F00_3C48D498.jpg"&gt;&lt;img title="clip_image019" style="display: inline; background-image: none;" border="0" alt="clip_image019" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0676.clip_5F00_image019_5F00_thumb_5F00_41B7453C.jpg" width="474" height="440" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is where we specify which databases to add to the HA group. We’ve only backed up one the CA content DB so this is only one we can add for now. &lt;/p&gt;  &lt;p&gt;Also this screen is a good place to point out something this technique requires that SharePoint doesn’t by default configure – a full recovery model for databases. We’ll change this later, but for now we just want to create the HA group. Click Next.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8103.clip_5F00_image021_5F00_19386328.jpg"&gt;&lt;img title="clip_image021" style="display: inline; background-image: none;" border="0" alt="clip_image021" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4774.clip_5F00_image021_5F00_thumb_5F00_509E7456.jpg" width="479" height="445" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here’s where we specify which SQL instances will make up our AlwaysOn HA group. Click “Add Replica” and connect to the 2&lt;sup&gt;nd&lt;/sup&gt; instance. We’ll create a listener later; just accept the defaults for now.&lt;/p&gt;  &lt;p&gt;Important notes here about the AlwaysOn configuration:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The default is “asynchronous commit” for data-safety settings which basically means the primary instance doesn’t wait for the secondary instance to confirm its’ COMMIT until the primary does its’ own COMMIT for any updates to the AlwaysOn databases. This isn’t necessarily unsafe but there’s a small potential for data loss should the network breakdown between instances during an update of some kind, however performance is much better. &lt;strong&gt;We care about safety over speed in this example, so we’re going to “synchronous commit”.&lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;You can have the secondary instance as a read-only instance but this slows down the machine so it’s off by default. Obviously if there’s a failover the secondary instance will start accepting sessions again from SharePoint but enabling this is probably not necessary right now.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6825.clip_5F00_image023_5F00_560CE4FA.jpg"&gt;&lt;img title="clip_image023" style="display: inline; background-image: none;" border="0" alt="clip_image023" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5758.clip_5F00_image023_5F00_thumb_5F00_0D72F629.jpg" width="348" height="324" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here’s where we kick-start the synchronisation. Again, SQL Server can save a lot of pain here &amp;amp; do everything for you (saving you the whole backup/restore process above) but as I mentioned, my SQL instances have different drive-letters for their data-stores so a full synchronisation will never work. We’ll go with “Join”.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2210.clip_5F00_image025_5F00_0C2E5D4A.jpg"&gt;&lt;img title="clip_image025" style="display: inline; background-image: none;" border="0" alt="clip_image025" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5824.clip_5F00_image025_5F00_thumb_5F00_2A989E33.jpg" width="348" height="324" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After a while, this should be what you see. If you get any error it’s likely because the backup/restore wasn’t done correctly – check the backup was a &lt;b&gt;full&lt;/b&gt; backup? &lt;/p&gt;  &lt;p&gt;Also it’s worth mentioning there’s some clustering considerations AlwaysOn requires like making sure each replica failover instance can’t be cross-hosted; I’m not sure why this is, but you’ll need to make sure if you have a cluster-of-clusters as I do here each cluster member can only host one failover cluster or the other, but not both.&lt;/p&gt;  &lt;p&gt;Assuming it worked you should you be able to right-click on the availability group, select “Dashboard” and see this wonderful screen of green:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2703.clip_5F00_image027_5F00_0938F897.jpg"&gt;&lt;img title="clip_image027" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="clip_image027" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4834.clip_5F00_image027_5F00_thumb_5F00_55908C38.jpg" width="686" height="472" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;A couple of points here:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;We’ve configured the group for &lt;b&gt;synchronous&lt;/b&gt; commits for both nodes. Again, this has a performance hit as a round-trip “ok” is needed before any writes are completed, but it is the safest. This makes little difference for SharePoint sites that are read-heavy compared to writes; a publishing site say, but could drag if lots of updates occur instead, say in a collaboration site. You can run in asynchronous mode which doesn’t wait for the ACK from the secondary node before continuing, but that’s at the risk of losing data.&lt;/li&gt;    &lt;li&gt;For the same reason the “failover readiness” says “no data loss”. If we were running &lt;em&gt;async&lt;/em&gt; commits this would say “data loss” for the secondary databases but this is just over-dramatizing the fact replica 1 doesn’t wait for replica 2 to commit before committing itself, so it can’t know the failover commit occurred and therefore it assumes the worst. If you want absolute guarantees and don’t mind the performance hit, make the AlwaysOn group perform synchronous commits. &lt;/li&gt;    &lt;li&gt;&lt;font color="#008000"&gt;Green&lt;/font&gt; is good; if one day it turns not-green (i.e. you have an unexpected failover or communication failure) then you need to figure that out with your DBA/networking people – don’t blame me, I’m just a SharePoint guy :)&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Restore remaining databases to SQL machine 2&lt;/h4&gt;  &lt;p&gt;Next up; we need to set every database that isn’t already configured to full recovery that mode. I’d point out that there are possible supportability issues here in that the product-group haven’t &lt;i&gt;officially&lt;/i&gt; said this is a supported action or not – I say this as a disclaimer on the very slim off-chance there are issues with changing the recovery model on SharePoint databases. There shouldn’t be any issues though although performance is obviously faster if simple transaction-logging is used.&lt;/p&gt;  &lt;p&gt;It’s fairly simple to change the recovery model – right-click on a database, open “options”, select the recovery model there and press OK. That’s it – no downtime or restarts or anything needed.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4010.clip_5F00_image029_5F00_21E81FDA.jpg"&gt;&lt;img title="clip_image029" style="display: inline; background-image: none;" border="0" alt="clip_image029" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6866.clip_5F00_image029_5F00_thumb_5F00_2756907E.jpg" width="460" height="414" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Do this for any database not in full-recovery mode. That’ll be:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Any search database.&lt;/li&gt;    &lt;li&gt;Any user-profile app database.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Next, backup each database as before. Copy as before.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8535.clip_5F00_image031_5F00_69E62BF6.jpg"&gt;&lt;img title="clip_image031" style="display: inline; background-image: none;" border="0" alt="clip_image031" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4807.clip_5F00_image031_5F00_thumb_5F00_690DC60C.jpg" width="244" height="93" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Restore as before (WITH NORECOVERY). Now your SQL Server Management Studio should look something like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4885.clip_5F00_image033_5F00_44100593.jpg"&gt;&lt;img title="clip_image033" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="clip_image033" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0268.clip_5F00_image033_5F00_thumb_5F00_425F39BF.jpg" width="667" height="459" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Scripting restores can be quicker than managing the GUI for multiple DBs at once (if they’re not overly complicated in file-structure that is). All databases are now ready to add to the high-availability group!&lt;/p&gt;  &lt;h4&gt;Add databases to availability group&lt;/h4&gt;  &lt;p&gt;On the primary instance, expand the AlwaysOn groups; right click on ours and select “Add Database”. We should now see the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8015.clip_5F00_image035_5F00_2BBCEB78.jpg"&gt;&lt;img title="clip_image035" style="display: inline; background-image: none;" border="0" alt="clip_image035" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4370.clip_5F00_image035_5F00_thumb_5F00_78147F19.jpg" width="563" height="523" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Select them all &amp;amp; click next. Again, we’re joining only as we’ve restored the exact copy to the 2&lt;sup&gt;nd&lt;/sup&gt; SQL replica. The process is basically as before just with a “connect” section to authorise.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7587.clip_5F00_image037_5F00_7663B345.jpg"&gt;&lt;img title="clip_image037" style="display: inline; background-image: none;" border="0" alt="clip_image037" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7585.clip_5F00_image037_5F00_thumb_5F00_1B14CABD.jpg" width="463" height="430" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is hopefully what you’ll see. If some database(s) don’t join because of insufficient transaction-log data with this error:&lt;/p&gt;  &lt;p&gt;The mirror database, &amp;quot;[database]&amp;quot;, has insufficient transaction log data to preserve the log backup chain of the principal database. This may happen if a log backup from the principal database has not been taken or has not been restored on the mirror database. (Microsoft SQL Server, Error: 1478)&lt;/p&gt;  &lt;p&gt;If you see that persistently despite being sure of a full backup &amp;amp; restore, try again but just backing-up and restoring the transaction log to the same database(s) this time. It worked for me anyway.&lt;/p&gt;  &lt;h4&gt;Create SQL AlwaysOn Listener&lt;/h4&gt;  &lt;p&gt;We’re almost done with SQL; our SharePoint databases are mounted and are perfectly syncing one to the other, and in fact there’s nothing stopping us from directly using the old connection-string again knowing that our changes will be mirrored to the 2&lt;sup&gt;nd&lt;/sup&gt; SQL instance. However we want a more automatic failover process than that – we want an abstract instance name that’s independent of which replica is the active one, and that’s what SQL AlwaysOn listeners give us.&lt;/p&gt;  &lt;p&gt;Right-click on the HA group “SP15-SQL” again and click “Add Listener”. This is more of a network-admin type thing but the idea is to create IPs in both subnets. We give it a name which will be the equivalent of a generic clustered end-point and a port-number to listen on. Behold:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3365.clip_5F00_image039_5F00_325FCF2E.jpg"&gt;&lt;img title="clip_image039" style="display: inline; background-image: none;" border="0" alt="clip_image039" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2870.clip_5F00_image039_5F00_thumb_5F00_57E94C8F.jpg" width="504" height="454" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Click OK. This has now happened:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8231.clip_5F00_image041_5F00_21982480.jpg"&gt;&lt;img title="clip_image041" style="display: inline; background-image: none;" border="0" alt="clip_image041" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6253.clip_5F00_image041_5F00_thumb_5F00_40026569.jpg" width="673" height="481" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The listener has a DNS record, computer account in AD, and the assigned IPs. Test it by pinging it. Clustering is awesome!&lt;/p&gt;  &lt;h2&gt;Add SharePoint Servers to the farm&lt;/h2&gt;  &lt;h4&gt;Configure SQL alias for listener&lt;/h4&gt;  &lt;p&gt;So that’s about it for the SQL side. We now need to add our SharePoint servers to use this new “server” we’ve setup, but given it’s on a non-standard port we need to use SQL aliases to get there with a simple name. How handy we have one as we needed to fool SharePoint into thinking the SQL Server name so we’re in luck – we’ll just update the alias with the new details!&lt;/p&gt;  &lt;p&gt;Open “cliconfg.exe” again and edit the alias. Enter the listener name, select TCP/IP, unselect “dynamically determine port” and enter the port-number we assigned for the listener.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7635.clip_5F00_image042_5F00_6C3EEC4D.png"&gt;&lt;img title="clip_image042" style="display: inline; background-image: none;" border="0" alt="clip_image042" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2450.clip_5F00_image042_5F00_thumb_5F00_72198FE6.png" width="471" height="254" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Accept all changes. Repeat this on all SharePoint servers.&lt;/p&gt;  &lt;h4&gt;Restart SharePoint services (with updated SQL alias)&lt;/h4&gt;  &lt;p&gt;The final stage in this journey now we’ve moved everything and have updated the alias is to restart all SharePoint services on our starting server and finally add any further servers to the same configuration database necessary. Start IIS &amp;amp; SPTimer and SharePoint will have no idea it’s now looking at a difference SQL instance. &lt;/p&gt;  &lt;p&gt;Connection success (again)! Continue the wizard as normal &amp;amp; repeat, lather and rinse for any remaining SharePoint servers.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8787.clip_5F00_image044_5F00_50B9EA4A.jpg"&gt;&lt;img title="clip_image044" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="clip_image044" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4578.clip_5F00_image044_5F00_thumb_5F00_1A68C23B.jpg" width="740" height="394" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;All SharePoint cares about is that its’ databases are on a SQL Server called “SP15”. Make sure this alias is consistent for all your SharePoint servers.&lt;/p&gt;  &lt;h2&gt;Test the Failover – Will SharePoint Survive?&lt;/h2&gt;  &lt;p&gt;So now’s the important bit – the main reason for doing all this is to ensure the continued uptime of SharePoint should the SQL back-end drop unexpectedly (even failover clusters go down sometimes). Suffice to say this blog is long enough as it is; I’ll just show what happens on a manual failover and you’ll have to believe that it kicks in automatically when various nodes go offline or don’t (assuming configured correctly). &lt;/p&gt;  &lt;p&gt;The keyword here is “test” because as we’ll see, SQL will failover perfectly to the 2&lt;sup&gt;nd&lt;/sup&gt; replica but SharePoint &lt;b&gt;won’t&lt;/b&gt; survive for reasons we’ll see in just a moment…&lt;/p&gt;  &lt;p&gt;So once we’re convinced we have both replicas talking and syncing to each other perfectly, we’re going to failover to the 2&lt;sup&gt;nd&lt;/sup&gt; replica (SQL2-SP2013\SP15B). Right-click on the HA group again and select “Failover…”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3173.clip_5F00_image046_5F00_1204ECE4.jpg"&gt;&lt;img title="clip_image046" style="display: inline; background-image: none;" border="0" alt="clip_image046" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6523.clip_5F00_image046_5F00_thumb_5F00_2C64DFFB.jpg" width="458" height="426" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This confirms what we’re about to do is “safe” – we’re running in synchronous mode so all update transactions are always guaranteed safe. Click next, then connect to the 2&lt;sup&gt;nd&lt;/sup&gt; replica with an appropriate login and start the failover.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7774.clip_5F00_image048_5F00_7C5A8E79.jpg"&gt;&lt;img title="clip_image048" style="display: inline; background-image: none;" border="0" alt="clip_image048" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8322.clip_5F00_image048_5F00_thumb_5F00_7245ED4E.jpg" width="459" height="423" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Success! If you have the dashboard of the AlwaysOn group of the 1&lt;sup&gt;st&lt;/sup&gt; replica, it might show all sorts of critical errors but it’ll straighten itself out once it works out the primary is now the secondary. Close it and open the dashboard on the previously secondary replica and it should show all OK.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6354.clip_5F00_image050_5F00_37EA776D.jpg"&gt;&lt;img title="clip_image050" style="display: inline; background-image: none;" border="0" alt="clip_image050" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5518.clip_5F00_image050_5F00_thumb_5F00_6426FE51.jpg" width="587" height="538" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Everything is now being run by our 2&lt;sup&gt;nd&lt;/sup&gt; replica. Ping SP15 and you’ll see the DNS has updated too.&lt;/p&gt;  &lt;h4&gt;But SharePoint is Down!&lt;/h4&gt;  &lt;p&gt;&lt;strong&gt;Agghh! The farm has been floored! Nightmare!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Yes indeed. This is also why planned, regular failovers are a good idea because you can never be certain of what’ll happen on a failover until it happens. You’ll notice SharePoint may now be complaining that various key accounts are being denied login by SQL Server. Well that simple why; your farm accounts probably aren’t known by the 2&lt;sup&gt;nd&lt;/sup&gt; replica endpoint.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: add the accounts to SQL as per this article (&lt;a href="http://technet.microsoft.com/en-us/library/cc678863.aspx"&gt;http://technet.microsoft.com/en-us/library/cc678863.aspx&lt;/a&gt;) and check everything is working as with both replicas being used. Make sure to check:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;All web-applications (default web-app; my-sites)&lt;/li&gt;    &lt;li&gt;All service applications (Search; UPA; Excel Services, etc.)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If something isn’t working with one replica active but on another one it is then there’ll be a difference in permissions. &lt;strong&gt;Testing is vital here&lt;/strong&gt;; make sure you run through every service &amp;amp; app that’ll use different credentials and ensure each one works with each replica member in the cluster being the primary.&lt;/p&gt;  &lt;h2&gt;Important&lt;/h2&gt;  &lt;p&gt;&lt;b&gt;Don’t change anything in the failover cluster manager&lt;/b&gt;! I’m told by my SQL friends this will render the cluster in an unsupported state as there’s all sorts of meta-data that Management Studio needs &amp;amp; reads which the Cluster Manager does not. &lt;/p&gt;  &lt;h2&gt;Wrap-Up&lt;/h2&gt;  &lt;p&gt;This has hopefully shown the benefits in mounting SharePoint in an AlwaysOn cluster and how that can work. Later we’ll experiment with some of the options AlwaysOn gives us and the farm configuration in this example is far from ideal, but the key stage explained here is how to mount the SharePoint databases at least.&lt;/p&gt;  &lt;p&gt;SharePoint is increasingly becoming critical to have online; this is yet another way we can make sure it stays online!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Cheers,&lt;/p&gt;  &lt;p&gt;Sam Betts&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10413694" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author><category term="farm" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/farm/" /><category term="high availability" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/high+availability/" /><category term="uptime" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/uptime/" /><category term="clustering" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/clustering/" /><category term="subnet" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/subnet/" /></entry><entry><title>Multi-Subnet SharePoint Farms - High Availability SharePoint</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2013/04/17/high-availability-sharepoint-multi-subnet-sharepoint-farms.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2013/04/17/high-availability-sharepoint-multi-subnet-sharepoint-farms.aspx</id><published>2013-04-17T16:40:38Z</published><updated>2013-04-17T16:40:38Z</updated><content type="html">&lt;h1&gt;Why is Multi-Subnetting Awesome?&lt;/h1&gt;  &lt;p&gt;Having a SharePoint farm span across multiple subnets can improve the reliability of a SharePoint farm against networking failures. Reasons why a network could fail are mentioned below, but they are just another reason SharePoint can go offline and removing them as a factor is the focus of this post. We’ll describe the idea first, then there’s a demonstration below.&lt;/p&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;When SharePoint falls over it’s not a pretty sight – more &amp;amp; more SharePoint is becoming an application platform on top of collaboration and data-storage and therefore it’s becoming increasingly important it does not keel-over unexpectedly. &lt;/p&gt;  &lt;p&gt;Many farm outages occur when the transition from web-front-end to app-server isn’t possible for whatever reason but many other outages are because of communication breakdowns in the chain of communication from client to web-front-end-“server” (whichever server that may be). &lt;/p&gt;  &lt;p&gt;It’s possible of course to make the “web-app to service-app” transition more resilient to failure by providing more endpoints in case one dies for service-app redundancy - this is nothing new for anyone familiar with SharePoint farms. &lt;/p&gt;  &lt;p&gt;What I really want to explore is extending this thinking into a networking paradigm by stretching our single SharePoint farm into multiple subnets with service failovers in each subnet. This way any one network (and servers inside) could go down and our SharePoint farm could live on anyway – front-end and back-end. If you like, this post is “network considerations for high-availability SharePoint farms”, or rather how to leverage networking tricks to allow failing services to have a lesser impact. Services will always fail, the only question is our ability to react to that happening.&lt;/p&gt;  &lt;p&gt;So let’s step-back a second and work out…&lt;/p&gt;  &lt;h1&gt;When do SharePoint Outages Occur?&lt;/h1&gt;  &lt;p&gt;Let’s rephrase that question slightly – what’s the &lt;u&gt;minimum&lt;/u&gt; that SharePoint needs in order to give successful responses to client?&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A working network for SharePoint + relying services to work together&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;A web-front-end.&lt;/li&gt;      &lt;li&gt;A server that has all the services that the user web-requests require.&lt;/li&gt;      &lt;li&gt;SQL Server.&lt;/li&gt;      &lt;li&gt;Active Directory.&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Connectivity &amp;amp; routing to the SharePoint network from the requesting client&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Routing is a chain – if any parts break SharePoint won’t respond.&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;As you can see, the network is key to all of this playing nicely. If any one of the above fails, you have an outage and if you have an outage you have many hacked-off users, bosses, etc. We’re focussing on how to be able to survive a network outage specifically, or at least keep things usable until we can restore full service.&lt;/p&gt;  &lt;h2&gt;When do Network Outages Occur?&lt;/h2&gt;  &lt;p&gt;Many reasons:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Routing failure to/from (network inaccessible even if working internally).&lt;/li&gt;    &lt;li&gt;Network/subnet flooding:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Bad driver/broken network-card&lt;/li&gt;      &lt;li&gt;Broadcasting is contained to subnets&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Cable interference &amp;amp; site disruption:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Broken or damaged cables&lt;/li&gt;      &lt;li&gt;Unplugged or failing router(s) or switch(es)&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;Any one of those events would plunge a SharePoint farm into murky darkness if it happens to be in just one subnet or network, and most network engineers would tell you they’re not as uncommon as you’d think. Subnets are nice safety barrier for networking screw-ups – a fallout in one probably won’t affect the other, and we want to harness this for making sure our SharePoint farm stays online for longer.&lt;/p&gt;  &lt;h3&gt;A Typical SharePoint Network &lt;/h3&gt;  &lt;p&gt;This is a typical, basic network setup for SharePoint. A client from another location entirely connects over TCP/IP and HTTP to SharePoint and the web-front-end that gets the request responds calling whatever local network services it needs to formulate a complete response. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4010.image_5F00_3845ED67.png"&gt;&lt;img title="image" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1205.image_5F00_thumb_5F00_37015488.png" width="609" height="226" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;Blue&lt;/strong&gt;&lt;/font&gt; arrows show &lt;font color="#333333"&gt;HTTP&lt;/font&gt; traffic; &lt;font color="#f79646"&gt;&lt;strong&gt;orange&lt;/strong&gt;&lt;/font&gt; is SQL, and &lt;font color="#00d900"&gt;&lt;strong&gt;green&lt;/strong&gt;&lt;/font&gt; is Active Directory traffic. &lt;b&gt;Any break in any &lt;u&gt;one&lt;/u&gt; arrow is an outage to the whole system.&lt;/b&gt; And this is a bad thing, of course.&lt;/p&gt;  &lt;p&gt;We know how little it takes for a failure to occur somewhere and there are several failure points in this simple diagram but in this post I want to focus on just networking for now so here’s how we can evade network failures from a network outage…&lt;/p&gt;  &lt;h3&gt;A Multi-Subnet SharePoint Network&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2604.image_5F00_39C7097B.png"&gt;&lt;img title="image" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4745.image_5F00_thumb_5F00_3F357A1F.png" width="727" height="424" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is a far superior solution for its redundancy capacity as now without impacting SharePoint we could suffer the following outages (aside from the usual AD/app-server failovers):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Route from site A à sites B &lt;u&gt;or&lt;/u&gt; C. Assuming sites B &amp;amp; C can communicate this won’t impact application servers, only web-front-ends.&lt;/li&gt;    &lt;li&gt;Entire network outage on either B or C (see below for diagram).&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Of course, we’ve not just increased redundancy just because of the multiple subnet factor; the design of the above farm also gives x2 AD and SharePoint application servers too, for the multiple subnet design to be worth it. AD calls will use the server in the same subnet (depending on config) but WFE1 will at some point invoke APP2 for example as SharePoint isn’t site aware like AD so internal calls are done on a round-robin basis. SQL, being a failover cluster will use one subnet address or another depending on where the failover nodes are located but the idea is to have at least one failover node on each subnet with local routing between sites for inter-site traffic.&lt;/p&gt;  &lt;p&gt;Regardless, we can now have a whole bunch of things die on us and SharePoint will carry on living (subnet 1 has died):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8547.image_5F00_769B8B4D.png"&gt;&lt;img title="image" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7065.image_5F00_thumb_5F00_29F74EAA.png" width="737" height="433" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Routing Reliability&lt;/h3&gt;  &lt;p&gt;Improving the route-failure resiliency from client to SharePoint WFE is only as good as the chain to &amp;amp; from the client. Take our example in more detail:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5241.image_5F00_1ADF6A14.png"&gt;&lt;img title="image" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0451.image_5F00_thumb_5F00_3296A17A.png" width="602" height="359" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If we have a routing/network failure in location &lt;strong&gt;X&lt;/strong&gt; we’re doomed. If however &lt;strong&gt;Z&lt;/strong&gt; or &lt;strong&gt;Y&lt;/strong&gt; goes down (taking with it B or C respectively) we’re fine. The further up the chain we can split the routes the better and this depends purely on the IP allocation used. Obviously if the client’s ISP goes down then there’s nothing we can do (nor would we have to – everyone else should be able to access the site no problem) but if our subnets routes only split at the data-centre then equally the multiple subnets become less advantageous.&lt;/p&gt;  &lt;h1&gt;Subnet Failover in Action&lt;/h1&gt;  &lt;h4&gt;Preparation&lt;/h4&gt;  &lt;p&gt;I’ve tested this on SP2010 just because my test environment doesn’t have the memory for a HA SharePoint setup in 2013. This is the same setup as the above diagram; x2 SharePoint subnets, web-front-ends &amp;amp; app-servers with each subnet containing an app + WFE + AD server. &lt;/p&gt;  &lt;p&gt;Currently the client machine is configured to point at the web-front-end on subnet 1.We’re going to kill the router on subnet 1 so everything on that network goes dark, update manually the DNS for the client to point at subnet 2 instead (this can be automated of course), then watch to see how SharePoint survives.&lt;/p&gt;  &lt;p&gt;Of course we have SharePoint configured so that both app-servers mirror each other for services-on-farm. Here’s the search topology in particular – notice the query component in particular is setup to failover to the 2&lt;sup&gt;nd&lt;/sup&gt; subnet app-server:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8561.clip_5F00_image010_5F00_3EB9215D.jpg"&gt;&lt;img title="clip_image010" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="clip_image010" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6404.clip_5F00_image010_5F00_thumb_5F00_6B61DB36.jpg" width="618" height="229" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here’s a search page working with all machines up:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5822.clip_5F00_image012_5F00_0319129D.jpg"&gt;&lt;img title="clip_image012" style="display: inline; background-image: none;" border="0" alt="clip_image012" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5415.clip_5F00_image012_5F00_thumb_5F00_3A7F23CB.jpg" width="497" height="382" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Both WFE’s online, our host-header using WFE1, and search working perfectly (WFE1 and our host-name “SP14” use the same IP):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2604.clip_5F00_image014_5F00_06D6B76D.jpg"&gt;&lt;img title="clip_image014" style="display: inline; background-image: none;" border="0" alt="clip_image014" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4341.clip_5F00_image014_5F00_thumb_5F00_3DD095A6.jpg" width="631" height="446" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Subnet Outage!&lt;/h4&gt;  &lt;p&gt;Now to cause an outage: break router from client network to WFE1 network.&lt;/p&gt;  &lt;p&gt;Sure enough, the client can now only see one WFE (notice SP14/WFE1 aren’t responding to the ping request anymore):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5482.clip_5F00_image016_5F00_5C3AD68F.jpg"&gt;&lt;img title="clip_image016" style="display: inline; background-image: none;" border="0" alt="clip_image016" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2768.clip_5F00_image016_5F00_thumb_5F00_13A0E7BE.jpg" width="402" height="289" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;When we detect the error we change the DNS for the SharePoint URL (manually in this example) – “SP14” responds to ping:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6404.clip_5F00_image018_5F00_594571DC.jpg"&gt;&lt;img title="clip_image018" style="display: inline; background-image: none;" border="0" alt="clip_image018" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0121.clip_5F00_image018_5F00_thumb_5F00_7F3B2232.jpg" width="262" height="104" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now we load the site. With the WFE alone obviously the content will load but the question is whether the depending service-apps will too as just web-front-ends working is a long way from having an operational SharePoint. Let’s test the search functionality:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2275.clip_5F00_image020_5F00_3DC06FD9.jpg"&gt;&lt;img title="clip_image020" style="display: inline; background-image: none;" border="0" alt="clip_image020" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0118.clip_5F00_image020_5F00_thumb_5F00_0364F9F8.jpg" width="484" height="260" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Everything’s working as expected – the WFE has picked up the 2&lt;sup&gt;nd&lt;/sup&gt; application server for search and queried there as appropriate. If there’d been a problem we’d be looking at an error right now; restarting IIS would show an error if the restart happened after the outage (see below for why).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8015.clip_5F00_image022_5F00_64BFF39F.jpg"&gt;&lt;img title="clip_image022" style="display: inline; background-image: none;" border="0" alt="clip_image022" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3323.clip_5F00_image022_5F00_thumb_5F00_630F27CB.jpg" width="623" height="285" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;SharePoint will complain there’s an issue with a server, but will carry on regardless. It’s not supposed to be beautiful, just work well enough until you get the rest of the farm back online.&lt;/p&gt;  &lt;h1&gt;Caveats&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Big one for search&lt;/b&gt;: if the new web-front-end server hasn’t loaded the application-pool for the website exposed to the users &lt;b&gt;AND&lt;/b&gt; the search admin component was on the inaccessible server, the search service will fail even though a mirror has been configured. This is because the WFE needs the search admin component to get topology information to then know that there’s a local failover mirror. If the server’s sat around doing nothing with the SharePoint content-app not loaded your search service will never survive for traffic sent to that server.&lt;/li&gt;    &lt;li&gt;On that note, if the only accessible app-server(s) aren’t running the services you need then obviously that’ll fail too. This basically means having duplicate servers &amp;amp; services for everything that’s critical.&lt;/li&gt;    &lt;li&gt;Per subnet, it’s probably more realistic to have the destination IP set as a network-load-balancer rather than a single web-front-end. It’s done this way here for simplicity.&lt;/li&gt;    &lt;li&gt;This depends on the SQL cluster failing over to subnet 2 successfully. It’s possible to have the cluster work out there’s been a network outage and failover automatically but the failover needs to happen if a subnet failure has occurred.&lt;/li&gt;    &lt;li&gt;AD too needs to be working &amp;amp; each server have a local AD server as its &lt;strong&gt;%logonserver%&lt;/strong&gt; environmental variable. No accessible AD, no SharePoint. Same with SQL.&lt;/li&gt;    &lt;li&gt;In the search administration page you’ll notice various components say “Online” even when the affected server has died. Think of it more like “Could be online” – meaning you’ve not taken it down for maintenance :)&lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;DNS &amp;amp; Supportability Issues – Important!&lt;/h1&gt;  &lt;p&gt;The whole theory described in this post relies on the client knowing the IP address for the SharePoint site has changed. This is a DNS issue and I’m leaving it out of this discussion for now, but needless to say a DNS update is critical to clients being able to locate the new web-front-end(s).&lt;/p&gt;  &lt;p&gt;Finally, for a SharePoint farm to be officially supported the latency between machines needs to be 1milisecond or less. Don’t save money on hardware in other words :)&lt;/p&gt;  &lt;p&gt;More info on supported network response times here - &lt;a href="http://technet.microsoft.com/en-us/library/cc262485(v=office.15).aspx#hwLocServers"&gt;http://technet.microsoft.com/en-us/library/cc262485(v=office.15).aspx#hwLocServers&lt;/a&gt;&lt;/p&gt;  &lt;h1&gt;Conclusion&lt;/h1&gt;  &lt;p&gt;This hopefully showed how it’s possible to avoid some extra outage scenarios by designing your farm into a network-spanning zombie-farm that just won’t die. Well, never say never but you can at least make it less likely by providing redundancy this way. When downtime isn’t a possibility and there’s the investment to make it work, this is something that should be considered.&lt;/p&gt;  &lt;p&gt;Cheers!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10411942" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author><category term="farm" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/farm/" /><category term="subnets" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/subnets/" /><category term="high availability" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/high+availability/" /><category term="uptime" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/uptime/" /><category term="networking" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/networking/" /><category term="service applications" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/service+applications/" /></entry><entry><title>PSConfig System.InvalidOperationException - Cannot start the service SPAdmin on computer</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2012/10/03/psconfig-system-invalidoperationexception-cannot-start-the-service-spadmin-on-computer.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2012/10/03/psconfig-system-invalidoperationexception-cannot-start-the-service-spadmin-on-computer.aspx</id><published>2012-10-03T13:27:34Z</published><updated>2012-10-03T13:27:34Z</updated><content type="html">&lt;p&gt;Yes, this has been &lt;a href="http://blogs.msdn.com/b/chaun/archive/2012/03/19/system-invalidoperationexception-cannot-start-the-service-spadmin-on-computer.aspx"&gt;covered&lt;/a&gt; already but this problem caused me real headaches on the last CU upgrade I did for my test farms and nothing I tried seemed to help. All the machines patched just fine but when it came to finishing the upgrade with the psconfig/SharePoint wizard operation it all collapsed on every machine, seemingly for no good reason.&lt;/p&gt;  &lt;p&gt;Looking at the upgrade logs we see:&lt;/p&gt;  &lt;p&gt;ERR&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Task configdb has failed with an unknown exception&amp;#160; &lt;br /&gt; ERR&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Exception: System.InvalidOperationException: Cannot start service SPAdmin on computer '.'. ---&amp;gt; System.ComponentModel.Win32Exception: &lt;strong&gt;The service did not respond to the start or control request in a timely fashion&lt;/strong&gt;    &lt;br /&gt;&amp;#160;&amp;#160; --- End of inner exception stack trace ---    &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceProcess.ServiceController.Start(String[] args)    &lt;br /&gt;&amp;#160;&amp;#160; at Microsoft.SharePoint.Win32.SPAdvApi32.StartService(String strServiceName)    &lt;br /&gt;&amp;#160;&amp;#160; at Microsoft.SharePoint.Administration.SPWindowsServiceInstance.Start()    &lt;br /&gt;&amp;#160;&amp;#160; at Microsoft.SharePoint.Administration.SPFarm.Join()    &lt;br /&gt;&amp;#160;&amp;#160; at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.CreateOrConnectConfigDb()    &lt;br /&gt;&amp;#160;&amp;#160; at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.Run()    &lt;br /&gt;&amp;#160;&amp;#160; at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Nothing really interesting there; the SharePoint admin service just timed out starting. However doing the same from services.msc also gave the same inexplicable timeout, even when changing the registry to allow for more time.&lt;/p&gt;  &lt;p&gt;So to the point then; I’d seen from others this might’ve been an issue with network connectivity. Sure enough, when starting the service manually we see this network traffic coming from WSSADMIN.EXE:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6644.image_5F00_4037B1A6.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4064.image_5F00_thumb_5F00_265355AA.png" width="705" height="507" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In case you can’t see that’s basically the service sending TCP packets to two IP addresses (92.122.127.241 and 92.122.127.40), not getting anything back again, and retrying. A quick look up the conversation and we see where these IPs came from; the proceding DNS query &amp;amp; response show us what’s really going on:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7776.image_5F00_45F209A5.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8802.image_5F00_thumb_5F00_288C8C0E.png" width="786" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The IPs belong to “crl.microsoft.com”; this being a certificate revocation URL for revocation checks . Since a while back SPAdmin will try to check with the Microsoft certificate authority for revoked Authenticode signatures as a security measure. This is normally good but when the machine in question has no line of sight to crl.microsoft.com then this fails; in this case causing a service timeout, and stopping psconfig from finishing the upgrade &amp;amp; bringing the server back online after a patch. This can have the unintended effect of leaving a half-baked SharePoint farm so is very far from ideal.&lt;/p&gt;  &lt;h1&gt;But Why Does SPAdmin Fail to Start?&lt;/h1&gt;  &lt;p&gt;Pinging the IP address from the machine in question tells us why - 92.122.127.241 for example. We get a response from a router saying the address isn’t accessible – that it has no route to that address. This has the effect of the host not replying whatsoever so the connection times-out. As is normal the connection is retried a few times, but the problem is this is all as the service is starting so Windows is waiting for SPAdmin to say “I’m started!” which it never gets round to doing in time.&lt;/p&gt;  &lt;p&gt;Why the no-route? Well, just like many production environments we’ve blocked off these servers from getting further than the internal router unless it goes via a web-proxy. Standard security stuff – anything not proxy aware stops at the network boundary, and anything through the proxy is scanned for security threats in a single point of control. &lt;/p&gt;  &lt;h1&gt;Solutions&lt;/h1&gt;  &lt;p&gt;Anyway, I needed a quick solution to this problem as I’m sure many other have too. CRL checking can be disabled in group-policy as far as I’m aware (I’m not a domains engineer) but even if that was true, all my machines were down and needing a quick &amp;amp; dirty hack to bring them back to life again. Even worse, this error was happening on newly installed VMs too just trying to join the farm.&lt;/p&gt;  &lt;h2&gt;The (Dirty) Solution&lt;/h2&gt;  &lt;p&gt;Add crl.microsoft.com to the hosts-file of the failing machine to point to 127.0.0.1. The service then started fine and the upgrade could complete. This isn’t ideal and I don’t recommend it as a long-term solution but it should work well enough to get up &amp;amp; stumbling again. If for some reason this doesn’t work try clearing DNS cache and repeating. If that doesn’t work use the same network tracing process to figure out what the service is trying to check against and for each DNS host, add a loopback address in the hosts file.&lt;/p&gt;  &lt;p&gt;Either way this hack works because now we get to the target host for any revocation check (now ourselves), so the request to check revocations is replied with a concrete “I don’t know what you’re talking about” network response as we’re now hitting something rather than just a router. This means of the start-up revocation check is quickly failed instead of hanging waiting for a reply from no-on, and finally SPAdmin can complete it’s start-up in a timely fashion. &lt;/p&gt;  &lt;h2&gt;Another Solution (for Upgrades Only)&lt;/h2&gt;  &lt;p&gt;If this is failing only to complete an upgrade; another option is to run psconfig with the –force parameter. This won’t obviously help when adding a new server but it will do the job of completing the upgrade at least.&lt;/p&gt;  &lt;p&gt;Happy SharePointing!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10355504" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author><category term="crl" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/crl/" /><category term="moss" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/moss/" /><category term="psconfig" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/psconfig/" /></entry><entry><title>SharePoint 2010 Apps for n00bs – Forms</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-forms.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-forms.aspx</id><published>2012-04-19T15:06:21Z</published><updated>2012-04-19T15:06:21Z</updated><content type="html">&lt;p&gt;By this point in you should’ve seen the default form engine that SharePoint provides already and most likely you would’ve thought “not bad, but I bet it doesn’t do exactly what I want it to do”. You’d probably be right; the normal engine just tries to best-guess the presentation of the fields and other screen elements based on the meta-data of your list – the field sizes, descriptions, types etc. We saw some forms already; here’s one:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8877.clip_5F00_image002_5F00_2DC74993.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8880.clip_5F00_image002_5F00_thumb_5F00_325D544D.jpg" width="524" height="456" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Anyway, the good news is that you can build your own forms if you want - InfoPath forms in this example, and then use those instead of the out-of-the-box default forms. A nice thing about InfoPath forms in general is that they’re cross-platform; in that they can work on the web or in a rich-client if you so wish, and also you can auto-generate forms from SharePoint lists so it doesn’t take much work to get something up &amp;amp; running. Multiple forms can be associated with a single list but we’re just going for the one for now, because we’re n00bs.&lt;/p&gt;  &lt;h3&gt;Editing Thy Forms&lt;/h3&gt;  &lt;p&gt;If you want to edit just the normal SharePoint provisioned forms, you can do so. Open SharePoint Designer again &amp;amp; navigate to the list you’re interested in:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0451.clip_5F00_image004_5F00_700A3C09.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5353.clip_5F00_image004_5F00_thumb_5F00_52D46E32.jpg" width="554" height="419" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;These forms are provisioned with your list automatically, meaning when you create a list, these files are created too for this list-type. Other form templates get previsioned with other list-templates but that’s waaaaaay too advanced for today. The point is that if you’re feeling brave you can just directly edit these files that exist already for your list; doing so won’t affect anything other list. &lt;/p&gt;  &lt;p&gt;Click on one of the forms, and the SharePoint Designer editor will load it in design mode – from here you can edit it in the GUI or the underlying code…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7713.clip_5F00_image006_5F00_1BCA6A2C.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3603.clip_5F00_image006_5F00_thumb_5F00_373F4662.jpg" width="525" height="449" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;…although if you really want to hack the page, you’ll have to do so in “advanced mode” which is basically a button that says “I’m &lt;i&gt;not&lt;/i&gt; a n00b – let me break my site if I so wish”, but as you’re reading this guide, you probably are a n00b for now so I’d not recommend it normally. There’s a code-view for editing the raw ASPX and everything, just like in Visual Studio.&lt;/p&gt;  &lt;h3&gt;Our First InfoPath Form&lt;/h3&gt;  &lt;p&gt;Anyway all of that’s too complicated - we don’t want to modify the existing forms, we want to create new forms with InfoPath to override the old completely. We’ll start with the “New Sale” form because, let’s be honest; it’s a bit bland. Plus we want to through on some extra validation in there (i.e. don’t sell what you don’t have).&lt;/p&gt;  &lt;p&gt;So in the list setting in SPD, click the “Design Forms in InfoPath”, then click on “item”. The reason it says “Item” is obviously significant (we’re talking about the “content-type” for this list) but that, like many other areas isn’t for today. Edit the “item” content-type.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1452.clip_5F00_image008_5F00_1DA79368.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2022.clip_5F00_image008_5F00_thumb_5F00_2DF2E554.jpg" width="521" height="446" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;By the way, in case you hadn’t figured it out yet you obviously need InfoPath Designer installed (and the enterprise edition of SharePoint 2010). Clicking this button will open a new form in InfoPath Designer and pre-populate all the list-fields for you, which is awful friendly I thought.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2548.clip_5F00_image010_5F00_10BD177D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5265.clip_5F00_image010_5F00_thumb_5F00_0780DC3C.jpg" width="580" height="398" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;On the right we see a list of fields available to us, and the main bit is the auto-generated, best-shot version InfoPath Designer has of it just to get started with. We however want to improve this.&lt;/p&gt;  &lt;p&gt;First, we want to get rid of “sale confirmed” from this form – it’s something the workflow fills in, not the user so select the bottom row like so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8308.clip_5F00_image012_5F00_5E29943D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4572.clip_5F00_image012_5F00_thumb_5F00_5C0C9574.jpg" width="586" height="331" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;…and hit the delete key. Goodbye field we don’t want to edit.&lt;/p&gt;  &lt;p&gt;Next, we want some validation on “customer email” to actually check we’re entering a real email address. Click the field, then add a rule like so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8080.clip_5F00_image014_5F00_19B97D31.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image014" border="0" alt="clip_image014" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0066.clip_5F00_image014_5F00_thumb_5F00_0553B7A6.jpg" width="604" height="444" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This will add the following rules:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0878.clip_5F00_image016_5F00_7A66B090.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image016" border="0" alt="clip_image016" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3000.clip_5F00_image016_5F00_thumb_5F00_232215DA.jpg" width="615" height="391" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;…and that’ll do; in just a few clicks we’ve significantly improved on the default SharePoint form for our own InfoPath-generated one.&lt;/p&gt;  &lt;p&gt;The only thing left to do now is publish it to our SharePoint list (specified in the bottom-right corner of InfoPath). This is a fairly unemotional affair – click on the “file” tab, then “Quick Publish”.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7318.clip_5F00_image018_5F00_40B3F0D9.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image018" border="0" alt="clip_image018" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1452.clip_5F00_image018_5F00_thumb_5F00_5EB1FECD.jpg" width="544" height="346" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Doing so will show this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6735.clip_5F00_image020_5F00_5C950004.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image020" border="0" alt="clip_image020" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3034.clip_5F00_image020_5F00_thumb_5F00_21612439.jpg" width="677" height="432" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Done! If you look at the “forms” view of your list now in SPD, you’ll notice a few more files in addition to the forms you had before. These are basically ASPX wrappers to InfoPath form you’ve created here, and these will be set to be the default for your list – all by magic.&lt;/p&gt;  &lt;p&gt;So now when we go to our sales list and click “New”, we get our much-nicer form…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8306.clip_5F00_image022_5F00_7A4664F6.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image022" border="0" alt="clip_image022" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8308.clip_5F00_image022_5F00_thumb_5F00_0352F078.jpg" width="703" height="526" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Everything works as expected – all the hard work is actually done by the InfoPath form wrapped into an ASPX form. For the record InfoPath forms can be integrated into and interacted from all sorts of things; emails, apps (and app-panels), pages, and mobile phones, and more – it’s a very powerful form technology.&lt;/p&gt;  &lt;h3&gt;Wrap-Up&lt;/h3&gt;  &lt;p&gt;We’ve looked at 2 ways of customising forms here; the first one by editing the out-of-the-box SharePoint built forms in SharePoint Designer but also very briefly at the InfoPath route of replacing the list forms for our own InfoPath built ones. InfoPath is a powerful form engine once you get to know it, and easier too – play around with it; we just skipped over the very basics for today to get used to the idea of being able to customise forms, but it is a fully-featured form engine with all sorts of exotic goodness you can build into your forms for validation, display, etc. &lt;/p&gt;  &lt;p&gt;Happy SharePointing!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10295394" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author><category term="guides" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/guides/" /><category term="forms" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/forms/" /></entry><entry><title>SharePoint 2010 Apps for n00bs – Reports</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-reports.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-reports.aspx</id><published>2012-04-19T15:04:34Z</published><updated>2012-04-19T15:04:34Z</updated><content type="html">&lt;p&gt;This part assumes you have done the “data” part of this workshop – &lt;a href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-data-and-lists.aspx" target="_blank"&gt;here&lt;/a&gt;. If you haven’t, you can do similar with your own lists of course.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;This workshop &amp;amp; the one on data is also in video form -&lt;/strong&gt; &lt;strong&gt;&lt;a href="http://youtu.be/iyQmam_fvdg"&gt;http://youtu.be/iyQmam_fvdg&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h1&gt;&lt;/h1&gt;  &lt;h1&gt;Reports in Excel&lt;/h1&gt;  &lt;p&gt;So it just so happens, SharePoint supports hosting an online version of Office inside a web-browser. That’s pretty handy because Excel was built to visualise large amounts of data, and actually can pull data out of a variety of external sources – SharePoint lists included. So the idea is simple – get Excel to generate reports based on external SharePoint data (our lists), make it all nice &amp;amp; pretty, but then put the Excel sheet inside our SharePoint site so we can see it all together. I bet you didn’t see that one coming! &lt;/p&gt;  &lt;h1&gt;&lt;/h1&gt;  &lt;h1&gt;Reading List Data in Excel&lt;/h1&gt;  &lt;p&gt;For any given list, we can work with the list in Excel if we want. As it happens, Excel’s got some pretty handy data visualisation abilities so I figured why reinvent the wheel, let’s do our reporting there. Click “Export to Excel” and SharePoint will export an IQY file (Excel Web Query File) that tells Excel to open a data-source from a certain location (our site/list) – much like SQL.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4087.clip_5F00_image036_5F00_2C4FADBD.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image036" border="0" alt="clip_image036" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8204.clip_5F00_image036_5F00_thumb_5F00_4AB9EEA6.jpg" width="556" height="280" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Open the web-query file; Excel should know what to do with it. A web-query file is just meta-data for Excel to know what data to grab and from where – SharePoint generates it automatically.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7282.clip_5F00_image038_5F00_021FFFD5.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image038" border="0" alt="clip_image038" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8371.clip_5F00_image038_5F00_thumb_5F00_2E5C86B9.jpg" width="559" height="358" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We now have a blank Excel spread-sheet with 1 data-connection to our SharePoint list, waiting for customisation &amp;amp; saving.&lt;/p&gt;  &lt;h3&gt;Generate Nice-looking Sales Report&lt;/h3&gt;  &lt;p&gt;Just seeing list data is a bit rubbish so now I’m going to knock-up a quick report to show what product has sold best. Given we’re in Excel-land this isn’t exactly rocket-science, but let’s run through it anyway…&lt;/p&gt;  &lt;p&gt;Insert a new PivotTable:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8765.clip_5F00_image042_5F00_30695FB5.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image042" border="0" alt="clip_image042" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1016.clip_5F00_image042_5F00_thumb_5F00_67CF70E3.jpg" width="399" height="225" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now we’re going to use the SharePoint data-source to base the table on so select is as below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1732.clip_5F00_image044_5F00_34270485.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image044" border="0" alt="clip_image044" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4478.clip_5F00_image044_5F00_thumb_5F00_125B2BF4.jpg" width="503" height="378" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;…and say OK. Now we need to say which fields we’re interested in; in this case, what was sold &amp;amp; how many. Thus giving us this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5633.clip_5F00_image046_5F00_69DC49DF.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image046" border="0" alt="clip_image046" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8863.clip_5F00_image046_5F00_thumb_5F00_2F14A109.jpg" width="563" height="381" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Yay! Stats and stuff! Now for the finishing touch…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1004.clip_5F00_image048_5F00_0D48C878.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image048" border="0" alt="clip_image048" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5040.clip_5F00_image048_5F00_thumb_5F00_16C186EE.jpg" width="566" height="383" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;No report is complete without a 3d pie-graph thrown in for good measure:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0827.clip_5F00_image050_5F00_5BF9DE17.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image050" border="0" alt="clip_image050" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7762.clip_5F00_image050_5F00_thumb_5F00_681B583E.jpg" width="517" height="410" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now one last things; let’s sell another cat-food bag and see the report update itself (although this time I’m doing it from the standard view – just because I can).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0728.clip_5F00_image052_5F00_6A74DA3C.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image052" border="0" alt="clip_image052" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2465.clip_5F00_image052_5F00_thumb_5F00_6FE34AE0.jpg" width="532" height="376" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And now in our report when we refresh the data-connections we can see the cat-food count rise and our graph update itself. Magic!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1882.clip_5F00_image054_5F00_7551BB84.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image054" border="0" alt="clip_image054" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7752.clip_5F00_image054_5F00_thumb_5F00_41A94F26.jpg" width="470" height="383" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h5&gt;Save Report in Application&lt;/h5&gt;  &lt;p&gt;Now we need to put the report in the site so we can open it from anywhere. To do this we want a “Document Library” to store it, so in the browser click “Site Actions” and then select “New Document library”. Fill it out to be like so (click to see more options if necessary):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2475.clip_5F00_image056_5F00_4B220D9C.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image056" border="0" alt="clip_image056" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3542.clip_5F00_image056_5F00_thumb_5F00_10C697BB.jpg" width="526" height="332" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Then in the list, let’s add a new item – our saved Excel spread-sheet.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4617.clip_5F00_image058_5F00_0862C264.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image058" border="0" alt="clip_image058" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2134.clip_5F00_image058_5F00_thumb_5F00_3BBE85C0.jpg" width="512" height="381" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Once it’s done your list should look like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6266.clip_5F00_image060_5F00_45374436.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image060" border="0" alt="clip_image060" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8233.clip_5F00_image060_5F00_thumb_5F00_118ED7D8.jpg" width="528" height="200" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now it is possible to open the spread-sheet directly in the browser, in SharePoint but that’s for another day – for now we just want to be able to save it centrally.&lt;/p&gt;  &lt;h3&gt;We’re done!&lt;/h3&gt;  &lt;p&gt;So that’s about it for now; here’s some customisation I’ve done to the homepage from the web-browser, just because I can:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5684.clip_5F00_image062_5F00_702F323B.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image062" border="0" alt="clip_image062" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5280.clip_5F00_image062_5F00_thumb_5F00_60AC206C.jpg" width="638" height="474" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here’s a customised homepage thanks to some web-parts I threw onto the page &amp;amp; a picture of Tristan the cat. Play &amp;amp; tweak this to your heart’s content.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h1&gt;Wrap-Up&lt;/h1&gt;  &lt;p&gt;Excel is a great way of presenting data in general, and SharePoint allows Excel to be embedded directly in your site. How marvellously convenient! &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10295392" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>SharePoint 2010 Apps for n00bs – Workflows</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-workflows.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-workflows.aspx</id><published>2012-04-19T15:02:18Z</published><updated>2012-04-19T15:02:18Z</updated><content type="html">&lt;p&gt;Another integral feature in SharePoint is the “workflows” concept that has been baked into the system since ye olde times and they’re basically just data-oriented application processes that can run automatically (or manually) when data changes. Specifically, they normally run important data operations that define how the business operates. Workflows are normally associated with a list, are triggered automatically when data changes in the list and the idea is they are basically automatic processes for the business that run as autonomously as possible.&lt;/p&gt;  &lt;p&gt;For our pet store we’re going to try automating a key process – stock control. In plain English we want the following process when there’s been a new sale:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Subtract store quantity for sale amount in inventory &lt;/li&gt;    &lt;li&gt;Warn people that care if stock reaches a low limit &lt;/li&gt;    &lt;li&gt;Confirm sale is OK (i.e. someone else didn’t take the last item(s) just before you). &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;All of that we want to just happen when we add a new sale item in our list.&lt;/p&gt;  &lt;h2&gt;Demo App Prerequisites&lt;/h2&gt;  &lt;p&gt;For any of this to work we need to add a new column to our “inventory” list – “quantity in store”. Also we want a new column on “Sales” – “Sale confirmed” (yes/no) to be populated by the workflow itself. Create these columns and add some fake quantities to your stock items, otherwise none of this example stuff will work.&lt;/p&gt;  &lt;h2&gt;What Will the Workflow do?&lt;/h2&gt;  &lt;p&gt;We want stock to be automatically taken care of so to be precise, we want a workflow to do the following when someone makes a new sale:&lt;/p&gt;  &lt;p&gt;1. Check we’re only running the workflow on “new” items only.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;o Done by comparing the “created” and “modified” dates on the “current item” (workflow talk for “item that’s changed &amp;amp; the reason I’m even running”). &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;o We want to do this because it is possible to set workflows to only run on “create” but there is the possibility it can be triggered other times too – like manually for example, so we want to take this into account.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;2. Update the stock-levels as appropriate.&lt;/p&gt;  &lt;p&gt;3. Email some people when stock gets low.&lt;/p&gt;  &lt;h2&gt;Creating the Workflow&lt;/h2&gt;  &lt;p&gt;First up we’re creating a workflow for a list – specifically “sales” and we’re going to do it in SharePoint Designer (SPD) again so open SPD &amp;amp; navigate to the “sales” list we created back in tutorial 1. You can create completely custom-coded workflows in Visual Studio but that’s way too advanced for this tutorial so for now we’re going to use the very simplified SharePoint Designer workflow Designer – it’s so easy even my grandma could manage it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4682.image_5F00_53BC27F9.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4111.image_5F00_thumb_5F00_768CC3DC.png" width="566" height="481" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The first thing to notice is there are no workflows for this list, but that’s where we’re going to see any we make &amp;amp; publish for the list.&lt;/p&gt;  &lt;p&gt;To begin making a new workflow, click this button:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0407.image_5F00_1A554F9D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4604.image_5F00_thumb_5F00_730AE09A.png" width="635" height="114" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You’ll be asked to give a name for the new workflow; fill it out something like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2860.image_5F00_5D30D270.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7824.image_5F00_thumb_5F00_36EE7918.png" width="367" height="202" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You’ll now be presented with this, a blank editor for our 1&lt;sup&gt;st&lt;/sup&gt; workflow!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7268.image_5F00_749B60D4.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6675.image_5F00_thumb_5F00_385F6F5F.png" width="629" height="218" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Structure the Workflow Tasks&lt;/h3&gt;  &lt;p&gt;The first thing I want to do is outline our three major actions this workflow will do:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Load &amp;amp; validate what just happened. &lt;/li&gt;    &lt;li&gt;Update data &lt;/li&gt;    &lt;li&gt;Notify users of low stock &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So let’s do that as 3 major “steps” – click the “Step” button in the toolbar. Bear in mind whatever you insert will be inserted wherever the orange cursor is set, so don’t do this…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1488.image_5F00_708DC0AA.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5611.image_5F00_thumb_5F00_1DFEBAA1.png" width="517" height="207" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It is possible to nest steps in steps; for now just put 3 steps in like so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2500.image_5F00_0F43E8EF.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0358.image_5F00_thumb_5F00_55B0B32A.png" width="528" height="286" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Note: you can click on the step title to change it. Amazing! Next, to actually put some “code” in.&lt;/p&gt;  &lt;h4&gt;Load &amp;amp; Validate the Data&lt;/h4&gt;  &lt;p&gt;As we said before we want to load &amp;amp; validate the data we’re passed before doing anything; specifically we want to check the “created” and “modified” dates on the “current item” are the same so let’s add a new condition in the 1&lt;sup&gt;st&lt;/sup&gt; step:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0755.image_5F00_78ED8202.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7624.image_5F00_thumb_5F00_772C9061.png" width="605" height="350" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;…which should give us this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2330.image_5F00_11B8E0E1.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3010.image_5F00_thumb_5F00_5BC3C5F9.png" width="610" height="358" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now those two links are clickable, and need to be. Because we inserted an “If current item field…” then SPD knows we’re talking about the current item. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;i&gt;Current item by the way just means “Item this workflow is executing against because a [verb] just happened” – where [verb] could be “insert”, “update”, or even “manually launched”.&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So it should be self-explanatory at this point, but select “created”…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2043.image_5F00_66FCB469.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8713.image_5F00_thumb_5F00_10244CA8.png" width="428" height="198" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Next we’re only interested in taking a branched action if the dates &lt;b&gt;don’t&lt;/b&gt; match, so click on “equals” and change to “not equals”. Now we need to specify is what “created” needs to be compared against so click “value” link and you’ll see this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8228.image_5F00_4DD13464.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0602.image_5F00_thumb_5F00_6111EB03.png" width="550" height="136" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here we can specify either a function or a concrete data lookup to compare against. Seeing as we’re comparing a concrete lookup (same item, different field) click the “&lt;i&gt;f&lt;/i&gt;&lt;i&gt;x&lt;/i&gt;” button and fill out the next form like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6560.image_5F00_3ED9DF7D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4118.image_5F00_thumb_5F00_3D8520D1.png" width="482" height="285" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Click “OK” and your workflow should look like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5008.image_5F00_42C3E1B5.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4812.image_5F00_thumb_5F00_079005EA.png" width="483" height="245" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Congratulations, you’ve made your first “IF” statement. Yay! Next to make something happen when our condition is met.&lt;/p&gt;  &lt;p&gt;Set the WF cursor to inside the condition block and type (without quotes) “stop”, like so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8625.image_5F00_1E6ED766.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7635.image_5F00_thumb_5F00_3CD9184F.png" width="485" height="124" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;…and press ENTER. SPD will set the command and allow you to pass a “message” parameter – click it and set a message like “Oh dear, this wasn’t a new sale”, like below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3835.image_5F00_0FE3B574.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0211.image_5F00_thumb_5F00_5FD963F2.png" width="438" height="405" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Notice you’re using the string-builder here – you can mix dynamic (data) &amp;amp; static (text) elements here.&lt;/p&gt;  &lt;p&gt;Next for the next step (Update Data) we’re going to just output some text for now &amp;amp; test our not-really-so-awesome-yet workflow so add the following step (Log to History):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2867.image_5F00_34D15020.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1768.image_5F00_thumb_5F00_52CF5E14.png" width="447" height="237" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Let’s insert the item being sold name into the log too, just because we can:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2867.image_5F00_1EBABEC1.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8712.image_5F00_thumb_5F00_373A3644.png" width="602" height="463" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now when you click ok, we want to save the workflow. &lt;/p&gt;  &lt;h3&gt;Save &amp;amp; Publish Your Workflow&lt;/h3&gt;  &lt;p&gt;So anyway, let’s test it now so we can see how workflows even look like. But before we do any of that we need to configure when our workflow is run automatically so click on the original workflow to get back to its configuration, as so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2870.image_5F00_3C98811B.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4540.image_5F00_thumb_5F00_405625EB.png" width="606" height="222" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;From here let’s set the WF to be triggered on new &amp;amp; update – if only to test our infallible sanity checking coded into the WF itself:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7673.image_5F00_0ACD3DF9.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1715.image_5F00_thumb_5F00_513A0834.png" width="677" height="383" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now we want to publish the workflow now everything’s ready for our test-run. What’s the difference between saving &amp;amp; publishing? Save will stop you losing any work; publish will actually make any changes since the last publication live – if you’re ever wondering why your workflow seemingly ignores you, it’s probably because you’ve only saved it. So click “Publish”!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2311.image_5F00_184F889A.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8168.image_5F00_thumb_5F00_3E351323.png" width="485" height="154" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Let’s do a Test-Run&lt;/h4&gt;  &lt;p&gt;Now we have a published &amp;amp; primed workflow let’s see the awesomeness in action. In the browser, go to your “sales” list. Add a new item; fill in anything you want – we just want to invoke the workflow which we can see when we do:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0247.image_5F00_07679252.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2804.image_5F00_thumb_5F00_032D94C0.png" width="733" height="250" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;That column shows the status of the workflow (it’s actually a virtual column but more on that another day). Click on it and we can see the result of that workflow. Note that sometimes you have to refresh the list in browser to see “Completed” reported.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4863.image_5F00_309E8EB6.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8512.image_5F00_thumb_5F00_0369564E.png" width="678" height="400" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here we can see what route our workflow execution took – the description of the sold item is a bit odd as in this example, to save some time we’re just flattening out the related record to text, which includes all the ID field too hence the weirdness. It’s possible to grab a specific property; we’ll look at that later – the important thing is we see some kind of audit/tracing going on with the data we’re reading.&lt;/p&gt;  &lt;p&gt;Anyway to test the sanity checking of our workflow, go back to the sales list but this time edit the sale instead of creating a new one.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2816.image_5F00_068B1869.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7028.image_5F00_thumb_5F00_5DBF8D52.png" width="669" height="195" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;When we edit a sale, the history shows us this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2337.image_5F00_4B4716D0.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2843.image_5F00_thumb_5F00_3E3D10F2.png" width="693" height="409" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Tada!&lt;/p&gt;  &lt;h3&gt;Read in Inventory Stock&lt;/h3&gt;  &lt;p&gt;So now we know our workflow works and we’ve covered how to debug them, let’s actually get it to do something useful – the first step of which is actually getting the WF to do what it says on the tin – update the stock level, but to do that we need to know what the current stock-level is for our associated inventory item.&lt;/p&gt;  &lt;p&gt;Now first, let’s create 2 variables – one to hold the current stock level, and another to hold a new stock level. The first one isn’t desperately necessary but holding the current level in a variable means we can also log the value to the workflow history for debugging purposes.&lt;/p&gt;  &lt;p&gt;Anyway, we create the variables in the “Local Variables” dialogue. Add like so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3326.image_5F00_2D654077.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0118.image_5F00_thumb_5F00_04D63896.png" width="638" height="387" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now once you’ve added these two number variables we’re going to set the “current stock level” var. Set the next action in “Update” data as “Set variable” by typing “var” and pressing ENTER like so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1205.image_5F00_2E7967EF.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1682.image_5F00_thumb_5F00_5396B25B.png" width="565" height="105" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;When you press ENTER you’ll be able to select which one; pick the “Current Stock Level”. &lt;/p&gt;  &lt;p&gt;The next step is where it gets interesting, because we’re reading from a record that isn’t the current one or even in the same list – we’re reading from our inventory list. This means we have to tell SharePoint how to find the inventory record we want. Anyway for now, set the “lookup” for our variable setting as so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8547.image_5F00_2AAB9D52.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6318.image_5F00_thumb_5F00_0D75CF7B.png" width="610" height="322" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This tells SharePoint Designer which value from the inventory list we’re going to insert into the variable. Next we need to tell SPD how to find the record we’re interested in which we do in the 2&lt;sup&gt;nd&lt;/sup&gt; part of this dialogue “Find the List Item”. In short, we’re going to find the inventory item by ID as it’s a unique value always so where it says “Field” select “ID” – the fields in this list are from the inventory list. Next we need to match inventory ID to a value in the current item and we do this by clicking the “&lt;i&gt;fx&lt;/i&gt;” button at the bottom-right (the lookup button). Make your form look like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8561.image_5F00_25F546FE.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1526.image_5F00_thumb_5F00_29833C0E.png" width="568" height="340" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;…and say “OK” to all forms. To make sure the variable is being read in ok we can output the value to the workflow history if only temporarily.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3364.image_5F00_68D0C9D1.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5482.image_5F00_thumb_5F00_09B416AC.png" width="384" height="188" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;...and here’s the result:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8551.image_5F00_0DDDEE71.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6087.image_5F00_thumb_5F00_1E09B66A.png" width="648" height="117" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is an important step; it shows we can debug our workflow if necessary (it will be if you get into writing these things).&lt;/p&gt;  &lt;h3&gt;Set New Stock Level&lt;/h3&gt;  &lt;p&gt;So let’s delete the last “log to history” task because we know it now works…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2275.image_5F00_77C75D11.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1682.image_5F00_thumb_5F00_2E550856.png" width="463" height="172" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;…and now let’s add a new command “Calculate Variable” – this is where we’ll do our super-complex maths of “New stock level = old stock level – order quantity”. So click in the right location:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4426.image_5F00_36F560E2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1682.image_5F00_thumb_5F00_50E92104.png" width="565" height="102" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;(Starting to type while the cursor is here will enter a new action)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5415.image_5F00_52D6700D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3757.image_5F00_thumb_5F00_70D47E01.png" width="572" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The command is “calculate”, and we take the variable “Current Stock Level”, &lt;strong&gt;minus&lt;/strong&gt; the “current item (sale) quantity” and output to our other variable “New Stock Level”. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2768.image_5F00_3CBFDEAE.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4747.image_5F00_thumb_5F00_2B8C010B.png" width="651" height="139" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Finally, one more step – “Update List Item” the action is called. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2275.image_5F00_1D6D120E.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4403.image_5F00_thumb_5F00_02544300.png" width="319" height="364" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We’re updating not the current item, but another record – the sale item. We need to locate it – just as we did before and also set the new stock level quantity to our variable value.&lt;/p&gt;  &lt;p&gt;Your WF should look like this now:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2678.image_5F00_0C290E9E.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6545.image_5F00_thumb_5F00_50F532D2.png" width="537" height="139" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Let’s test it!&lt;/p&gt;  &lt;h3&gt;Testing Stock Updates&lt;/h3&gt;  &lt;p&gt;As before let’s make a new sale, but let’s also make sure there is some stock first…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3817.image_5F00_00CFD494.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2766.image_5F00_thumb_5F00_13382549.png" width="448" height="222" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If we buy 4 of these, there should be 2 left, right? Right?! Let’s save our workflow and test it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1346.image_5F00_29AAC3D0.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2816.image_5F00_thumb_5F00_6DFA8F42.png" width="611" height="436" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Well this is odd; the workflow’s complete but it’s not updating. Why?&lt;/p&gt;  &lt;p&gt;Well because we didn’t publish the changes so it’s our last-published workflow running still. A common mistake to make, worry ye not.&lt;/p&gt;  &lt;p&gt;So publish it and try again…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6136.image_5F00_045D07FD.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8686.image_5F00_thumb_5F00_5AF59A31.png" width="582" height="392" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Yay!&lt;/p&gt;  &lt;h3&gt;Send Email Notifications&lt;/h3&gt;  &lt;p&gt;Last things to do then should be easy.&lt;/p&gt;  &lt;p&gt;1&lt;sup&gt;st&lt;/sup&gt; thing in the “notify users” block – an “if” statement that says:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“If there are less than 3 items left in inventory, alert people with an email.”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So insert a new condition, and in the condition block add “email” action (without specifying how/who) like so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/0247.image_5F00_0C04AF05.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1727.image_5F00_thumb_5F00_5BFA5D83.png" width="539" height="127" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Click the “these users” link to begin defining an email to be sent automatically. Here’s where we’re going to generate a nice automatic email to send to a group of people with auto-generated messages just like we did above. Fill it all out like so, adding lookups where we need dynamically inserted data:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5025.image_5F00_765A509A.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1715.image_5F00_thumb_5F00_5205464B.png" width="416" height="383" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now in the “to” field, click the address-book. This will show all the contacts relevant to this site; we can email 1 user in the system or out, or a whole group, or several combinations of the two. Let’s email anyone in the Pet Shop “owner” SharePoint group.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8664.image_5F00_06E225BC.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6082.image_5F00_thumb_5F00_0C8D1995.png" width="377" height="251" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;That’s it; the SharePoint emailing robot (assuming it’s been setup by your administrator) will now do thy pet-shop bidding.&lt;/p&gt;  &lt;h3&gt;Set “Sale Confirmed” Flag&lt;/h3&gt;  &lt;p&gt;Finally, and as a last step we’re going to set the “Sale Confirmed” flag as “true”. You’ve done this already, but here it is:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6661.image_5F00_091B5C20.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2043.image_5F00_thumb_5F00_017FC6E6.png" width="479" height="357" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This last step means we’re assuming that if we got there, it all went well. It’s something of an assumption but this isn’t a lesson in system design so it’ll do for now. Publish &amp;amp; test…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4118.image_5F00_607C2E71.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8713.image_5F00_thumb_5F00_20A2221F.png" width="721" height="234" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If the email doesn’t arrive, there’s not much more you can do than speak to your SharePoint administrator – it’s setup at a farm level so way, way outside your control in this instance. You as the programmer though don’t care; someone else can deal with actually making the email arrive where &amp;amp; when it should.&lt;/p&gt;  &lt;h1&gt;Wrap-Up&lt;/h1&gt;  &lt;p&gt;That’s it for now. The idea was to give a basic idea of debugging, decision-making &amp;amp; performing actions all automatically for a list. You should have a basic understanding of how workflows work. For serious workflows that SPD can’t/won’t be able to do, there’s always Visual Studio too but that, like many other subjects in SharePoint, is for another day. Congrats on programming your first workflow!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10295390" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author><category term="guides" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/guides/" /><category term="workflows" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/workflows/" /></entry><entry><title>SharePoint 2010 Apps for n00bs – Data and Lists</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-data-and-lists.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-data-and-lists.aspx</id><published>2012-04-19T14:56:00Z</published><updated>2012-04-19T14:56:00Z</updated><content type="html">&lt;p&gt;We’ll start off by running through the very fundamentals of any application – storing data in lists, with some basic interfaces to get &amp;amp; set the data too. In SharePoint land, unlike SQL, we always have a basic interface to any list with the out-of-the-box forms SharePoint will provision for any given list store. This is nice because sometimes writing a GUI for doing it ourselves can be a pain, especially if you rarely ever want to interact with the list so can’t be bothered to write one especially. Incidentally all lists will always have automatically various web-service interfaces to interact with them too, but that too is for another day.&lt;/p&gt;  &lt;p&gt;There are many types of lists – Document Libraries you’ve probably heard of for example, but all lists effectively inherit from a base “List” implementation so that’s what we’re going to build for now.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;This workshop &amp;amp; the one on reports is also in video form -&lt;/strong&gt; &lt;strong&gt;&lt;a href="http://youtu.be/iyQmam_fvdg"&gt;http://youtu.be/iyQmam_fvdg&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;Steps to Build a SharePoint Application&lt;/h2&gt;  &lt;p&gt;There’s multiple ways to build things in SharePoint. The most common &amp;amp; easiest way is to use the web GUI to do it so that’s how we’re going to start; later I’ll dive into how to programmatically do the same but for now it’s a case of:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a (blank) site. &lt;/li&gt;    &lt;li&gt;Create lists to hold products and sales. &lt;/li&gt;    &lt;li&gt;Add product/sale data. &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Create a Site&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4370.clip_5F00_image008_5F00_1BCBEC9B.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3806.clip_5F00_image008_5F00_thumb_5F00_3A362D84.jpg" width="512" height="459" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;From Central Administration, I’ll create a blank site for my application. There’s only 1 user, me, AKA “Administrator”.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8686.clip_5F00_image010_5F00_58A06E6D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7181.clip_5F00_image010_5F00_thumb_5F00_7E29EBCE.jpg" width="498" height="193" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;My rather barren looking site. Even with the “blank” site we get various master-pages and a default page as seen above; if a site was truly blank, you wouldn’t see anything in a browser. You could think of the different site-types as different application templates – we want enough functionality that we can use the default SharePoint GUI to play around and create more things, but little else.&lt;/p&gt;  &lt;h3&gt;Create lists&lt;/h3&gt;  &lt;p&gt;I’ll do the next bit in SharePoint Designer 2010 (free download, also called “SPD” for short) as it’s just quicker. From SPD click “Open Site” and enter the URL of your new site, in this case &lt;a href="http://sfb-ntlm-ad:39712/sites/PetStore"&gt;http://sfb-ntlm-ad:39712/sites/PetStore&lt;/a&gt; (or you can click “Open in SharePoint Designer” from the web-browser site-actions menu).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7607.clip_5F00_image012_5F00_75C61677.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2620.clip_5F00_image012_5F00_thumb_5F00_53FA3DE6.jpg" width="538" height="404" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Our new site in SharePoint Designer (SPD). Already some basic security &amp;amp; UI functionality is provided (master-pages etc.).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4861.clip_5F00_image014_5F00_44772C17.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image014" border="0" alt="clip_image014" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2388.clip_5F00_image014_5F00_thumb_5F00_7BDD3D45.jpg" width="542" height="407" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In “Lists and Libraries” we want to create two custom lists, “Inventory” and “Sales” – custom just means “blank” in this instance.&lt;/p&gt;  &lt;p&gt;Once you’ve created both, let’s edit one. Click on it in the list (of lists), then click the toolbar button “Edit Columns” to add any missing columns (“Title” &amp;amp; others are created by default)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3872.clip_5F00_image016_5F00_1A477E2F.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image016" border="0" alt="clip_image016" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2308.clip_5F00_image016_5F00_thumb_5F00_669F11D0.jpg" width="556" height="308" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Let’s add a “price” field:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/2476.clip_5F00_image018_5F00_32F6A572.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image018" border="0" alt="clip_image018" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3463.clip_5F00_image018_5F00_thumb_5F00_3CDB96DD.jpg" width="207" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now edit the column settings:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7651.clip_5F00_image020_5F00_229B2DB9.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image020" border="0" alt="clip_image020" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4024.clip_5F00_image020_5F00_thumb_5F00_13844EDF.jpg" width="217" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Done; the full list schema is as follows (with hidden out-of-the-box columns too):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3365.clip_5F00_image022_5F00_60481575.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image022" border="0" alt="clip_image022" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3441.clip_5F00_image022_5F00_thumb_5F00_6CD5C291.jpg" width="608" height="253" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now do the same, but for “Sales”; making custom-field “Game Sold” a “lookup” field to “Games” as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6180.clip_5F00_image024_5F00_2F655E0A.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image024" border="0" alt="clip_image024" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3343.clip_5F00_image024_5F00_thumb_5F00_4E3BD1E8.jpg" width="190" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Your list should look something like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/8233.clip_5F00_image026_5F00_1AFF987F.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image026" border="0" alt="clip_image026" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7651.clip_5F00_image026_5F00_thumb_5F00_408915E0.jpg" width="602" height="208" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Note: I renamed “Title” to “Customer Name” as all lists in SharePoint-land have to have a title field as every list inherits from a base content-type “Item” which has this field, but more on that another day. In short, you have to have it in one form or another, even if you don’t use it. Apart from that I’ve set “Sale Date” to default to today’s date and “Quantity” to default to “1”.&lt;/p&gt;  &lt;p&gt;Now you’re done in SharePoint Designer. You can do the exactly same list-creation process via the browser too, but just because there’re fewer clicks so I chose to do it in SPD.&lt;/p&gt;  &lt;h3&gt;Add some data&lt;/h3&gt;  &lt;p&gt;I’ll do this in the GUI; there’s a great datasheet view that speeds this up greatly. This is one of the many things that come even with blank sites, but more on that later.&lt;/p&gt;  &lt;p&gt;Open/refresh the homepage again, navigate to the Inventory list and then click:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5008.clip_5F00_image028_5F00_31060411.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image028" border="0" alt="clip_image028" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1778.clip_5F00_image028_5F00_thumb_5F00_3D93B12D.jpg" width="579" height="265" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4503.clip_5F00_image030_5F00_352FDBD6.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image030" border="0" alt="clip_image030" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4503.clip_5F00_image030_5F00_thumb_5F00_41BD88F2.jpg" width="244" height="243" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Select “Datasheet View” &amp;amp; enter data like you would a spread-sheet.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3021.clip_5F00_image032_5F00_7270909D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image032" border="0" alt="clip_image032" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1447.clip_5F00_image032_5F00_thumb_5F00_3EC8243F.jpg" width="452" height="276" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Please note, I have no idea how much dogs/cats actually cost, however I did learn there is such a thing as a “Munchkin cat”. You learn something every day, thanks Wikipedia.&lt;/p&gt;  &lt;p&gt;Now do the same for “sales”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5460.clip_5F00_image034_5F00_2F451270.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image034" border="0" alt="clip_image034" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/4812.clip_5F00_image034_5F00_thumb_5F00_4DAF5359.jpg" width="449" height="243" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It turns out the Munchkin cat is very popular. Who knew?&lt;/p&gt;  &lt;h1&gt;Wrap-Up&lt;/h1&gt;  &lt;p&gt;You’ve created your first lists to store and link data - well done! It’s not rocket-science of course but it is important obviously, and this is just the absolute very basics. What we’ve done here you can automate of course – the same way you don’t need a GUI to create SQL Server tables, and as for the data-input/forms of the data mentioned – don’t worry if you don’t like them, you can change them but we’re looking at that separately in the “Forms” demo where we’ll customise and modify the forms SharePoint has given us by default, but for now just getting a reasonable schema in and some data will be enough.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10295384" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author><category term="lists" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/lists/" /><category term="guides" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/guides/" /><category term="data" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/data/" /></entry><entry><title>SharePoint 2010 Apps for n00bs – Introduction</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-introduction.aspx" /><id>http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-introduction.aspx</id><published>2012-04-19T14:55:18Z</published><updated>2012-04-19T14:55:18Z</updated><content type="html">&lt;p&gt;Hello! Welcome to my blog section “SharePoint 2010 Apps for n00bs”. This mini-section is all about building SharePoint apps obviously but the bigger point is to highlight where SharePoint can be used to build your generic app with faster &amp;amp; better than traditional development frameworks. Given I’m assuming no experience with SharePoint previously I’m starting at the very beginning – something even one’s Grandma could follow, if she were that way inclined.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/1537.logo_5F00_sharepoint_5F00_2010_5F00_603EFF8F.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Logo Microsoft SharePoint 2010" border="0" alt="Logo Microsoft SharePoint 2010" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3107.logo_5F00_sharepoint_5F00_2010_5F00_thumb_5F00_76B19E16.jpg" width="150" height="30" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Most of SharePoint apps are designed for a web interface but it’s ultimately just an apps platform; one that can be extended into mobile, rich-client apps, or you can use SharePoint to just build web-service end-points. My focus in this is going to be web-based apps and as I said we’re going to start very &lt;strong&gt;basic&lt;/strong&gt; (oh so basic) with objects created manually by hand and build up from there. No custom-code; no complex solutions - the idea just for now is to build a simple application using as many major parts of SharePoint as possible to get an understanding of what the platform is good at doing, then to look at automating some of it all later. A bit like how you can build a SQL database in a nice GUI, or you can generate your own scripts to do the same – for now we’re living in shiny GUI land. &lt;/p&gt;  &lt;h1&gt;So What do SharePoint?&lt;/h1&gt;  &lt;p&gt;We have 4 major focus areas we’re going to start with to demonstrate building apps in SharePoint. In this blog there are blogs &amp;amp; video-blogs for: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font style="background-color: #ffff00"&gt;&lt;/font&gt;&lt;a href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-data-and-lists.aspx"&gt;Storing and listing our data&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-reports.aspx"&gt;Reporting on and analysing our data&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-forms.aspx"&gt;Forms for manipulating our data&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-workflows.aspx"&gt;Workflows to automate our data changes and drive system events&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Pretty much any system of any type needs all four of these activities; my idea is to show you how SharePoint does them in its own unique &amp;amp; awesome way. At the end of all the workshops/demos we’ll have a basic system that provides some functionality you would otherwise have to write by hand, except it’ll take us no more than 30 minutes. And that my friends is why SharePoint rocks – because you can build this stuff very quickly if you have to. Sure it’ll be rough at the beginning but some very shiny sites run SharePoint – perhaps none more so than &lt;a title="http://www.ferrari.com" href="http://www.ferrari.com"&gt;http://www.ferrari.com&lt;/a&gt; as just one example but just for now we’re covering the basic building-blocks – later we’ll look at making Ferrari-type systems in SharePoint too.&lt;/p&gt;  &lt;h1&gt;&lt;/h1&gt;  &lt;h2&gt;But Why Build on SharePoint?&lt;/h2&gt;  &lt;p&gt;There are lot’s of reasons; speed of development is one, but my favourite would probably be that the programmer doesn’t need to be a system admin too. Your code is the same on 1 server as 100 – good programmers tend to make rubbish system admins and visa versa (I’m generalising of course), so it’s good to keep the two camps separate if possible and SharePoint does that nicely.&lt;/p&gt;  &lt;p&gt;Genius code &amp;amp; content reuse is another, but that’s for another day.&lt;/p&gt;  &lt;p&gt;As this is a series for “n00bs” (newbies/new people) we’ll going to do everything by hand. Later we’ll look at automating all of these and how it’s possible to reuse functionality in SharePoint in very cool ways that set it apart from other app-building frameworks. We’re looking at stuff that’s just using the SharePoint foundation framework principally – if you want to try this out you can either &lt;a href="http://technet.microsoft.com/en-us/sharepoint/ee263910" target="_blank"&gt;get SharePoint 2010 Foundation for free&lt;/a&gt; (not everything we do here will work in the freebie version), or get yourself a SharePoint online account for “proper SharePoint”.&lt;/p&gt;  &lt;h1&gt;&lt;/h1&gt;  &lt;h1&gt;Example Application (The Pet Shop)&lt;/h1&gt;  &lt;p&gt;For all of these demos we’re going to be building a very simple application. Let’s pretend we have a friend that has a pet store and we had the genius idea of automating his paper-based sale tracking system. So anyway, for a first version it needs to do the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Keep track of inventory in the store – food, actual pets, etc. &lt;/li&gt;    &lt;li&gt;As above, but for sales too. &lt;/li&gt;    &lt;li&gt;Show basic report of what has sold the best. &lt;/li&gt;    &lt;li&gt;Automate stock-control. &lt;/li&gt;    &lt;li&gt;Not look &amp;amp; feel terrible. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This is very basic indeed, which is perfect for this series. For the time-being, a sale just consists of entering a person’s name &amp;amp; email-address + quantity into a basic table that relates to an item.&lt;/p&gt;  &lt;p&gt;Anyway, the result needs to be that our friend could run his pet-shop better with a SharePoint cat-themed application even a n00b could build. Do not underestimate the power of learning with cats.&lt;/p&gt;  &lt;h1&gt;Platform Comparison&lt;/h1&gt;  &lt;p&gt;To get started let’s have an idea what it would take to build our pet-store with normal programming languages. Remember, SharePoint isn’t looking to replace these but just in some scenarios it’s quicker/better and that’s what this is all about. There are some situations where SharePoint would be a nightmare to use over some other languages but for some stuff it’s a breeze to do in SharePoint land.&lt;/p&gt;  &lt;h2&gt;Building in Bespoke&lt;/h2&gt;  &lt;p&gt;If we were to hack this out in ASP.Net for example, this application specification would imply the following development work:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Storage in a database. &lt;/li&gt;    &lt;li&gt;Code to save &amp;amp; load from it DB. &lt;/li&gt;    &lt;li&gt;Custom written forms to interact with the data. &lt;/li&gt;    &lt;li&gt;Reporting tools – either implement existing or write bespoke. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The data structure would look something like this (with ID fields, created &amp;amp; last-edited dates too):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/6038.clip_5F00_image002_5F00_7C996B94.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/7103.clip_5F00_image002_5F00_thumb_5F00_1B03AC7E.png" width="244" height="131" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This isn’t much, but certainly this is not an insubstantial amount of coding to do would it be done in ASP.Net or PHP or whatever is your programming language/framework of choice. Here’s how the application would be built if it were bespoke; the textbook N-tiered application setup, just like they taught you at college:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/3884.clip_5F00_image004_5F00_2C07DA61.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-50-44-metablogapi/5050.clip_5F00_image004_5F00_thumb_5F00_3895877D.png" width="342" height="124" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Building in SharePoint&lt;/h2&gt;  &lt;p&gt;Building this same model in SharePoint however is much easier - it’s all there with the toys baked into SharePoint 2010:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font style="background-color: #ffff00"&gt;&lt;/font&gt;&lt;a href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-data-and-lists.aspx"&gt;Lists&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-forms.aspx"&gt;InfoPath forms&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-reports.aspx"&gt;Excel reports&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/sambetts/archive/2012/04/19/sharepoint-2010-apps-for-n00bs-workflows.aspx"&gt;List workflows&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Click on each subject to learn how to do it, although if you’re really new to this you might want to start with “lists”.&lt;/p&gt;  &lt;p&gt;Anyway, enjoy! &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10295383" width="1" height="1"&gt;</content><author><name>Samuel Betts</name><uri>http://blogs.msdn.com/elbetzio_4000_gmail.com/ProfileUrlRedirect.ashx</uri></author><category term="guides" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/guides/" /><category term="introduction" scheme="http://blogs.msdn.com/b/sambetts/archive/tags/introduction/" /></entry></feed>