This post started with a pretty innocuous email that I thought had an innocuous answer too. But you know if I’m writing about it here, it got a little challenging.
The question of the day is what is a Project Server User? A Project Server user is a resource that has rights to login to Project Server… right? Not quite, you can be a user, but not a resource. If I’m coming up to Project Server for the first time what can the administrator do for me in the system?
Assigned to tasks
Can login in the Project Server, but get no assignments.
Resource & User
I can enter my own time for assignments directly in PWA
Setting up a person to interact with Project Server 2007 is pretty straightforward in the user interface. This shows you were to go for creating the different interactions:
Project Center->New Resource
Uncheck “Resource Can Login to Project Server”
Server Settings->Manage Users -> New User
Uncheck “User Can be assigned as Resource”
Project Center->New Resource ()
Be sure to fill in the User Authentication Area
That’s is all fine, but this is a development Blog, not a How-to on the UI J. Resource creation is intuitive and comes quickly, so let’s start there.
First you need a web reference to the Resource Web Service:
Adding a Resource consists of:
· Creating a ResourceDataSet
o Don’t forget to create a ResourceRow that is added back to the ResourceDataSet
· Filling the ResourceDataSet
o What columns are important here? RES_UID, RES_NAME, RES_TYPE
o If this is a people resource the RES_TYPE would be WorkResource, find all the resource types in the Project Server Library assembly.
· Calling the Resource Web Service method CreateResources
Here is the code sample for the above workflow:
resDs = new ResourceWS.ResourceDataSet();
ResourceWS.ResourceDataSet.ResourcesRow resourceRow =
Guid NewResGuid = Guid.NewGuid();
resourceRow.RES_UID = NewResGuid;
resourceRow.RES_NAME = Name;
resourceRow.RES_INITIALS = Name.Substring(0, 1) +
(Name.IndexOf(" ") > 0 ?
Name.Substring(Name.IndexOf(" ") + 1, 1) : "");
resourceRow.RES_TYPE = (int)PSLibrary.Resource.Type.WorkResource;
resourceRow.RES_GROUP = "Team Members";
resourceRow.WRES_EMAIL = “firstname.lastname@example.org”;
ResSvc.CreateResources(resDs, false, true);
I’ve got a resource, now we’ll upgrade them to be a user too. I’ll be honest that I’ve created 100s of resources for demo purposes, but really never considered how to make them users.
My first try I saw the columns RES_IS_WINDOWS_USER and WRES_ACCOUNT , I figured set them and the resource would now be a user too. Wrong, they had no effect… in fact they were completely ignored, no error, no exception. I discovered later those columns are read-only much like the notes field I discussed in an earlier post.
From working with some of the other Project custom DataSets I knew that there are “sub” DataSets (tables) that sometime need to be set. I started looking through there (Rates, Abilities, CustomFields, etc.) with nothing really jumping out.
Next I went back to the API. First looking at the Resource Web Service I see ReadUserList and GetCurrentUserID, both look related this may be promising. But that’s it… no UpgradeToUser, MakeResourceUser, nada, nothing, zero. Well there are other web services too. How about the Admin web service, that could make sense, nope.
At this point I got to tell you I’m pretty disappointed that I cannot find a solution. So I trek down the hall to find someone from the product team to fix my pain. I encounter three guys that know a ton about the API in the hall heading out the door. I ask my question, in almost unison they say you have to set the authorization, chuckle, and take off. I get the feeling they’ve heard this question before and know it wasn’t a readily available answer.
Back to the DataSet, I see a ResourceAuthorizationDataSet, but there is no relationship to ResrouceDataSet that I see. Then I notice in the API SetResourceAthorization. From that point the heavens opened and the angles sung… and I had a code sample to share with you:
private void AddAuthorization(Guid resourceUid, string Account, bool WindowsUser)
ResourceWS.ResourceAuthorizationDataSet resourceAuthDs =
ResourceWS.ResourceAuthorizationDataSet.ResourcesRow resourceAuthRow =
resourceAuthRow.RES_UID = resourceUid;
resourceAuthRow.RES_IS_WINDOWS_USER = WindowsUser;
resourceAuthRow.WRES_ACCOUNT = Account;
Pairing up creating the resource with adding the authorization… you have a resource that can login.
How about a pure user? I’m happy to report that is pretty simple. Use the same code for resource create and authorization addition, but set the RES_TYPE to PSLibrary.Resource.Type.PureUser.
Attached is a sample that does everything described above. Just change the name of the server to match yours and you’re ready to go.