<?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/"
	>

<channel>
	<title>Alex Angas &#187; Project Server</title>
	<atom:link href="http://alexangas.com/blog/category/project-server/feed/" rel="self" type="application/rss+xml" />
	<link>http://alexangas.com/blog</link>
	<description>SharePoint</description>
	<lastBuildDate>Fri, 06 Nov 2009 18:53:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Workspace permissions &#8211; Part 3: &quot;Workarounds and The Future&quot;</title>
		<link>http://alexangas.com/blog/2008/11/workspace-permissions-part-3-workarounds-and-the-future/</link>
		<comments>http://alexangas.com/blog/2008/11/workspace-permissions-part-3-workarounds-and-the-future/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 08:00:26 +0000</pubDate>
		<dc:creator>Alex Angas</dc:creator>
				<category><![CDATA[Project Server]]></category>
		<category><![CDATA[permissions]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[workspaces]]></category>

		<guid isPermaLink="false">http://alexangas.wordpress.com/?p=100</guid>
		<description><![CDATA[A crucial foundation of SharePoint is its powerful permissioning model. This is a series of three posts that discusses SharePoint permission assignment in a Project Server project workspace. Part 1 explained how permissions are assigned and problems with the feature’s &#8230; <a href="http://alexangas.com/blog/2008/11/workspace-permissions-part-3-workarounds-and-the-future/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>A crucial foundation of SharePoint is its powerful permissioning model. This is a series of three posts that discusses SharePoint permission assignment in a Project Server project workspace. <a href="http://alexangas.wordpress.com/2008/11/25/workspace-permissions-part-1-by-design/">Part 1</a> explained how permissions are assigned and problems with the feature’s design. <a href="http://alexangas.wordpress.com/2008/11/26/workspace-permissions-part-2-access-denied/">Part 2</a> discusses a particular bug (i.e. the feature’s implementation). Finally, Part 3 has some solutions.</em></p>
<p>We&#8217;ve looked at the problems with this feature, so what can we do about it? Well the new Project Server 2007 eventing model isn&#8217;t broken, so if you have a developer handy use that!</p>
<p>First, uncheck the Workspace Permissions box in Server Settings / Project Workspace Provisioning Settings. Then, have a look at the WssInterop event WssWorkspaceCreated. This fires whenever, um, a workspace is created. The initial state of a created workspace is with permission inheritance broken and the service account assigned to the workspace with Full Control.</p>
<p>From here, use <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.ensureuser.aspx">SPWeb.EnsureUser</a> for each user you&#8217;d like to give access to the workspace. This works by adding the user to the SPWeb if they haven&#8217;t been already. This does not give the added users any permissions to the workspace. SPWeb.EnsureUser also works with Active Directory groups, so a model where every user needs read access can be simply accomplished. Finally, use <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.roleassignments.aspx">SPWeb.RoleAssignments</a>, <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.roledefinitions.aspx">SPWeb.RoleDefinitions</a>, and <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.sproleassignment.roledefinitionbindings.aspx">SPRoleAssignment.RoleDefinitionBindings</a> to assign users the correct permissions (sorry, hopelessly glossed over but there are examples out there on how to use these).</p>
<p>Something else to note about a custom solution is that despite unchecking the Workspace Permissions box earlier on, Project Server&#8217;s behaviour does not change when giving access to the PWA site. It will still handle this for you according to the rules in <a href="http://alexangas.wordpress.com/2008/11/25/workspace-permissions-part-1-by-design/">Part 1</a>, leaving you to configure the permissions for the workspace with custom code.</p>
<p>This works fine and if you are able to make use of Active Directory groups, is fast as well. Plus now that you&#8217;ve gone custom, you have all of the freedom (and traps) of flexibility and the ability to create your own permission assignment rules. Don&#8217;t forget you&#8217;ll need to invest time in creating custom administration pages to manage those as well.</p>
<p>So what about going forward and sticking with the product for a solution? For Project Server 14 or 2009 or 2010 I have no idea if there will be any changes to the workspace permissions functionality. If you agree that this feature needs looking at, please give feedback to the <a href="http://blogs.msdn.com/project/">Project Server team</a> as they do read it and listen (I&#8217;ve had great responses from <a href="http://evildoctorporkchop.spaces.live.com/">Treb Gatte</a> and <a href="http://blogs.msdn.com/brismith/">Brian Smith</a> on other issues). Hopefully bugs will be fixed and the feature improved next release!</p>
<p>Thanks for reading and I hope this helps someone else out there with similar experiences.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexangas.com/blog/2008/11/workspace-permissions-part-3-workarounds-and-the-future/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Workspace permissions &#8211; Part 2: &quot;Access Denied&quot;</title>
		<link>http://alexangas.com/blog/2008/11/workspace-permissions-part-2-access-denied/</link>
		<comments>http://alexangas.com/blog/2008/11/workspace-permissions-part-2-access-denied/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 08:00:48 +0000</pubDate>
		<dc:creator>Alex Angas</dc:creator>
				<category><![CDATA[Project Server]]></category>
		<category><![CDATA[permissions]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[workspaces]]></category>

		<guid isPermaLink="false">http://alexangas.wordpress.com/?p=96</guid>
		<description><![CDATA[A crucial foundation of SharePoint is its powerful permissioning model. This is a series of three posts that discusses SharePoint permission assignment in a Project Server project workspace. Part 1 explained how permissions are assigned and problems with the feature’s &#8230; <a href="http://alexangas.com/blog/2008/11/workspace-permissions-part-2-access-denied/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>A crucial foundation of SharePoint is its powerful permissioning model. This is a series of three posts that discusses SharePoint permission assignment in a Project Server project workspace. <a href="http://alexangas.wordpress.com/2008/11/25/workspace-permissions-part-1-by-design/">Part 1</a> explained how permissions are assigned and problems with the feature’s design. Part 2 discusses a particular bug (i.e. the feature’s implementation). Finally, Part 3 has some solutions.<br />
</em></p>
<p>If you&#8217;ve been having some great successes out of your Project Server solution you&#8217;ll probably be building up quite a few users and workspaces. One particular customer I&#8217;m aware of has over 1000 of each. To try and get around the inflexible rules outlined in <a href="http://alexangas.wordpress.com/2008/11/25/workspace-permissions-part-1-by-design/">Part 1</a>, they&#8217;ve decided to give every user at least read access to every workspace. Unfortunately this has uncovered a particularly nasty SQL deadlock bug.</p>
<p><code>10/06/2008 15:33:59.86 Microsoft.Office.Project.Server (0x1540)   0x12C4 Windows SharePoint Services     Database                                  6f8g      Unexpected       Unexpected query execution failure, error code 1205. Additional error information from SQL Server is included below. "Transaction (Process ID 151) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction." Query text (if available): "{?=call proc_SecAddPrincipalToRole(?,?,?,?,?,?)}"<br />
</code></p>
<p>The bug happens when one or more of the following operations is occurring at a time:</p>
<ol>
<li>Creating a new workspace by publishing a project (queue job &#8220;WSS Workspace Create&#8221;)</li>
<li>Resynchronising workspace permissions from Server Settings / Project Workspaces (queue job &#8220;WSS Workspace Membership Synchronisation&#8221;)</li>
<li>Changing a user&#8217;s Project Server groups which results in changes to SharePoint permissions (queue job &#8220;User Synchronization for Project Web Access App Root Site and Project WSS Workspaces&#8221;)</li>
</ol>
<p>When the bug hits, permissions are only partially assigned so as this happens again and again, a user&#8217;s consistency of access disappears. The only solution is to try and resynchronise the workspace with fingers crossed that it succeeds without another SQL deadlock. But you&#8217;re completely out of luck when running a batch job that affects several workspaces such as number 3 above. The workspace it reached before everything went horribly wrong doesn&#8217;t appear to be logged!</p>
<p>Because of the SQL deadlock failures, the <a href="http://msdn.microsoft.com/en-us/library/websvcwssinterop.wssinterop.synchronizemembershipforpwaapprootsite.aspx">SynchronizeMembershipForPwaAppRootSite()</a> method in the <a href="http://msdn.microsoft.com/en-us/library/websvcwssinterop.wssinterop_methods.aspx">WssInterop</a> web service has been looked at. This performs a complete resynchronisation across all workspaces, functionality that is not available through the UI. Unfortunately with testing in UAT (less powerful than production but still a three server farm), this operation was going to run for days. Also, no other sync jobs could occur at the same time or else it would be SQL deadlock again!</p>
<p>Bugs are the worst, but implementation is also a shocker because of the huge length of time these jobs take to run. For example, up to 7 minutes for numbers 1 or 2 above, and 15-45 minutes for number 3 depending on number of users with changed permissions. This is exacerbated as more workspaces are created (the problem seems to be more related to number of workspaces rather than number of users). The server environment where this issue is occurring is very powerful and speed should not be an issue.</p>
<p>We&#8217;ve seen from <a href="http://alexangas.wordpress.com/2008/11/25/workspace-permissions-part-1-by-design/">Part 1</a> the deficiencies in design of this feature, but now also it&#8217;s implementation. So things can only get better in Part 3, coming next!</p>
]]></content:encoded>
			<wfw:commentRss>http://alexangas.com/blog/2008/11/workspace-permissions-part-2-access-denied/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Workspace permissions &#8211; Part 1: &quot;By Design&quot;</title>
		<link>http://alexangas.com/blog/2008/11/workspace-permissions-part-1-by-design/</link>
		<comments>http://alexangas.com/blog/2008/11/workspace-permissions-part-1-by-design/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 08:00:37 +0000</pubDate>
		<dc:creator>Alex Angas</dc:creator>
				<category><![CDATA[Project Server]]></category>
		<category><![CDATA[permissions]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[workspaces]]></category>

		<guid isPermaLink="false">http://alexangas.wordpress.com/?p=86</guid>
		<description><![CDATA[A crucial foundation of SharePoint is its powerful permissioning model. This is a series of three posts that discusses SharePoint permission assignment in a Project Server project workspace. Part 1 explains how permissions are assigned and problems with the feature&#8217;s &#8230; <a href="http://alexangas.com/blog/2008/11/workspace-permissions-part-1-by-design/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>A crucial foundation of SharePoint is its powerful permissioning model. This is a series of three posts that discusses SharePoint permission assignment in a Project Server project workspace. Part 1 explains how permissions are assigned and problems with the feature&#8217;s design. Part 2 discusses a particular bug (i.e. the feature&#8217;s implementation). Finally, Part 3 has some solutions.</em></p>
<p>Project Server has its own SharePoint security groups which almost precisely equate to the standard SharePoint groups of Read, Contribute, Design and Full Control. The TechNet article <a href="http://technet.microsoft.com/en-us/library/cc197668.aspx">Coordinate Project Server and Windows SharePoint Services security</a> is the official word for exactly how permissions are assigned. Essentially just as SharePoint has its own built-in list of groups for &#8220;Read&#8221;, &#8220;Contribute&#8221;, &#8220;Design&#8221; and &#8220;Full Control&#8221;, then Project Server comes to the party with &#8220;Readers (Microsoft Office Project Server)&#8221;, &#8220;Team members (Microsoft Office Project Server)&#8221;, &#8220;Project Managers (Microsoft Office Project Server)&#8221; and &#8220;Web Administrators (Microsoft Office Project Server)&#8221;&#8230; blurrgh!</p>
<p>Here is a simplified summary of the rules that explain how users get their permissions. This is without the &#8220;(Microsoft Office Project Server)&#8221; suffix but with standard SharePoint group names in brackets:</p>
<ul>
<li>User that publishes the project has Project Manager (Design) permissions</li>
<li>Users assigned to tasks within the project have Team Member (Contribute) permissions</li>
<li>Users on the Resource Sheet of a project have Reader (Read) permissions</li>
<li>Users that have Manage Windows SharePoint Services permission have Web Administrator (Full Control) permission over all workspaces</li>
<li>Users that have Save Project permission have Project Manager (Design) permission over all workspaces</li>
</ul>
<p>This looks complicated and it is. Try explaining to a project manager that access to documents in their workspace depends on who is added to the project&#8217;s Resource Sheet. It just doesn&#8217;t make sense! Then try explaining to an administrator why there is a group called &#8220;Readers (Microsoft Office Project Server)&#8221; as well as the standard SharePoint group called &#8220;Read&#8221;. It just doesn&#8217;t make sense!!</p>
<p>Then there&#8217;s the inflexibility of the rules themselves. There are no options &#8211; they are either on or off. And if you don&#8217;t go with MS on this one folks and uncheck the box for Workspace Permissions in Server Settings / Project Workspace Provisioning Settings, then only the Project Server service account is given access to new workspaces! This is hardly useful to the humble user needing to assign permissions who will never get their hands on <em>this</em> particular username and password. It just doesn&#8217;t make sense!</p>
<p>Don&#8217;t worry, there are solutions. However, they don&#8217;t come until Part 3! Next we look at how Microsoft&#8217;s solution is also slow, and even worse, buggy.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexangas.com/blog/2008/11/workspace-permissions-part-1-by-design/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Programmatically retrieving the name of an SSP</title>
		<link>http://alexangas.com/blog/2008/10/programmatically-retrieving-the-name-of-an-ssp/</link>
		<comments>http://alexangas.com/blog/2008/10/programmatically-retrieving-the-name-of-an-ssp/#comments</comments>
		<pubDate>Tue, 14 Oct 2008 14:51:37 +0000</pubDate>
		<dc:creator>Alex Angas</dc:creator>
				<category><![CDATA[Project Server]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[PSI]]></category>
		<category><![CDATA[SSP]]></category>

		<guid isPermaLink="false">http://alexangas.wordpress.com/?p=79</guid>
		<description><![CDATA[This was asked on the new Stack Overflow programming questions site recently (which you should really check out and start using if you don&#8217;t already!). Getting the SSP name is something that I&#8217;ve needed to do to build the SSP &#8230; <a href="http://alexangas.com/blog/2008/10/programmatically-retrieving-the-name-of-an-ssp/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This <a href="http://stackoverflow.com/questions/58809/retrieving-the-associated-shared-service-providers-name">was asked</a> on the new Stack Overflow programming questions site recently (which you should really check out and start using if you don&#8217;t already!). Getting the SSP name is something that I&#8217;ve needed to do to build the SSP URL for <a href="http://msdn.microsoft.com/en-us/library/aa974413.aspx">impersonating access to the Project Server PSI</a>. I used to think that the URL had to live in a config file. Then after some digging into Project Server&#8217;s behaviour with the help of <a href="http://www.red-gate.com/products/reflector/">Reflector</a>, I discovered Microsoft use the SharedResourceProvider class in the Microsoft.Office.Server.Administration namespace. Who knows why, but this class is marked internal so reflection is required to access it, and therefore accessing it is not supported. We should be on relatively safe ground if MS products such as Project Server use it however&#8230;</p>
<p>The following code retrieves the name of the SSP for the current site collection.</p>
<pre class="brush: csharp;">
SPSite site = SPContext.Current.Site;
ServerContext serverContext = ServerContext.GetContext(site);

PropertyInfo srpProp = serverContext.GetType().GetProperty(
	&quot;SharedResourceProvider&quot;,
	BindingFlags.NonPublic | BindingFlags.Instance);
object sharedResourceProvider = srpProp.GetValue(serverContext, null);
PropertyInfo srpName = sharedResourceProvider.GetType().GetProperty(
	&quot;Name&quot;,
	BindingFlags.Public | BindingFlags.Instance);

string sspName = (string)srpName.GetValue(sharedResourceProvider, null);
</pre>
<p>From there the URL to the PSI web services within the SSP directly becomes the following (and the port number is always the following on every server):<br />
http://<em>servername</em>:56737/<em>SSPName</em>/PSI/ or</p>
<p>https://<em>servername</em>:56738/<em>SSPName</em>/PSI/</p>
<p>This does seem overly complex so if someone out there has a better solution please add it as a comment to this blog or update the <a href="http://stackoverflow.com/questions/58809/retrieving-the-associated-shared-service-providers-name">answer on Stack Overflow</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexangas.com/blog/2008/10/programmatically-retrieving-the-name-of-an-ssp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL querying the queue</title>
		<link>http://alexangas.com/blog/2008/09/sql-querying-the-queue/</link>
		<comments>http://alexangas.com/blog/2008/09/sql-querying-the-queue/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 09:21:49 +0000</pubDate>
		<dc:creator>Alex Angas</dc:creator>
				<category><![CDATA[Project Server]]></category>
		<category><![CDATA[queue]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://alexangas.wordpress.com/?p=77</guid>
		<description><![CDATA[I recently found myself in the situation where the Project Server queue service was taking up almost all of a server&#8217;s CPU. Unfortunately due to the high demands of the queue jobs, the administration page was unavailable with a connection &#8230; <a href="http://alexangas.com/blog/2008/09/sql-querying-the-queue/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I recently found myself in the situation where the Project Server queue service was taking up almost all of a server&#8217;s CPU. Unfortunately due to the high demands of the queue jobs, the administration page was unavailable with a connection timeout error.</p>
<p>One way to try and access the administration page again might have been to stop or restart the queue service or the entire server itself, but what if unpredictable behaviour had disrupted those jobs? Instead, by carefully looking at the Project Server databases we can see the draft project database stores a lot of information about the queue in tables and views starting with MSP_QUEUE.</p>
<p>The following query gives a summary of jobs in the queue:</p>
<pre class="brush: sql;">
SELECT
  QPG.GRP_QUEUE_ID,
  QPG.CREATED_DATE,
  QPG.READY_FOR_PROCESSING_DATE,
  QPM.MSG_QUEUE_BODY_TYPE,
  QPG.GRP_QUEUE_MESSAGE_TYPE,
  QPG.GRP_QUEUE_STATE,
  QPG.PROCESSING_DATE,
  QPG.PERCENT_COMPLETE,
  QPG.COMPLETED_DATE,
  QPG.GRP_QUEUE_ERROR_INFO,
  QPG.GRP_QUEUE_PRIORITY,
  QPG.LAST_MSG_ID,
  QPG.LAST_ADMIN_ACTION
FROM dbo.MSP_QUEUE_PROJECT_GROUP_FULL_VIEW QPG (NOLOCK)
INNER JOIN dbo.MSP_QUEUE_PROJECT_MESSAGE QPM (NOLOCK)
  ON QPM.GRP_UID = QPG.GRP_UID
ORDER BY GRP_QUEUE_STATE DESC, GRP_QUEUE_PRIORITY, QPG.GRP_QUEUE_ID
</pre>
<p>This query gives how many jobs are remaining to run:</p>
<pre class="brush: sql;">
SELECT COUNT(*)
FROM dbo.MSP_QUEUE_PROJECT_GROUP_FULL_VIEW QPG (NOLOCK)
WHERE QPG.PROCESSING_DATE IS NULL
</pre>
<p>This query gives how many jobs of each priority are remaining to run:</p>
<pre class="brush: sql;">
SELECT QPG.GRP_QUEUE_PRIORITY, COUNT(*) AS [COUNT]
FROM dbo.MSP_QUEUE_PROJECT_GROUP_FULL_VIEW QPG (NOLOCK)
WHERE QPG.PROCESSING_DATE IS NULL
GROUP BY QPG.GRP_QUEUE_PRIORITY
</pre>
<p>There are also an interesting statistics table, although I haven&#8217;t yet found how to get a text value for GRP_QUEUE_MESSAGE_TYPE:</p>
<pre class="brush: sql;">
SELECT QPS.*
FROM dbo.MSP_QUEUE_PROJECT_STATS QPS (NOLOCK)
</pre>
<p>Ideally you would never want to execute raw SQL statements against the database, but as with any computer system, unpredictable things can happen. These queries might help with some troubleshooting.</p>
]]></content:encoded>
			<wfw:commentRss>http://alexangas.com/blog/2008/09/sql-querying-the-queue/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linking tasks to issues, risks, documents, and more&#8230;</title>
		<link>http://alexangas.com/blog/2008/09/linking-tasks-to-issues-risks-documents-and-more/</link>
		<comments>http://alexangas.com/blog/2008/09/linking-tasks-to-issues-risks-documents-and-more/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 14:14:55 +0000</pubDate>
		<dc:creator>Alex Angas</dc:creator>
				<category><![CDATA[Project Server]]></category>
		<category><![CDATA[feature]]></category>

		<guid isPermaLink="false">http://alexangas.wordpress.com/?p=43</guid>
		<description><![CDATA[In Project Server 2003 a feature was introduced to link issues, risks and documents to tasks. It&#8217;s been carried over to 2007 as well (although the UI for it isn&#8217;t as noticeable) and I think it&#8217;s one of the coolest &#8230; <a href="http://alexangas.com/blog/2008/09/linking-tasks-to-issues-risks-documents-and-more/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In Project Server 2003 a feature was introduced to link issues, risks and documents to tasks. It&#8217;s been carried over to 2007 as well (although the UI for it isn&#8217;t as noticeable) and I think it&#8217;s one of the coolest yet underrated features in the web interface. Let me take you through it&#8230; (Note: you will need the Create Object Link category permission to use this feature.)</p>
<p>Every project workspace out of the box comes with the Project Documents, Risks and Issues lists. On the add and edit pages of these lists, you can find &#8220;Link Items&#8221;:<br />
<img src="http://alexangas.files.wordpress.com/2008/09/link-items-link.png" alt="" title="Link Items link" width="456" height="65" class="aligncenter size-full wp-image-44" /></p>
<p>Clicking Link Items while creating or editing an issue, for example, allows the issue to be linked to any task in the project. Also, this linking can have several meanings, such as whether the issue simply relates to the task, affects the task, or whether the task resolves the issue. Here is the dialog:<br />
<img src="http://alexangas.files.wordpress.com/2008/09/link-task-to-issue.png" alt="" title="Link an issue to tasks" width="550" height="392" class="aligncenter size-full wp-image-46" /></p>
<p>You&#8217;ll notice the drop-down at the top that reads Project Tasks. This can be changed so that this issue is linked to any risk, document or other issue as well! (Note there is no additional &#8216;meaning&#8217; unless linking to a task.)</p>
<p>Upon clicking OK on this dialog box, a nice little summary is displayed of the link options chosen:<br />
<img src="http://alexangas.files.wordpress.com/2008/09/link-task-to-issue-summary.png" alt="" title="Link issue summary" width="445" height="316" class="aligncenter size-full wp-image-47" /></p>
<p>Of course, the issues list is just an example here. It is also possible to link items from the other lists previously mentioned. Here are the other dialog boxes shown&#8230;</p>
<p>Risk:<br />
<img src="http://alexangas.files.wordpress.com/2008/09/link-task-to-risk.png" alt="" title="Link risk to tasks" width="550" height="392" class="aligncenter size-full wp-image-48" /></p>
<p>Document:<br />
<img src="http://alexangas.files.wordpress.com/2008/09/link-task-to-document.png" alt="" title="Link document to task" width="550" height="392" class="aligncenter size-full wp-image-49" /></p>
<p><em>Linking&#8217;s cool, but now what?</em></p>
<p>Obviously whenever you look at a linked object you will be able to see and click on what each object is linked to which helps to describe the relations within your project, not to mention handy as well. Some examples are linking a document to a task for its delivery, or linking a risk item to a risky task! Also very useful is that the link gets propagated to the reporting database when the workspace&#8217;s project is next published, so some neat queries can be written to relate your data together.</p>
<p>What&#8217;s even better is what you don&#8217;t see. This functionality is powered by the Object Link Provider, which is described in some detail within the <a href="http://msdn.microsoft.com/en-us/library/aa568840.aspx">Project 2007 SDK</a>. With some custom development work, it is possible to link tasks or project workspace items in other lists to any object you can reach with a URL. Imagine the possibilities &#8211; linking to an item in the company&#8217;s financial system, for example! This can all be done with the ObjectLinkProvider web service (examine the SDK for more details).</p>
<p><em>A few cautionary words</em></p>
<p>As you may have already encountered, some functionality in Project Server can break when you start altering project workspaces. This is even though it does nothing to stop you and virtually every customer/user has a requirement to. The Link Items feature is no exception here. If you delete the Links column from a workspace, there is no way I&#8217;ve found to put it back (this is probably because it is not a built-in SharePoint field type). Instead, try setting it to Hidden within the content type! In fact, hiding the field in the list&#8217;s content type should be done for every workspace field you don&#8217;t want to use.</p>
<p><em>Thanks for reading</em></p>
<p>Hopefully this provides a deeper look at a feature that doesn&#8217;t seem to get mentioned much. If you have good uses for &#8220;Link Items&#8221;, please add a few comments to this post!</p>
]]></content:encoded>
			<wfw:commentRss>http://alexangas.com/blog/2008/09/linking-tasks-to-issues-risks-documents-and-more/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>SharePoint and SQL schemas</title>
		<link>http://alexangas.com/blog/2008/09/sharepoint-and-sql-schemas/</link>
		<comments>http://alexangas.com/blog/2008/09/sharepoint-and-sql-schemas/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 15:57:17 +0000</pubDate>
		<dc:creator>Alex Angas</dc:creator>
				<category><![CDATA[Project Server]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[update]]></category>

		<guid isPermaLink="false">http://alexangas.wordpress.com/?p=41</guid>
		<description><![CDATA[I&#8217;m just under two weeks away from installing the infrastructure update to a production environment. But of course these things need testing first so I started the install on the development environment. Thing&#8217;s went hairy for a while&#8230; First I &#8230; <a href="http://alexangas.com/blog/2008/09/sharepoint-and-sql-schemas/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m just under two weeks away from installing the infrastructure update to a production environment. But of course these things need testing first so I started the install on the development environment. Thing&#8217;s went hairy for a while&#8230;</p>
<p>First I must admit I&#8217;m not running the update as the service account, <a href="http://technet.microsoft.com/en-us/library/cc671413.aspx">recommended by Microsoft</a>. This is because I&#8217;m working in a locked down environment where trying to get the permission to do this requires a lot of questions, moaning and red tape. However both my account and the service account (there&#8217;s only one service account in use here) are local administrators.</p>
<p>The log file pointed to by the SharePoint Configuration Wizard contains this ever so helpful line: &#8220;An exception of type Microsoft.SharePoint.PostSetupConfiguration.PostSetupConfigurationTaskException was thrown.  Additional exception information: Failed to upgrade SharePoint Products and Technologies.&#8221; However, with a little more digging there are details located at C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\LOGS. (This isn&#8217;t actually the folder where I have directed diagnostic logs to, but for the purposes of an upgrade it seems SharePoint sometimes redirects it!) The logs contain errors over the several times I tried to upgrade&#8230;</p>
<p>Upgrade.log:</p>
<ul>
<li>SqlException: The default schema does not exist.</li>
<li>SqlException: Cannot find the object &#8216;MFN_Epm_GetAllCustomFieldsInformation&#8217;, because it does not exist or you do not have permission.</li>
<li>SqlException: Cannot drop the function &#8216;dbo.MFN_Epm_GetAllCustomFieldsInformation&#8217;, because it does not exist or you do not have permission.</li>
</ul>
<p>Then in the ULS logs:</p>
<ul>
<li>The schema version (3.1.4.0) of the database SharePoint_AdminContent on server_x is not consistent with the expected database schema version (3.1.5.0) on server_x.  Connections to this database from this server have been blocked to avoid data loss.  Upgrade the web front end or the content database to ensure that these versions match.</li>
<li>SqlException: Cannot find the user &#8216;DOMAIN\myusername&#8217;, because it does not exist or you do not have permission.</li>
<li>Queue unable to interact with SQL. Queue type (Project Queue, Timesheet Queue etc): ProjectQ Exception: Microsoft.Office.Project.Server.BusinessLayer.Queue.QueueSqlException: PeriodicTasks failed &#8212;&gt; System.Data.SqlClient.SqlException: Invalid object name &#8216;MSP_QUEUE_RENDEZVOUS&#8217;.</li>
</ul>
<p>It appears that I don&#8217;t have permission to the databases. However, my account is db_owner on every database The service account permissions haven&#8217;t been changed. What&#8217;s going on?!! It turns out the root of the cause was described this exception: <strong>The default schema does not exist</strong>.</p>
<p>I don&#8217;t know a great deal about the schema feature introduced with SQL 2005, however with every user added to a SQL 2005 box, an accompanying schema with the same name is also created. A colleague of mine who was doing some spring cleaning on our databases removed the schema for our service account, however the service account&#8217;s SQL user was still trying to use it as its default schema! The solution was to change the schema to <strong>dbo</strong>.</p>
<p>Unfortunately the upgrade still didn&#8217;t quite complete since I was part of the way through the upgrade when it fell over&#8230; I also had to create a fake MFN_Epm_GetAllCustomFieldsInformation function in the Reporting database so the upgrade could find and drop it (fortunately replaced with the new version in the upgrade).</p>
<p>It was a big relief that this ended up working. The downside is that my user account and a schema for it have been created on the database server. It can&#8217;t be removed right now because the new database objects that come with the update have my schema set as their owner! Now I have to change them all&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://alexangas.com/blog/2008/09/sharepoint-and-sql-schemas/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Project Server ItemSwapper control</title>
		<link>http://alexangas.com/blog/2008/07/project-server-itemswapper-control/</link>
		<comments>http://alexangas.com/blog/2008/07/project-server-itemswapper-control/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 19:00:22 +0000</pubDate>
		<dc:creator>Alex Angas</dc:creator>
				<category><![CDATA[Project Server]]></category>
		<category><![CDATA[control]]></category>
		<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://alexangas.wordpress.com/?p=24</guid>
		<description><![CDATA[ItemSwapper hasn&#8217;t been documented by Microsoft so its behaviour may change between service packs &#8211; use at your own risk! With the 2007 version, Project Server is now a SharePoint application. One of the best things about this is the &#8230; <a href="http://alexangas.com/blog/2008/07/project-server-itemswapper-control/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>ItemSwapper hasn&#8217;t been documented by Microsoft so its behaviour may change between service packs &#8211; use at your own risk!</em></p>
<p>With the 2007 version, Project Server is now a SharePoint application. One of the best things about this is the nifty stuff you get out of the box as part of SP. Custom controls are a highlight, of which there are many that can be used in your custom Project Server solutions. Even better is that Project Server 2007 comes with some cool controls of its own which you can use in any solution running within Project Server. My latest discovery is the handy <strong>ItemSwapper</strong>.</p>
<div id="attachment_29" class="wp-caption aligncenter" style="width: 520px"><a href="http://alexangas.files.wordpress.com/2008/07/itemswapper-intro.png"><img src="http://alexangas.files.wordpress.com/2008/07/itemswapper-intro.png" alt="ItemSwapper" width="510" height="148" class="size-full wp-image-29" /></a><p class="wp-caption-text">ItemSwapper</p></div>
<p>This might look familiar to you from popular administration pages such as &#8220;Manage Queue&#8221; or &#8220;Manage Groups&#8221;. Just by popping one of these on your page, you get a pretty flawless interface to selecting projects. It&#8217;s also speedy and has some great features both client and server side. It&#8217;s great to use in a web part used for selecting report parameters, so that&#8217;s what we&#8217;re going to build in this post!</p>
<p>First of all, let&#8217;s have a look at two other custom controls used by ItemSwapper. There is the ItemSwapperLabel (extended from System.Web.UI.WebControls.Label) which renders the text above each list, and ItemSwapperSelect (extended from System.Web.UI.HtmlControls.HtmlSelect) which renders the list itself. Data binding is done with ItemSwapperSelect and the &#8216;parent&#8217; ItemSwapper control renders all of these controls for you.</p>
<p>The ItemSwapper control refers to the two select lists as the &#8216;alpha&#8217; and &#8216;beta&#8217; lists (originally designed for Greek Project Server?). In our example the beta list will be blank for us to add projects into, so we only want to initalise the alpha list. Looking at the code, our CreateChildControls method contains:</p>
<pre class="brush: csharp;">protected override void CreateChildControls()
{
    alphaSelect = new ItemSwapperSelect();
    alphaSelect.Multiple = true;

    projectSwapper = new ItemSwapper();
    projectSwapper.ID = &quot;projectSwapper&quot;;
    projectSwapper.TrackBetaListChanges = true;
    projectSwapper.AlphaSelect = alphaSelect;
    projectSwapper.LblAlphaList.Text = &quot;Available Projects&quot;;
    projectSwapper.LblBetaList.Text = &quot;Selected Projects&quot;;
    projectSwapper.DisplaySelectedItemText = false;
    projectSwapper.ShowBetaUpDownButtons = true;
    projectSwapper.ShowRestoreAllButton = true;
    projectSwapper.ShowRemoveAllButton = true;
    this.Controls.Add(projectSwapper);
}</pre>
<p>This should be pretty self-explanatory (we will discuss the ID and TrackBetaListChanges properties later in this post). Now let&#8217;s perform a data bind in our OnLoad method:</p>
<pre class="brush: csharp;">protected override void OnLoad(EventArgs e)
{
    if (!Page.IsPostBack)
    {
        DataTable projects = DataLayer.GetProjects();
        projectSwapper.DataSource = projects;
        projectSwapper.DataTextField = &quot;Name&quot;;
        projectSwapper.DataValueField = &quot;Uid&quot;;
    }
}</pre>
<p>This will now render fine, but the finishing touch is a workaround to what I would call a bug. If you set ShowRestoreAllButton to true, this will display the &#8220;Add All&#8221; button. However it is important to know that this button is greyed out unless the user has selected an item first, meaning that will need two clicks to add all projects to the other list. I don&#8217;t know why Microsoft would have done this, but to get around it, add the following code to our OnPreRender method:</p>
<pre class="brush: csharp;">protected override void OnPreRender(EventArgs e)
{
    alphaSelect.SelectedIndex = 0;
}</pre>
<p>Have a look at the work so far as the ItemSwapper should now render!</p>
<p>Now let&#8217;s make use of the items chosen in the lists. First of all we&#8217;ll need a button in our web part for users to click on and start the report generation. We&#8217;ll also need at least one hidden field that will contain the selected items for us to use on the server side. Note that there is quite a bit of data we can get from the ItemSwapper JavaScript object, such as a count of items for both lists, text labels of chosen items for both lists, and values (e.g. project GUIDs) of chosen items for both lists!</p>
<p>To be able to do retrieve the data on the client side there are two key properties we need to set when creating the ItemSwapper which I touched upon earlier: ID and TrackBetaListChanges (or if you care about the alpha list, TrackAlphaListChanges). We need to use JavaScript to get a reference to the ItemSwapper object and setting ID lets us use document.getElementByID() to do this. (Surprisingly and fortunately, ID doesn&#8217;t get mangled in usual SharePoint fashion when rendered.) Setting TrackBetaListChanges sets a property on the JavaScript object to, well, track beta list changes.</p>
<p>So going back to CreateChildControls(), let&#8217;s add the following code and connect our server code to the client:</p>
<pre class="brush: csharp;">chosenProjectValues = new HiddenField();
this.Controls.Add(chosenProjectValues);

createButton = new Button();
createButton.Text = &quot;Create&quot;;
createButton.Click += CreateButton_Click;  // server-side processing done in this method
createButton.OnClientClick = String.Format(&quot;SaveItemSwapperValues('{0}', '{1}');&quot;, projectSwapper.ID, chosenProjectValues.ClientID);
this.Controls.Add(createButton);</pre>
<p>Everything&#8217;s ready now on the server side. We just need to create the SaveItemSwapperValues JavaScript function. Put this JavaScript wherever is standard for your projects.</p>
<pre class="brush: jscript;">function SaveItemSwapperValues(itemSwapperClientID, chosenValuesClientID)
{
    var chosenValuesField = document.getElementById(chosenValuesClientID);
    var itemSwapper = document.getElementById(itemSwapperClientID);
    chosenValuesField.value = itemSwapper.GetBetaListValuesAsString();
}</pre>
<p>That&#8217;s it! Now when your server-code hits CreateButton_Click(), you should find a nice comma-separated list of project GUIDs in the Value property of your hidden field that can be used to generate reports!</p>
<p>But it&#8217;s nice to take things a bit further&#8230; Our Create button is always active, even when no projects are in the chosen list. Well then, behold! The ItemSwapper contains JavaScript event handling functionality! Add script that runs on startup such as this:</p>
<pre class="brush: jscript;">var itemSwapper = document.getElementById('projectSwapper'); // 'projectSwapper' should be passed as a parameter and not hard-coded
itemSwapper.OnAlphaListChange = ChosenProjectsChanged;
itemSwapper.OnBetaListChange = ChosenProjectsChanged;</pre>
<p>Then add the following with the SaveItemSwapperValues function:</p>
<pre class="brush: jscript;">function ChosenProjectsChanged()
{
    var itemSwapper = document.getElementById('projectSwapper');
    var createButton = /* how you get this reference depends on your environment */
    if (itemSwapper.betaListItemCount == 0)
    {
        createButton.disabled = true;
    }
    else
    {
        createButton.disabled = false;
    }
}</pre>
<p>Now we&#8217;re talkin&#8217; &#8211; a smart ItemSwapper. And that&#8217;s not all, there is heaps of handy JavaScript goodness you can hook on to if you&#8217;re able to navigate to this file and have a look: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\PWA\LIBRARY\ItemSwapper.htc.</p>
<p>Last but not least, none of the ItemSwapper controls are sealed so you are free to extend them with your own functionality!</p>
]]></content:encoded>
			<wfw:commentRss>http://alexangas.com/blog/2008/07/project-server-itemswapper-control/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
