<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>The SI SharePoint Blog</title>
	<atom:link href="http://sisharepoint.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://sisharepoint.wordpress.com</link>
	<description>Development with SharePoint 2010</description>
	<lastBuildDate>Thu, 24 Nov 2011 10:09:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='sisharepoint.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>The SI SharePoint Blog</title>
		<link>http://sisharepoint.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://sisharepoint.wordpress.com/osd.xml" title="The SI SharePoint Blog" />
	<atom:link rel='hub' href='http://sisharepoint.wordpress.com/?pushpress=hub'/>
		<item>
		<title>The perils of storing SPWeb metadata</title>
		<link>http://sisharepoint.wordpress.com/2010/09/19/the-perils-of-storing-spweb-metadata/</link>
		<comments>http://sisharepoint.wordpress.com/2010/09/19/the-perils-of-storing-spweb-metadata/#comments</comments>
		<pubDate>Sun, 19 Sep 2010 11:34:58 +0000</pubDate>
		<dc:creator>Tor Lye</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[SPWeb]]></category>

		<guid isPermaLink="false">http://spblog.software-innovation.com/?p=111</guid>
		<description><![CDATA[On Friday while searching for how to store metadata in a web object, I was looking through the MSDN documentation for the SPWeb class. The SPWeb.Properties property looked like just what I needed. As I was reading the detailed description, I found this gem: Remarks This property returns only a subset of the metadata for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=111&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>On Friday while searching for how to store metadata in a web object, I was looking through the MSDN documentation for the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.aspx">SPWeb class</a>. The <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.properties.aspx">SPWeb.Properties</a> property looked like just what I needed. As I was reading the detailed description, I found this gem:</p>
<blockquote>
<div id="_mcePaste"><strong>Remarks</strong></div>
<div id="_mcePaste">This property returns only a subset of the metadata for a Web site. To get all the metadata, use the AllProperties property.</div>
</blockquote>
<p></p>
<p>Huh. So why does it return only a subset? What subset does it return, a random selection perhaps? If it only returns a subset, shouldn&#8217;t they have named it <em>SomeProperties</em> or perhaps <em>NotAllProperties</em> instead?</p>
<p>The MSDN docs din&#8217;t explain anything, but Google always knows the answer. It turns out that  the Properties property (besides having a confusing name) represents an older mechanism for storing metadata. It has been replaced by the newer <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.allproperties.aspx">AllProperties</a> property, but is still present for backwards compatibility.</p>
<p>Properties returns a <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.utilities.sppropertybag.aspx">SPPropertyBag</a> object, a custom type which can store key/value pairs — keys are case insensitive and are converted to lowercase when added. AllProperties on the other hand uses a standard Hashtable collection to store its key/value pairs and has case sensitive keys. Furthermore, the SPPropertyBag class has its own Update method which updates the database with any changes to the collection. The AllProperties collection on the other hand is  saved by calling the Update method of the SPWeb object.</p>
<p>To add to the confusion, keys added to Properties are also stored in AllProperties, but not the other way around. This explains the &#8220;returns only a subset of the metadata&#8221; part of the property description.</p>
<p>But it doesn&#8217;t stop there — no, joy of joys, there&#8217;s more! In SharePoint 2010, four new methods were added to the SPWeb class.</p>
<p><a href="http://sisharepoint.files.wordpress.com/2010/09/addproperty.png"><img class="alignnone size-full wp-image-116" title="SPWeb new methods" src="http://sisharepoint.files.wordpress.com/2010/09/addproperty.png?w=646&#038;h=150" alt="SPWeb new methods" width="646" height="150" /></a></p>
<p>Thanks, that&#8217;s <em>so very</em> helpful. Four new methods that deal with SPWeb metadata, and no description or explanation. Which collection do they store their data in? Properties? AllProperties? Both? Their own, separate collection?</p>
<p>Thankfully PowerShell, which I&#8217;m just learning to use, allowed me to quickly test the behaviour of the new methods. Perhaps not unexpectedly, they read and write to AllProperties, the more recent of the metadata collections.</p>
<p>It seems like all this has the potential to cause great confusion if not all developers on a team use the same collection to store their metadata. Especially the way Properties updates AllProperties but not vice versa, and the fact that the new methods are not documented, nor is the distinction between Properties and AllProperties explained properly. Luckily though, as I have just recently started to work with SharePoint, this issue hasn&#8217;t had the chance to cause me any grief yet&#8230; on the contrary, the process discovering all of this on a Friday afternoon proved to be a great source of entertainment.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/111/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=111&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2010/09/19/the-perils-of-storing-spweb-metadata/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/429dd7374c0d1f525144f01da9beec92?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">torly</media:title>
		</media:content>

		<media:content url="http://sisharepoint.files.wordpress.com/2010/09/addproperty.png" medium="image">
			<media:title type="html">SPWeb new methods</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting around GAC problems when you deploy SharePoint solutions with PowerShell</title>
		<link>http://sisharepoint.wordpress.com/2010/03/26/getting-around-gac-problems-when-you-deploy-sharepoint-solutions-with-powershell/</link>
		<comments>http://sisharepoint.wordpress.com/2010/03/26/getting-around-gac-problems-when-you-deploy-sharepoint-solutions-with-powershell/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 13:56:31 +0000</pubDate>
		<dc:creator>Bjørn Stærk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://sisharepoint.wordpress.com/2010/03/26/getting-around-gac-problems-when-you-deploy-sharepoint-solutions-with-powershell/</guid>
		<description><![CDATA[In a previous post I wrote about how to replace the Visual Studio deployment steps with your own PowerShell script, which allows you to take full control over how you deploy solutions to your development machine. In addition to enabling more advanced deployment scenarios, this allows you to use the same scripts when you deploy [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=96&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In a previous post I wrote about <a href="http://sisharepoint.wordpress.com/2010/03/25/make-your-own-powershell-scripts-for-sharepoint-deployment-in-visual-studio-2010/">how to replace the Visual Studio deployment steps with your own PowerShell script</a>, which allows you to take full control over how you deploy solutions to your development machine.</p>
<p>In addition to enabling more advanced deployment scenarios, this allows you to use the same scripts when you deploy locally and to your test and production environments. The Visual Studio deployment engine is great &#8211; but it&#8217;s almost too helpful. It cleans up everything for you, automatically fixing all kinds of deployment conflicts.</p>
<p>This creates an artificial environment. In test or production, it&#8217;s possible that you <em>never</em> want to actually retract and reinstall your solution, just update it, and if you do reinstall it, Visual Studio is not around to fix deployment conflicts for you. So you may be headed for a nasty surprise when you take your solution to a test server for the first time, and discover there are all sorts of upgrade scenarios to consider.  (For instance, <a href="http://sisharepoint.wordpress.com/2010/03/02/changing-the-disk-location-of-uncustomized-ghosted-pages/">it’s really difficult to overwrite existing files</a>.)</p>
<p><span id="more-96"></span></p>
<p>If you use a PowerShell script to deploy from Visual Studio, you can use that same script in development, test and production. This makes your development environment more like real life, which is a Good Thing. And as I showed earlier, you can use different build configurations to choose between different deployment scenarios: Full reinstall, <a href="http://sisharepoint.wordpress.com/2010/01/21/using-the-featureupgrading-event-to-upgrade-features-sharepoint-2010/">upgrade from previous version</a>, etc.</p>
<p>But there are some stumbling blocks you may encounter once you leave the safe world of the Visual Studio deployment engine. I mentioned one earlier &#8211; <a href="http://sisharepoint.wordpress.com/2010/03/25/make-your-own-powershell-scripts-for-sharepoint-deployment-in-visual-studio-2010/">getting your PowerShell scripts to run in 64-bit mode</a> &#8211; and here&#8217;s another: <strong>The Global Assembly Cache</strong>.</p>
<p>Let&#8217;s say you&#8217;ve added a new feature and a new feature receiver to your solution, and you deploy it with a PowerShell script. You may experience that the feature can not be installed, because the receiver class couldn&#8217;t be found. Or you&#8217;ve changed the code in a feature receiver, and you experience that the old code is executed instead of a new one when you deploy.</p>
<p>Why? Because when a process loads an assembly from the Global Assembly Cache, it will keep using that version of the assembly for the rest of its life <em>even if a new version has later been added to the GAC</em>. Solution deployment is run by the SharePoint 2010 Timer service, and features are activated within your PowerShell process. So if something you&#8217;ve done earlier has caused one of these processes to load the assemblies you&#8217;re updating, an old version of your code will be used during solution deployment or feature activation.</p>
<p>The solution is to restart the timer service, and launch new PowerShell processes, whenever you require the latest version of an assembly to run.</p>
<p>(<strong>Update:</strong> The timer service problem described here happens when  you retract a solution, then reinstall it with a new feature receiver,  or a feature receiver with a changed name. The problem does not occur  when you update an already installed solution.  You still have to launch  a new PowerShell process, though.)</p>
<p>To restart the timer service, run this:</p>
<blockquote><p>restart-service SPTimerV4</p></blockquote>
<p>And to launch a new PowerShell process, just call PowerShell from your script like this:</p>
<blockquote><p>$scriptPath = split-path $myInvocation.MyCommand.Definition</p>
<p>powershell -file (join-path $scriptPath Retract-Solution.ps1) -solutionId $solutionId -url $url -package $package</p>
<p>powershell -file (join-path $scriptPath Install-Solution.ps1) -solutionId $solutionId -url $url -package $package</p></blockquote>
<p>In this example I have one script that retracts a solution, and another that installs it.  Each is launched in a separate process, ensuring that they’ll get a fresh copy of the solution assemblies, and before they install/uninstall the solutions, they restart the timer service.</p>
<p>(There may be other processes to consider in other scenarios – check the SharePoint logs to see which process is performing which operations.)</p>
<p>Why isn’t this a problem when you do Visual Studio deployment?  Actually I have encountered that problem with Visual Studio, and had to restart it, but that may have been a bug in the beta.  In any case, Visual Studio runs its deployment steps with a process called vssphost4, which works directly with the object model, not through the Timer service.  So it takes care of this for you.</p>
<p>In other words, the Visual Studio deployment engine is really helpful when you’re getting started with SharePoint 2010, but not something you don’t want to rely on too much later on. If you develop SharePoint solutions, you <em>have</em> to face difficult deployment issues at some point.  Better that you face them on your development machine than on a production server.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/96/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=96&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2010/03/26/getting-around-gac-problems-when-you-deploy-sharepoint-solutions-with-powershell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e75d7aeb9f5b095d81f91ae8cb5c330?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bjørn Stærk</media:title>
		</media:content>
	</item>
		<item>
		<title>Make your own PowerShell scripts for SharePoint deployment in Visual Studio 2010</title>
		<link>http://sisharepoint.wordpress.com/2010/03/25/make-your-own-powershell-scripts-for-sharepoint-deployment-in-visual-studio-2010/</link>
		<comments>http://sisharepoint.wordpress.com/2010/03/25/make-your-own-powershell-scripts-for-sharepoint-deployment-in-visual-studio-2010/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 15:11:21 +0000</pubDate>
		<dc:creator>Bjørn Stærk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Solutions]]></category>

		<guid isPermaLink="false">http://spblog.software-innovation.com/?p=91</guid>
		<description><![CDATA[The SharePoint developer tools in Visual Studio 2010 allow you to deploy the solution you&#8217;re working on directly to a SharePoint site.  The deployment steps are both configurable and extensible: You can choose which deployment steps you want to perform (add solution, activate features, etc.), and it is also possible to define your own custom [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=91&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The SharePoint developer tools in Visual Studio 2010 allow you to deploy the solution you&#8217;re working on directly to a SharePoint site.  The deployment steps are both configurable and extensible: You can choose which deployment steps you want to perform (add solution, activate features, etc.), and it is also possible to define your own custom deployment steps in a Visual Studio extension.</p>
<p>The configuration options are fairly limited.  For instance, you can choose to &#8220;activate features&#8221; as part of the deployment.  But what if you have multiple features in your solution, and you normally only want to activate some of them?  You could move the rest into their own solution, but that&#8217;s an ugly way to solve this.  What then?</p>
<p><span id="more-91"></span>There are some guides on the web about how to make your own custom deployment steps, which can then do things like only activate some features instead of all of them.  Here&#8217;s a series of posts by Eric Shupps &#8211; <a href="http://www.binarywave.com/blogs/eshupps/Lists/Posts/Post.aspx?ID=228">part one</a>, <a href="http://www.binarywave.com/blogs/eshupps/Lists/Posts/Post.aspx?ID=231">two</a>, <a href="http://www.binarywave.com/blogs/eshupps/Lists/Posts/Post.aspx?ID=233">three</a>.  This is interesting, but it&#8217;s a lot of components to make for what could really be just a simple deployment script.  And then if you want to change the deployment step later, you&#8217;ll have to update the extension you&#8217;ve made on all the Visual Studio installations in your team.</p>
<p>What I prefer instead is to extend the deployment steps with PowerShell scripts.  You can of course run PowerShell scripts whenever you like outside of Visual Studio, but running them as part of the Visual Studio deployment steps is much more convenient.  You build, the scripts run, and there you are.  Here&#8217;s how to do it.</p>
<p><strong>Launching a PowerShell script during deployment</strong></p>
<p>The first thing you&#8217;ll want to do is create a new deployment configuration in the SharePoint tab in the project properties, and configure it to do nothing except run the post-deployment command line.</p>
<p>Next, create a PowerShell script file and put it in your project.  You could also put it somewhere else, since it isn&#8217;t strictly a part of the solution, but it&#8217;s more convenient that way.</p>
<p>Finally, add something like this to your Post-deployment Command Line:</p>
<p style="padding-left:30px;">%windir%\sysnative\windowspowershell\v1.0\powershell -file &#8220;$(ProjectDir)\Scripts\Deploy-Solution.ps1&#8243; -configuration &#8220;$(ConfigurationName)&#8221; -url &#8220;$(SharePointSiteUrl)&#8221; -package &#8220;$(TargetDir)$(TargetName).wsp&#8221;</p>
<p>The <strong>sysnative</strong> part at the beginning is necessary in order to launch PowerShell as a 64-bit process.  Visual Studio 2010 is 32-bit, and when you start PowerShell (or any other system command) from a 32-bit process, it <em>automatically launches the 32-bit version of that tool</em>.  This will fail, because SharePoint 2010 is 64-bit only.</p>
<p>On a 64-bit Windows machine, the 32-bit versions of system tools are located in c:\windows\SysWOW64, and the 64-bit versions in c:\windows\system32, (which is confusing enough in itself), but even if you explicitly refer to an application in system32, you&#8217;ll get the 32-bit version from SysWOW64 instead, because of magic.  %windir%\sysnative overrides that magic.  The sysnative folder only exists when you&#8217;re running in a 32-bit process, so don&#8217;t go looking for it on the disk, but it will be there when Visual Studio runs the post-deployment command line.</p>
<p>Btw: There is also a <a href="http://blog.mastykarz.nl/imtech-run-powershell-script-deployment-step/">Visual Studio extension from Imtech</a> that allows you to run a PowerShell script as a deployment step.  This is a good idea, and would accomplish the same thing, but I couldn&#8217;t get it to work on Visual Studio 2010 RC, so it probably needs some more work.</p>
<p><strong>Supporting multiple configurations</strong></p>
<p>What&#8217;s all those input parameters?  You don&#8217;t need to have them there, but they illustrate how you can integrate your script with the build variables from Visual Studio, which opens up some really exciting possibilities.</p>
<p><strong>$(ConfigurationName)</strong> is the name of the active configuration, such as Debug or Release.  <strong>$(SharePointSiteUrl)</strong> is the URL you&#8217;ve selected in the properties of the SharePoint project.  And <strong>$(TargetDir)$(TargetName).wsp</strong> is the name of the solution package file.</p>
<p>Some of these variables are the same as those you see in the pre- and post-build event editor.  SharePointSiteUrl is an extra variable that is available for SharePoint projects.  There are more, and they&#8217;re <a href="http://msdn.microsoft.com/en-us/library/ee696754%28VS.100%29.aspx">listed here</a>.</p>
<p>In order to read these parameters in your script, add this line at the top:</p>
<p style="padding-left:30px;">Param($configuration, $url, $package)</p>
<p>Here&#8217;s the fun part: Your script can now test on the active configuration, and change the deployment accordingly.  For instance, you could have one configuration that retracts and installs the solution, another that <a href="http://spblog.software-innovation.com/2010/01/21/using-the-featureupgrading-event-to-upgrade-features-sharepoint-2010/">upgrades an existing solution</a>, and one that just adds your assemblies directly to the GAC, (in order to save time when all you&#8217;ve done is change code).</p>
<p>You&#8217;ll also want to add the SharePoint snapin:</p>
<p style="padding-left:30px;">$snapin = get-pssnapin | where { $_.Name -eq &#8220;Microsoft.SharePoint.PowerShell&#8221; }</p>
<p style="padding-left:30px;">if($snapin -eq $null)  {</p>
<p style="padding-left:60px;">Add-PsSnapin Microsoft.SharePoint.PowerShell</p>
<p style="padding-left:30px;">}</p>
<p>By testing on whether the snapin is already loaded, you can also run this script from the SharePoint management shell.</p>
<p>This is a good starting point for taking full control of your Visual Studio deployment.  No need to create Visual Studio extensions, just do everything in PowerShell.</p>
<p>(Update: Also read this entry about <a href="http://sisharepoint.wordpress.com/2010/03/26/getting-around-gac-problems-when-you-deploy-sharepoint-solutions-with-powershell/">avoiding assembly cache problems</a> during deployment.)</p>
<div id="_mcePaste" style="position:absolute;width:1px;height:1px;overflow:hidden;top:552px;left:-10000px;">http://blog.mastykarz.nl/imtech-run-powershell-script-deployment-step/</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/91/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=91&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2010/03/25/make-your-own-powershell-scripts-for-sharepoint-deployment-in-visual-studio-2010/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e75d7aeb9f5b095d81f91ae8cb5c330?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bjørn Stærk</media:title>
		</media:content>
	</item>
		<item>
		<title>Changing the disk location of uncustomized (ghosted) pages</title>
		<link>http://sisharepoint.wordpress.com/2010/03/02/changing-the-disk-location-of-uncustomized-ghosted-pages/</link>
		<comments>http://sisharepoint.wordpress.com/2010/03/02/changing-the-disk-location-of-uncustomized-ghosted-pages/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 13:10:52 +0000</pubDate>
		<dc:creator>Bjørn Stærk</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://spblog.software-innovation.com/?p=81</guid>
		<description><![CDATA[Files that have been added to SharePoint can be either customized or uncustomized.  Customized means the data lives in the database.  Uncustomized means the entry in the database just points to a location on the disk.  When you change an uncustomized file on a particular site, for instance using SharePoint Designer, it becomes customized, and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=81&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Files that have been added to SharePoint can be either customized or uncustomized.  Customized means the data lives in the database.  Uncustomized means the entry in the database just points to a location on the disk.  When you change an uncustomized file on a particular site, for instance using SharePoint Designer, it becomes customized, and is moved into the database.</p>
<p><span id="more-81"></span>(Previously the terms <em>unghosted</em> and <em>ghosted</em> were used instead of customized and uncustomized.  This was confusing, and you should forget them right away.)</p>
<p>When files are uncustomized, multiple sites may be using the same copy of the file, so you can change it in one place, without having to update every single instance of it in different sites.  If the files are ASPX pages or master pages, there&#8217;s another advantage to having them uncustomized: Customized pages have a lot of restrictions.  For instance,  you can&#8217;t have inline code or <a href="http://littletalk.wordpress.com/2009/11/04/use-session-in-custom-page-session-state-can-only-be-used-when-enablesessionstate-is-set-to-true/">use sessions</a> without adding an exception for your page in the <a href="http://msdn.microsoft.com/en-us/library/bb862025.aspx">PageParserPaths section of web.config</a>.   The reason is that, otherwise, users of a site could just upload some code and have it executed, which would be a gaping security hole.</p>
<p>Normally you add uncustomized pages through features, using the <a href="http://msdn.microsoft.com/en-us/library/ms459213.aspx">File element</a>.  But there&#8217;s a drawback: If the page exists already, for instance because you&#8217;re trying to replace a standard page like default.aspx, there appears to be no way to overwrite the existing file.  The documentation implies that you can do this with the IgnoreIfAlreadyExists attribute, but <a href="http://johanleino.wordpress.com/2009/04/22/howto-handling-file-updates-in-sharepoint/">that&#8217;s not actually the case</a>.  IgnoreIfAlreadyExists just determines whether SharePoint should <em>let you know</em> (by failing to activate the feature) that it couldn&#8217;t overwrite the existing file.</p>
<p>The only way to overwrite a file as part of a feature activation is to do it programmatically, in the feature receiver&#8217;s FeatureActivated event, (and/or delete the file in FeatureDeactivated).  <a href="http://vivek-soni.blogspot.com/2009/07/overwriting-files-using-module-element.html">Here&#8217;s a good description</a> of how to add a file by parsing the feature definition and adding the SPFile objects in code.  But this example won&#8217;t work if you want to add an <em>uncustomized</em> file.</p>
<p>There actually seems to be no way to create an uncustomized file through the SharePoint object model.  There is a method called AddGhosted in the internal SPRequest class, but <a href="http://hristopavlov.wordpress.com/2009/01/19/understanding-sharepoint-sprequest/">using SPRequest to bypass the public API</a> leaves your installation in an <em>unsupported state</em>, which is a Bad Idea.</p>
<p>So the <em>only</em> way to add an uncustomized file is with the File element in the feature definition.  And the <em>only</em> way to overwrite an existing file is with code.  How then can we add an uncustomized file and overwrite an existing file at the same time?</p>
<p>Easy: By adding the file with a different name, then use code to <a href="http://www.codeproject.com/KB/sharepoint/Reghost_Sample.aspx">move it and replace the original file</a>.</p>
<p>In the feature:</p>
<pre class="code"><span style="color:blue;">&lt;</span><span style="color:#a31515;">File </span><span style="color:red;">Path</span><span style="color:blue;">=</span>"<span style="color:blue;">Pages\defaultv2.aspx</span>" <span style="color:red;">Url</span><span style="color:blue;">=</span>"<span style="color:blue;">defaultv2.aspx</span>"<span style="color:blue;">/&gt;
</span></pre>
<pre class="code"><span style="color:blue;"> </span></pre>
<p>And in the FeatureActivated event of the feature receiver:</p>
<pre class="code"><span style="color:#2b91af;">SPFile </span>sourceFile = site.RootWeb.GetFile(<span style="color:#a31515;">"defaultv2.aspx"</span>);
sourceFile.MoveTo(<span style="color:#a31515;">"default.aspx"</span>, <span style="color:blue;">true</span>);</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Now default.aspx will be read from your location instead of the old one.</p>
<p>The best solution is obviously not to overwrite files that are part of the standard site template at all.  In this example, we could have instead changed the WelcomePage of the site to defaultv2.aspx, like this:</p>
<pre class="code"><span style="color:#2b91af;">SPFolder </span>rootFolder = site.RootWeb.RootFolder;
rootFolder.WelcomePage = <span style="color:#a31515;">"defaultv2.aspx"</span>;
rootFolder.Update();</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>But there may be circumstances where you want to keep the original URL, for instance if users may have already bookmarked it.  Then you need to do it this way.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/81/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=81&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2010/03/02/changing-the-disk-location-of-uncustomized-ghosted-pages/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e75d7aeb9f5b095d81f91ae8cb5c330?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bjørn Stærk</media:title>
		</media:content>
	</item>
		<item>
		<title>&#8220;The language-neutral solution package was not found&#8221;</title>
		<link>http://sisharepoint.wordpress.com/2010/01/28/the-language-neutral-solution-package-was-not-found/</link>
		<comments>http://sisharepoint.wordpress.com/2010/01/28/the-language-neutral-solution-package-was-not-found/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 11:58:37 +0000</pubDate>
		<dc:creator>Bjørn Stærk</dc:creator>
				<category><![CDATA[Beta experimentation]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://spblog.software-innovation.com/?p=79</guid>
		<description><![CDATA[We sometimes get this error when deploying SharePoint 2010 (beta 2) solutions from Visual Studio 2010: Error occurred in deployment step &#8216;Retract Solution&#8217;: The language-neutral solution package was not found. We don&#8217;t know why this happens, possibly some beta problem, but one solution is to call the Delete method on the solution directly, using PowerShell: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=79&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>We sometimes get this error when deploying SharePoint 2010 (beta 2) solutions from Visual Studio 2010:</p>
<blockquote><p>Error occurred in deployment step &#8216;Retract Solution&#8217;: The language-neutral solution package was not found.</p></blockquote>
<p>We don&#8217;t know why this happens, possibly some beta problem, but one solution is to call the Delete method on the solution directly, using <a href="http://spblog.software-innovation.com/2010/01/12/time-to-replace-stsadm-with-powershell/">PowerShell</a>:</p>
<p style="padding-left:30px;">(get-spsolution mysolution.wsp).Delete()</p>
<p>You can also run get-spsolution without parameters to see which solutions are currently installed in the farm.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/79/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=79&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2010/01/28/the-language-neutral-solution-package-was-not-found/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e75d7aeb9f5b095d81f91ae8cb5c330?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bjørn Stærk</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting multiple layers of web.config modifications to live together</title>
		<link>http://sisharepoint.wordpress.com/2010/01/22/getting-multiple-layers-of-web-config-modifications-to-live-together-sharepoint-2010/</link>
		<comments>http://sisharepoint.wordpress.com/2010/01/22/getting-multiple-layers-of-web-config-modifications-to-live-together-sharepoint-2010/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 10:00:34 +0000</pubDate>
		<dc:creator>Bjørn Stærk</dc:creator>
				<category><![CDATA[Beta experimentation]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Upgrade]]></category>
		<category><![CDATA[Web.config modification]]></category>

		<guid isPermaLink="false">http://spblog.software-innovation.com/?p=74</guid>
		<description><![CDATA[In our SharePoint 2010 solutions we have web.config modifications that are standard, and custom modifications that are later added on top of the standard ones.  This article describes a way for multiple levels of modifications to live together, in a way that supports upgrades of the standard modifications without destroying the custom ones. Before you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=74&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In our SharePoint 2010 solutions we have web.config modifications that are standard, and custom modifications that are later added on top of the standard ones.  This article describes a way for multiple levels of modifications to live together, in a way that supports upgrades of the standard modifications without destroying the custom ones.</p>
<p>Before you read this you should be familiar with the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spwebconfigmodification%28office.14%29.aspx">web config modification framework</a> in SharePoint.  It&#8217;s important never to modify SharePoint web.config files directly, especially when you&#8217;re deploying your solutions to a farm environment.</p>
<p><span id="more-74"></span>Let&#8217;s say the standard web.config modifications made by our solution look like this:</p>
<p style="padding-left:30px;">&lt;configuration&gt;</p>
<p style="padding-left:60px;"><strong>&lt;ourproduct&gt;</strong></p>
<p style="padding-left:90px;"><strong>&lt;standard-element&gt;</strong></p>
<p style="padding-left:120px;"><strong>&lt;sub-element/&gt;</strong></p>
<p style="padding-left:90px;"><strong>&lt;/standard-element&gt;</strong></p>
<p style="padding-left:60px;"><strong>&lt;/ourproduct&gt;</strong></p>
<p style="padding-left:30px;">&lt;/configuration&gt;</p>
<p>.. and then somebody adds an attribute and a node to this for a particular customer, like this:</p>
<p style="padding-left:30px;">&lt;configuration&gt;</p>
<p style="padding-left:60px;">&lt;ourproduct&gt;</p>
<p style="padding-left:90px;">&lt;standard-element <strong>custom-property=&#8221;x&#8221;</strong>&gt;</p>
<p style="padding-left:120px;">&lt;sub-element/&gt;</p>
<p style="padding-left:90px;">&lt;/standard-element&gt;</p>
<p style="padding-left:90px;"><strong>&lt;custom-element/&gt;</strong></p>
<p style="padding-left:60px;">&lt;/ourproduct&gt;</p>
<p style="padding-left:30px;">&lt;/configuration&gt;</p>
<p>.. and now we want to update the standard section like this:</p>
<p style="padding-left:30px;">&lt;configuration&gt;</p>
<p style="padding-left:60px;">&lt;ourproduct&gt;</p>
<p style="padding-left:90px;"><strong>&lt;standard-element</strong> custom-property=&#8221;x&#8221;/&gt;</p>
<p style="padding-left:90px;">&lt;custom-element/&gt;</p>
<p style="padding-left:90px;"><strong>&lt;another-standard-element/&gt;</strong></p>
<p style="padding-left:60px;">&lt;/ourproduct&gt;</p>
<p style="padding-left:30px;">&lt;/configuration&gt;</p>
<p>We&#8217;ve removed one element, and added another.  And we want to deploy this to all installations where our solution is in use, without knowing which (or if) custom elements may have been added.</p>
<h3>Using Sequence and Owner</h3>
<p>As long as we only add new nodes, and never remove old ones, we could simply add new web config modifications to SharePoint.  But I&#8217;m going to describe a solution that I think is cleaner, and also allows you to delete some of the standard elements.</p>
<p>The key is the Sequence and Owner properties of the SPWebConfigModification class.  <strong>Owner</strong> is used to keep track of who owns a modification, and should be the same for all modifications added by a particular feature.  That way, when the feature deactivates, it can just loop through all the web config modifications, and delete the ones with that name.</p>
<p><strong>Sequence</strong> tells SharePoint in which order to apply modifications.  If you don&#8217;t set a Sequence, the order depends on the order you added the modifications in, which becomes fragile if you want to upgrade a feature later.  In our scenario, the standard changes should have a low Sequence, for instance 0, and the custom changes a higher Sequence, such as 10.  That way, when the web.config is updated, the custom changes are always added on top of the standard ones.</p>
<p>(There&#8217;s no point in having different Sequence values for each modification in your feature, as they&#8217;re always applied in the order you add them.)</p>
<h3>Activation and deactivation</h3>
<p>So let&#8217;s begin with the initial activation.  We have a feature called StandardFeatureX and another called CustomFeatureY.  When each feature activates, they add their modifications:</p>
<p style="padding-left:30px;">SPWebConfigModification mod = new SPWebConfigModification(&#8220;ourproduct&#8221;, &#8220;configuration);</p>
<p style="padding-left:30px;">mod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;</p>
<p style="padding-left:30px;">mod.Value = &#8220;&lt;ourproduct&gt;&lt;standard-element&gt;&lt;sub-element/&gt;&lt;/standard-element&gt;&lt;/ourproduct&gt;&#8221;;</p>
<p style="padding-left:30px;">mod.Owner = &#8220;StandardFeatureX&#8221;;</p>
<p style="padding-left:30px;">mod.Sequence = 0; // 10 for the custom feature</p>
<p style="padding-left:30px;">
<p style="padding-left:30px;">webApp.WebConfigModifications.Add(mod);</p>
<p>And when they are deactivated, they delete them, checking the Owner property to make sure they remove everything:</p>
<p style="padding-left:30px;">List&lt;SPWebConfigModification&gt; modsToDelete = new List&lt;SPWebConfigModification&gt;();</p>
<p style="padding-left:30px;">foreach (SPWebConfigModification existingMod in webApp.WebConfigModifications)</p>
<p style="padding-left:30px;">{</p>
<p style="padding-left:60px;">if (existingMod.Owner == &#8220;StandardFeatureX&#8221;)</p>
<p style="padding-left:60px;">{</p>
<p style="padding-left:90px;">modsToDelete.Add(existingMod);</p>
<p style="padding-left:60px;">}</p>
<p style="padding-left:30px;">}</p>
<p style="padding-left:30px;">foreach (SPWebConfigModification modToDelete in modsToDelete)</p>
<p style="padding-left:30px;">{</p>
<p style="padding-left:60px;">webApp.WebConfigModifications.Remove(modToDelete);</p>
<p style="padding-left:30px;">}</p>
<p>After the modifications have been added or removed, we apply the modifications, like this:</p>
<p style="padding-left:30px;">webApp.Update();</p>
<p style="padding-left:30px;">webApp.Farm.Services.GetValue&lt;SPWebService&gt;().ApplyWebConfigModifications();</p>
<p>So if we first activate StandardFeatureX, and then CustomFeatureY, we get the result in the second example above.  (We can then later deactivate the features in the opposite order to return web.config to its initial state.)</p>
<h3>Upgrading the standard modifications</h3>
<p>But now we want to change StandardFeatureX so that we get the result in the third example above.  How do we do that?  If you simply deactivate and activate StandardFeatureX, SharePoint won&#8217;t know what to do with the modifications from CustomFeatureY in the mean time.  And we can&#8217;t deactivate CustomFeatureY, because we don&#8217;t know that it exists.</p>
<p>The solution is to use a <strong>feature upgrade</strong>, <a href="http://spblog.software-innovation.com/2010/01/21/using-the-featureupgrading-event-to-upgrade-features-sharepoint-2010/">as described in an earlier post</a>, and then in the FeatureUpgrading method do the following:</p>
<p style="padding-left:30px;">[Remove all our old modifications]</p>
<p style="padding-left:30px;">[Add all our modifications back again, the way they're supposed to look now]</p>
<p style="padding-left:30px;">webApp.Update();</p>
<p style="padding-left:30px;">webApp.Farm.Services.GetValue&lt;SPWebService&gt;().ApplyWebConfigModifications();</p>
<p>The trick is to not apply the modifications until the end, when we&#8217;re done.  SharePoint does not update web.config files immediately when you add or remove a modification.  It waits until you call ApplyWebConfigModifications.  So it&#8217;s okay that the first step leaves the modifications in an invalid state, as long as it&#8217;s made valid again immediately afterwards.</p>
<p>And when you do call ApplyWebConfigModifications, the modifications are made in the order of their Sequence values first, and the order they were added second, like this:</p>
<p style="padding-left:30px;">Sequence 0, added first</p>
<p style="padding-left:30px;">Sequence 0, added second</p>
<p style="padding-left:30px;">Sequence 10, added first</p>
<p style="padding-left:30px;">Sequence 10, added second</p>
<p>It&#8217;s still possible that the standard changes will conflict with the custom changes, of course.  You can only remove elements that are not open for customization.  But this approach allows you make non-conflicting upgrades that might otherwise be difficult, and it allows you to have a few big chunks of XML that you add new elements to, instead of making every change as a separate modification.</p>
<h3>Behind the scenes</h3>
<p>When you&#8217;re working with web.config modifications it&#8217;s useful to look at the modifications that are currently in effect on a web application.  Use this PowerShell command:</p>
<p style="padding-left:30px;">(get-spwebapplication http://mysite).WebConfigModifications | select Name, Path, Sequence, Owner</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/74/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=74&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2010/01/22/getting-multiple-layers-of-web-config-modifications-to-live-together-sharepoint-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e75d7aeb9f5b095d81f91ae8cb5c330?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bjørn Stærk</media:title>
		</media:content>
	</item>
		<item>
		<title>Using the FeatureUpgrading event to upgrade features</title>
		<link>http://sisharepoint.wordpress.com/2010/01/21/using-the-featureupgrading-event-to-upgrade-features-sharepoint-2010/</link>
		<comments>http://sisharepoint.wordpress.com/2010/01/21/using-the-featureupgrading-event-to-upgrade-features-sharepoint-2010/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 11:21:34 +0000</pubDate>
		<dc:creator>Bjørn Stærk</dc:creator>
				<category><![CDATA[Beta experimentation]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Upgrade]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://spblog.software-innovation.com/?p=67</guid>
		<description><![CDATA[In SharePoint 2010 there is now a way to control how features are upgraded from one version to another.  Here&#8217;s how to get it working, using the new FeatureUpgrading event in the feature receiver class. Writing the upgrade code Add an event receiver to your feature, and uncomment the FeatureUpgrading method.  This method will run [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=67&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In SharePoint 2010 there is now a way to control how features are upgraded from one version to another.  Here&#8217;s how to get it working, using the new FeatureUpgrading event in the feature receiver class.</p>
<p><span id="more-67"></span></p>
<p><strong>Writing the upgrade code</strong></p>
<p>Add an event receiver to your feature, and uncomment the FeatureUpgrading method.  This method will run whenever your feature is being upgraded.</p>
<p>Next, go to the feature properties, and copy the values for Receiver Assembly and Receiver Class to Upgrade Actions Receiver Assembly and Upgrade Actions Receiver Class, and set an initial value for the Version property, for instance 1.0.0.0.</p>
<p><img class="alignnone size-full wp-image-68" title="Feature upgrading - properties" src="http://sisharepoint.files.wordpress.com/2010/01/feature-upgrading-properties.png?w=468&#038;h=234" alt="" width="468" height="234" /></p>
<p>The Version is on the same format as .Net assembly versions, ie. Major.Minor.Build.Revision.</p>
<p>Deploy the solution, then go back and increase the Version, for instance to 1.0.0.1.  Open the feature designer, and click on Manifest.</p>
<p>Click on Edit options.  This allows you to add XML to your feature that will be merged with what you&#8217;ve configured in the feature designer and the feature properties.  Enter the following:</p>
<p style="padding-left:30px;">&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243; ?&gt;</p>
<p style="padding-left:30px;">&lt;Feature xmlns=&#8221;<a href="http://schemas.microsoft.com/sharepoint/">http://schemas.microsoft.com/sharepoint/</a>&#8220;&gt;</p>
<p style="padding-left:60px;">&lt;UpgradeActions&gt;</p>
<p style="padding-left:90px;">&lt;VersionRange&gt;</p>
<p style="padding-left:120px;">&lt;CustomUpgradeAction Name=&#8221;DoTheUpgrade&#8221;/&gt;</p>
<p style="padding-left:90px;">&lt;/VersionRange&gt;</p>
<p style="padding-left:60px;">&lt;/UpgradeActions&gt;</p>
<p style="padding-left:30px;">&lt;/Feature&gt;</p>
<p>You can specify multiple VersionRange elements that apply different upgrade actions to different version ranges, by using the BeginVersion and EndVersion attributes.  If you don&#8217;t specify these values, like above, the same upgrade actions are taken no matter which version we&#8217;re upgrading from, so then it&#8217;s up to your code to determine what it needs to do. You can access the latest and current version numbers from properties.Definition.Version (latest) and properties.Feature.Version (current).</p>
<p>The CustomUpgradeAction element is the node that actually triggers the call to FeatureUpgrading.  The Name property is sent to the method as the parameter upgradeActionName, and you can use that to determine which upgrade action to perform, like this:</p>
<p style="padding-left:30px;">&lt;VersionRange BeginVersion=&#8221;1.0.0.0&#8243; EndVersion=&#8221;2.0.0.0&#8243;&gt;</p>
<p style="padding-left:60px;">&lt;CustomUpgradeAction Name=&#8221;UpgradeToV2&#8243;/&gt;</p>
<p style="padding-left:30px;">&lt;/VersionRange&gt;</p>
<p style="padding-left:30px;">&lt;VersionRange BeginVersion=&#8221;2.0.0.0&#8243; EndVersion=&#8221;3.0.0.0&#8243;&gt;</p>
<p style="padding-left:60px;">&lt;CustomUpgradeAction Name=&#8221;UpgradeToV3&#8243;/&gt;</p>
<p style="padding-left:30px;">&lt;/VersionRange&gt;</p>
<p>And in the feature receiver class:</p>
<p style="padding-left:30px;">public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary&lt;string, string&gt; parameters)</p>
<p style="padding-left:30px;">{</p>
<p style="padding-left:60px;">switch (upgradeActionName)</p>
<p style="padding-left:60px;">{</p>
<p style="padding-left:90px;">case &#8220;UpgradeToV2&#8243;:</p>
<p style="padding-left:90px;">..</p>
<p style="padding-left:90px;">case &#8220;UpgradeToV3&#8243;:</p>
<p style="padding-left:90px;">..</p>
<p style="padding-left:60px;">}</p>
<p style="padding-left:30px;">}</p>
<p>We can now deploy the new version.  Do not use Visual Studio to do this, since the default deployment action in Visual Studio is to retract the solution and then add it back in again.  Instead, just package the solution, then use the update-spsolution command in PowerShell:</p>
<p style="padding-left:30px;">update-spsolution -identity SharePointProject3.wsp -literalpath bin\Debug\SharePointProject3.wsp -GACDeployment</p>
<p>(Note: You should probably start a new instance of PowerShell after each time you build, otherwise the actions you perform may be run against an outdated version of your assembly from the GAC.  The same thing sometimes applies to Visual Studio deployment, for instance if one solution refers to an assembly in another solution &#8211; hopefully this is a bug in the beta.)</p>
<p><strong>Performing the upgrade</strong></p>
<p>At this point the new version of the feature has been installed, but it has not been upgraded on the sites where it is in use.  You can verify this by running the following script in <a href="http://spblog.software-innovation.com/2010/01/12/time-to-replace-stsadm-with-powershell/">PowerShell</a>:</p>
<p style="padding-left:30px;">get-spfeature | where {$_.DisplayName -eq &#8220;FeatureName&#8221;} | select DisplayName, Version</p>
<p>This is the latest version.  Here&#8217;s the version currently in use on your site:</p>
<p style="padding-left:30px;">(get-spsite http://[siteurl]).Features | where {$_.Definition.DisplayName -eq &#8220;FeatureName&#8221;} | select Version</p>
<p>If you&#8217;ve done everything correctly, the versions should differ.  It&#8217;s now time to perform the actual upgrade.  Features aren&#8217;t upgraded automatically.  There are two ways to trigger an upgrade, one slow and one quick.</p>
<p>The slow way is to run psconfig:</p>
<p style="padding-left:30px;">psconfig -cmd upgrade -inplace b2b</p>
<p>This will take several minutes, but is probably the correct way to perform an upgrade in a test or production environment.  &#8220;-inplace b2b&#8221; means that features will be upgraded if any part of the version has been increased, even the build or revision number.  If you specify &#8220;-inplace v2v&#8221;, features will only be upgraded if the major or minor version number has increased, ie. 1.1.0.0 =&gt; 1.2.0.0.</p>
<p>A quicker way to perform an upgrade is to call the Upgrade method on the SPFeature object directly on the site where it is activated.</p>
<p style="padding-left:30px;">$site = get-spsite http://siteurl</p>
<p style="padding-left:30px;">$enabledfeature = $site.Features | where {$_.Definition.DisplayName -eq &#8220;FeatureName&#8221; }</p>
<p style="padding-left:30px;">if($enabledfeature)</p>
<p style="padding-left:30px;">{</p>
<p style="padding-left:60px;">$enabledfeature.Upgrade($false)</p>
<p style="padding-left:30px;">}</p>
<p>This may be a useful script to run on your development server when you want to test that your upgrade code is running correctly.</p>
<p>Now if you check the current version again, it should be the latest version.  Note that you&#8217;re upgrading the feature only on one particular site.  Also note that the feature in this example is Site-scoped.  For other scopes, run the upgrade at the appropriate level.</p>
<p>In addition to executing upgrade code, you can also specify other actions in the VersionRange element, such as adding a field to a content type, or renaming a module file.</p>
<p><strong>Sources and more information</strong></p>
<p style="padding-left:30px;">Corey Roth: <a href="http://blackberry.sys-con.com/node/1234988">Feature Versioning and Upgrades in SharePoint 2010</a></p>
<p style="padding-left:30px;">Dave Graham: <a href="http://sharepointtipoftheday.blogspot.com/2009/11/in-place-upgrade-of-solutions-in.html">In-place Upgrade of Solutions in SharePoint 2010</a></p>
<p style="padding-left:30px;">MSDN: <a href="http://msdn.microsoft.com/en-us/library/ee538968%28office.14%29.aspx">How to: Use Upgrade Code to Activate a Feature with Dependencies</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/67/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=67&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2010/01/21/using-the-featureupgrading-event-to-upgrade-features-sharepoint-2010/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e75d7aeb9f5b095d81f91ae8cb5c330?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bjørn Stærk</media:title>
		</media:content>

		<media:content url="http://sisharepoint.files.wordpress.com/2010/01/feature-upgrading-properties.png" medium="image">
			<media:title type="html">Feature upgrading - properties</media:title>
		</media:content>
	</item>
		<item>
		<title>Time to replace stsadm with PowerShell</title>
		<link>http://sisharepoint.wordpress.com/2010/01/12/time-to-replace-stsadm-with-powershell/</link>
		<comments>http://sisharepoint.wordpress.com/2010/01/12/time-to-replace-stsadm-with-powershell/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 07:59:31 +0000</pubDate>
		<dc:creator>Bjørn Stærk</dc:creator>
				<category><![CDATA[Beta experimentation]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SharePoint 2010]]></category>

		<guid isPermaLink="false">http://sisharepoint.wordpress.com/?p=59</guid>
		<description><![CDATA[One thing in SharePoint 2010 I appreciate as a developer is the close integration with PowerShell.  PowerShell is the result of a bit of Unix envy at Microsoft.  Unix systems have had good command-line tools and scripting languages since the dawn of time.  Windows had cmd.exe, which was inferior 20 years ago when it was [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=59&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One thing in SharePoint 2010 I appreciate as a developer is the close integration with PowerShell.  PowerShell is the result of a bit of Unix envy at Microsoft.  Unix systems have had good command-line tools and scripting languages since the dawn of time.  Windows had cmd.exe, which was inferior 20 years ago when it was known as MS-DOS, and hasn&#8217;t been changed since.</p>
<p>But when PowerShell finally did arrive, in 2006, it was as good as the Unix alternatives, and in one important way superior: Object piping.  PowerShell allows you to string commands together and pipe the results of one as input to the next, <em>as .Net objects</em>.  In a SharePoint 2010 context, that allows you to do this:</p>
<p><span id="more-59"></span></p>
<p style="padding-left:30px;">get-spsite | get-spweb -filter {$_.Template -eq &#8220;STS#0&#8243; } | foreach-object { enable-spfeature -identity LinksList -force -url $_.Url }</p>
<p><em>get-spsite</em> without parameters returns all site collections in the farm, <em>get-spweb</em> looks for every site in those site collections that use the site template STS#0 (Team Site), and then the <em>foreach</em> command loops through each of these sites and enables the LinksList feature on them.  ($_ refers to the current object in the foreach loop.  The same syntax is used in related commands such as <em>where-object</em>, which filters results based on a condition.)</p>
<p>In short, this command finds all sites based on a given template, and activates a feature on them.</p>
<p>Is this useful?  Yes &#8211; for SharePoint 2007 I made my own deployment tool just to do things like that.  Now it&#8217;s just a line of commands.</p>
<p>PowerShell syntax is a bit daunting.  Even if you know the basic concepts from a Unix shell, there are a lot of commands to get familiar with.  So probably the most important thing to learn in PowerShell as a beginner is how to get help about the available commands.  Which, in the literal-minded world of PowerShell you do by typing, well, <em>get-help</em>:</p>
<p style="padding-left:30px;">get-help</p>
<p>To get help about a particular command, write get-help commandname, for instance:</p>
<p style="padding-left:30px;">get-help get-command</p>
<p style="padding-left:30px;">get-help get-command -examples</p>
<p>The first will tell you how to use <em>get-command</em>, which allows you to find all the available commands, and the -examples parameter will show you examples of how to use it.  -examples can be used with all PowerShell commands.</p>
<p>To get all SharePoint commands in PowerShell, write:</p>
<p style="padding-left:30px;">get-command -module Microsoft.SharePoint.PowerShell</p>
<p>To get all commands for the SPWeb (site) object, write:</p>
<p style="padding-left:30px;">get-command -noun SPWeb</p>
<p>All PowerShell are built up on the format verb-noun, for instance <em>get-spweb</em>, so when we ask for all commands where the noun is SPWeb, we get <em>get-spweb</em>, <em>export-spweb</em>, <em>new-spweb</em>, <em>remove-spweb</em>, etc.</p>
<p>You can also dig into the properties and methods of the objects you retrieve:</p>
<p style="padding-left:30px;">get-spweb http://servername | get-member</p>
<p style="padding-left:30px;">get-spweb http://servername | select *</p>
<p>The first gives you a list of all the properties and methods that exist on an SPWeb object.  The second retrieves all the property values on that object.</p>
<p>One aspect of working with SharePoint in PowerShell that probably will trip people up, because it&#8217;s unintuitive, is that you must use <em>start-spassignment</em> and <em>stop-spassignment</em> to prevent SPWeb and SPSite objects you&#8217;re working with from being automatically disposed.  For instance:</p>
<p style="padding-left:30px;">start-spassignment -global</p>
<p style="padding-left:30px;">$web = get-spweb http://servername</p>
<p style="padding-left:30px;">[operate on the $web object here]</p>
<p style="padding-left:30px;">stop-spassignment -global</p>
<p>The -global parameter means that no objects will be disposed at all until <em>stop-spassignment</em> is called.  So you can safely work with anything you instantiate.  It&#8217;s also possible to do this with individual objects, which is useful to prevent memory bloat in complex scripts.  See the documentation on start-spassignment for more on this.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/59/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=59&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2010/01/12/time-to-replace-stsadm-with-powershell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e75d7aeb9f5b095d81f91ae8cb5c330?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bjørn Stærk</media:title>
		</media:content>
	</item>
		<item>
		<title>BCS first impressions</title>
		<link>http://sisharepoint.wordpress.com/2010/01/06/bcs-first-impressions/</link>
		<comments>http://sisharepoint.wordpress.com/2010/01/06/bcs-first-impressions/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 13:03:59 +0000</pubDate>
		<dc:creator>Bjørn Stærk</dc:creator>
				<category><![CDATA[Beta experimentation]]></category>
		<category><![CDATA[BCS]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[SharePoint Designer]]></category>
		<category><![CDATA[Visual Studio 2010]]></category>

		<guid isPermaLink="false">http://sisharepoint.wordpress.com/?p=54</guid>
		<description><![CDATA[The right way to think of Business Connectivity Services in SharePoint 2010 is probably as a pipe you can attach your data to, and, once you&#8217;re connected, that pipe can take you anywhere within SharePoint and Office.  One shouldn&#8217;t be taken in by the hype here &#8211; this is the sort of functionality Microsoft often [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=54&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The right way to think of Business Connectivity Services in SharePoint 2010 is probably as a pipe you can attach your data to, and, once you&#8217;re connected, that pipe can take you anywhere within SharePoint and Office.  One shouldn&#8217;t be taken in by the hype here &#8211; this is the sort of functionality Microsoft often oversells as a magical tool for anything &#8211; but within the limitations BCS looks like a really useful technology for anyone who has data in various systems that they want to display in a SharePoint context.  Which is probably everyone.</p>
<p>There are four approaches to BCS, two of them are comparatively easy and can be used with SharePoint Designer, and the other two are more difficult and are used with Visual Studio.</p>
<p><strong><span id="more-54"></span>The easy approaches: Database and WCF connections with SharePoint Designer</strong></p>
<p>If you&#8217;re doing a fairly simple integration, and if your data are available from a database or a WCF service, you can accomplish a lot with SharePoint Designer, which has really become a must-have tool for working with SharePoint 2010.</p>
<p>That&#8217;s not to say that everything about this is easy.  Setting up relations between different external content types is unintuitive, nor could I get navigation across these relations to work, (this is either a bug with me or the beta).  But you can achieve a lot by clicking around a bit.</p>
<p>More information:</p>
<ul type="disc">
<li><a href="http://msdn.microsoft.com/en-us/library/ee558778%28office.14%29.aspx">How to: Create External Lists      in SharePoint</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ee558417%28office.14%29.aspx">How to: Add an Association      between Two External Content Types</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ee557949%28office.14%29.aspx">..more BCS howto&#8217;s</a></li>
</ul>
<p><strong>The hard approaches: .Net assemblies and custom connectors with Visual Studio</strong></p>
<p>It&#8217;s a bit unfair to group these two together: Defining external content types in .Net assemblies has very good tool support within Visual Studio 2010.  Custom connectors, by contrast, appear not to be documented at all, at the moment.</p>
<p>The .Net assembly approach involves using Visual Studio to edit the BDC model that defines your external content types, and write classes that contain logic for retrieving and updating data.  Visual Studio contains a BDC Explorer which you can use to work with the underlying XML file that defines the model.  The tools are very good, compared to editing the XML by hand, but it doesn&#8217;t actually make the task any less complex, it just provides a visual interface for it.</p>
<p>One immediate stumbling block for developers will probably be that you have to define every property of your data types every time you refer to them.  For instance, you can&#8217;t just say &#8220;this is what a Product looks like, and I want to return it from these five methods&#8221;.  You say &#8220;I want this method to return something called Product, which looks like this, and I want this other method to return something called Product, which looks like this, and .. etc.&#8221;</p>
<p>The error messages aren&#8217;t helpful.  For instance, I got this error when trying to create a list for an external content type I had defined in .Net: &#8220;Could not save changes.  No Finders available in the View Group associated with the SpecificFinder (Read Item) operation &#8216;ReadItem&#8217; on Entity (External Content Type) with Namespace = &#8216;..&#8217;, Name = &#8216;..&#8217;.  The list cannot be created.&#8221;</p>
<p>Huh?  It turned out that I had misspelled a property name, so that the BDC model referred to a property that didn&#8217;t exist, but there were no error messages anywhere that said so, or even said which property or type descriptor that caused the problem.</p>
<p>When you use the .Net assembly approach, you need to define classes for everything you want to return.  This becomes a limitation if you want to expose a large data model, or if the model is dynamic.  In those cases you should consider making a custom connector, which allow you to decide everything about how you read and update data for yourself.</p>
<p>Custom connectors are also written in .Net, but you get no tool support from Visual Studio.  Nor is there much documentation about how to make one.  Hopefully there will be more later, because this will probably be the right approach for many advanced scenarios.</p>
<p>More information:</p>
<ul type="disc">
<li><a href="http://msdn.microsoft.com/en-us/magazine/ee819133.aspx">Using Business Connectivity      Services in SharePoint 2010</a></li>
<li><a href="http://www.toddbaginski.com/blog/archive/2009/12/01/how-to-programmatically-create-a-sharepoint-2010-external-content-type.aspx">HOW TO: Programmatically      create a SharePoint 2010 External Content Type</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ee554911%28office.14%29.aspx">Differences Between Using the      .NET Assembly Connector and Writing a Custom Connector</a></li>
</ul>
<p><strong>Conclusion</strong></p>
<p>This is going to be big.  BCS has its oddities, and will not be easy to master, but the payoff from doing so is potentially huge, so anyone who works with SharePoint development should get familiar with it.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/54/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=54&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2010/01/06/bcs-first-impressions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e75d7aeb9f5b095d81f91ae8cb5c330?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bjørn Stærk</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting the current users language programmatically</title>
		<link>http://sisharepoint.wordpress.com/2009/12/21/getting-the-current-users-language-programmatically/</link>
		<comments>http://sisharepoint.wordpress.com/2009/12/21/getting-the-current-users-language-programmatically/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 15:01:05 +0000</pubDate>
		<dc:creator>Oddleif Halvorsen</dc:creator>
				<category><![CDATA[Beta experimentation]]></category>
		<category><![CDATA[Multilingual sites]]></category>
		<category><![CDATA[Web Part Localization]]></category>

		<guid isPermaLink="false">http://sisharepoint.wordpress.com/?p=37</guid>
		<description><![CDATA[Running with multilingual sites in SharePoint 2010, it can often be relevant to programmatically figure out what language the current user has selected. In this case I am running an english site, where I have changed the language for my user to german. There are several SharePoint objects one can consider to look in, for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=37&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Running with multilingual sites in SharePoint 2010, it can often be relevant to programmatically figure out what language the current user has selected. In this case I am running an english site, where I have changed the language for my user to german.</p>
<p><A href="http://sisharepoint.files.wordpress.com/2009/12/changelanguage.jpg"><IMG class="alignnone size-medium wp-image-41" title="Change language to german" height="116" alt="" src="http://sisharepoint.files.wordpress.com/2009/12/changelanguage.jpg?w=300" width="300"></A></p>
<p>There are several SharePoint objects one can consider to look in, for example SPWeb or SPUser to get the users selected language. In the picture below I have added a screenshot of a debugging session with the various relevant values I found. </p>
<p><A href="http://sisharepoint.files.wordpress.com/2009/12/localprops.jpg"><IMG class="alignnone size-medium wp-image-38" title="Debug watch for localization properties" height="115" alt="" src="http://sisharepoint.files.wordpress.com/2009/12/localprops.jpg?w=300" width="300"></A></p>
<p>In order to get the language selected by the user, you will have to access the property System.Globalization.CultureInfo.CurrentUICulture. Properties like SPContect.Current.Web.UICulture is not affected by the user selected language.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sisharepoint.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sisharepoint.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sisharepoint.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sisharepoint.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sisharepoint.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sisharepoint.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sisharepoint.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sisharepoint.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sisharepoint.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sisharepoint.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sisharepoint.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sisharepoint.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sisharepoint.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sisharepoint.wordpress.com/37/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sisharepoint.wordpress.com&amp;blog=10773117&amp;post=37&amp;subd=sisharepoint&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sisharepoint.wordpress.com/2009/12/21/getting-the-current-users-language-programmatically/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/78f1ccfe1f04daae1ba18c28c93a3161?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Oddleif</media:title>
		</media:content>
	</item>
	</channel>
</rss>
