Cascade Skyline - with Microsoft Logo and Project Support header - author Brian Smith

August, 2010

  • Brian Smith's Microsoft Project Support Blog

    Project Server: Resource Plans and the PSI

    • 11 Comments

    I was doing some investigations this week on the Resource Plans Web Service and want to share this as it probably gives more information than we have in the SDK currently – or at least pulls it together.  The example I will be working towards is adding a resource to a resource plan, along with an assignment within that resource plan.  My work was specifically with 2007, but as far as the dataset manipulation is concerned this applies equally to Project Server 2010.

    But first a quick look round the resource plan dataset and explaining how this maps to the UI.  The SDK article for 2007 is here and for 2010 is here – but to be honest you will be hard pressed to find much difference.

    The dataset has four data tables, Utilization, Dates, PlanAssignmentCustomFields and PlanResources.

    Utilization – This table shows the utilization type and date – which relate to the UI in this screenshots – 2007 and 2010. The types are as listed 0, 1 and 2 – with the date only applicable for type 2 (plan until:

    image           image

    From the SDK: The ResourcePlan.UtilizationType type is used in the RESPLAN_UTILIZATION_TYPE column of the ResourcePlanDataSet Utilization table. Values and descriptions for the ResourcePlan.UtilizationType type are provided solely for interpreting the information in this table.

    This is not intended to be used directly from your code.

    Dates – This table shows the start and end dates of the intervals defined for the Resource Plan.  The overall range will be set by the start and end dates entered when reading the dataset, and it will be broken into intervals according to the TimeScale specified.  The TimeScaleClass enumeration can be used when reading the dataset.  3 = Days, 4 = weeks, 5 = months and 7 = years – or (short)PSLibrary.TimeScaleClass.TimeScale.Months. 

    PlanAssignmentCustomFields – You can have custom fields set for the resource’s assignments in a resource plan!  Who knew?  I’m guessing not many people have seen the following screen.  This is from 2007, but almost identical to the 2010 equivalent.  This is also the place you can change the resource from Committed to Proposed – or vice versa.

    image

    I’ve not played around with these via the PSI – but this is the table you would work with, and as is usual with Custom Fields, you need to add a row then set the properties.

    PlanResource – This table is the one that I will be working with in my sample code where we will be adding a resource.  When you read a Resource Plan you will see it contains a ton of information on the resource, most of which you do not need to enter when adding one, along with a flag for Committed or Proposed (ASSN_BOOKING_TYPE) and a set of fields Interval0 to Interval’n’ which relates to the ‘n’ intervals you will see in the dates table.  When adding a resource you can also add an assignment by putting some value in one or more of these intervals.  The parameters for getting the resource plan dataset using ReadResourcePlan are:

    filter - XML filter to limit data returned. For more information, see How to: Use a Filter Parameter with PSI Methods. I am not using filters, and as you can specify the project GUID there probably aren’t many circumstances when you’d need to filter down – unless you have a really large number of resources assigned.
    projectUid - Project GUID.
    startDate - Start date. This is the start date of the data you want to pull down from the server and manipulate – so it is potentially just a window on the entire resource plan, and need not relate to the date settings within the UI
    endDate - End date.
    timeScale - Time scale specified by the TimeScaleClass.TimeScale enumeration. Explained above – controls the time intervals
    timephasedFTE - If true, return the full time equivalent resources.  This will govern if you enter FTEs, or, if false, then time (in 1/10th of a minutes) for the work values.
    autoCheckOut - If true, check out the resource plan for editing.  This will depend exactly what you are doing.  You might want to check out just before the update, and you would also want to check that it wasn’t already checked out too.

    A similar set of parameters also apply to the QueueUpdateResourcePlan method:

    projectUid - Project GUID.
    rpds - ResourcePlanDataSet that specifies changes in the specified resource plan.  Basically a manipulated version of the one you read in.  Don’t AcceptChanges!
    timephasedFTE - If true, update with timephased full time equivalent resources. Same meaning as above.
    autoCheckIn - If true, check in the resource plan after updating.
    jobUid - Queue job GUID.

    Also I am assuming there is already a Resource Plan for the project – if not my code would fail with a System.Web.Services.Protocols.SoapException: ProjectServerError(s) LastError=GeneralItemDoesNotExist and you would need to use the UI or QueueCreateResourcePlan method.  And finally you cannot publish the resource plan unless the project plan is published – or you will get another error - System.Web.Services.Protocols.SoapException: ProjectServerError(s) LastError=ResourcePlanProjectPublishIncomplete.  It would be unusual to get this condition as in most cases you create resource plans on published projects, but could happen with Activitity plans and proposals and server-side or other programmatically created projects.

    Rather than repeat things I have added comments in the code where I think some explanation is necessary.  This snippet assumes you have a reference to PSLibrary = Microsoft.Office.Project.Server.Library; and a web reference to the Resource Plan web service.  I’ve hardcoded quite a bit of stuff just to show what is going on.

     

    Guid projUid = new Guid("357afdea-0b68-46bc-8358-7557c8f90a8f");            
    Guid resUid = new Guid("f249df7c-eca9-41c7-bd52-48def0ab50bc");                        
    ResourcePlan resourcePlan = new ResourcePlan();           
    resourcePlan.Credentials = CredentialCache.DefaultCredentials;           
    resourcePlan.Url = "http://brismithupgrade/2k7/_vti_bin/PSI/resourceplan.asmx";
    ResourcePlanDataSet dsResourcePlan = new ResourcePlanDataSet();
                 
    // Read in a resource plan dataset for our chosen project 
               
    dsResourcePlan = resourcePlan.ReadResourcePlan(null, projUid               
     ,DateTime.Parse("01/01/2010"), DateTime.Parse("12/31/2010")
     ,(short)PSLibrary.TimeScaleClass.TimeScale.Months , false, false); 
                           
    // Create a new Plan Resource Row and set some properties
    
    
    ResourcePlanDataSet.PlanResourcesRow resourcePlanRow 
    = dsResourcePlan.PlanResources.NewPlanResourcesRow();            
    resourcePlanRow.PROJ_UID = projUid;            
    resourcePlanRow.RES_UID = resUid; 
               
    // Assignment UID does not need to be specified - it will be auto generated             
    // The value used against intervalx will depend on the setting for the timePhasedFTE value            
    // If set to true, then enter values like 1 for one Full Time Equivalent            
    // If set to false the Intervalx values are entered as 1/10th Minutes - 600 = 1h, 4800 = 1d            
    // This entry adds 4800 = 1d = 8h, to the 7th interval - August with the settings I am using
      
    resourcePlanRow["Interval7"] = 4800;
                
    // And this one adds 5 days to September
               
    resourcePlanRow["Interval8"] = 48000;
                
    // 0 = Committed and 1 = Proposed or use the enumeration
                
    resourcePlanRow.ASSN_BOOKING_TYPE = (byte)PSLibrary.Resource.BookingType.Committed ;
                 
    // Add the row the the resource plan 
               
    dsResourcePlan.PlanResources.AddPlanResourcesRow(resourcePlanRow);
                            
    // Use the same jobUid for the update and checkin.
                
    Guid jobUid = Guid.NewGuid();
                            
    resourcePlan.CheckOutResourcePlans(new Guid[1] { projUid });            
    System.Threading.Thread.Sleep(1000);                      
    resourcePlan.QueueUpdateResourcePlan(projUid, dsResourcePlan, false, false, jobUid);  
                          
    //  Need to be sure the project plan is published or this will fail
    
    resourcePlan.QueuePublishResourcePlan(projUid, Guid.NewGuid());            
    resourcePlan.QueueCheckInResourcePlans(new Guid[1] { projUid }, false, new Guid[1] { jobUid });
     

    I hope this help you understand how to work with Resource Plans in a programmatic way.

  • Brian Smith's Microsoft Project Support Blog

    Project Server: A few AD Sync Gotchas

    • 8 Comments

    Thanks to Jon and Mark on our team for this article on ADSync.

    Sometimes there are lingering questions around Project Server and Active Directory Sync or specific scenarios to watch for that aren't documented. One of the biggest of these is something we've come to call AD GUID mismatches. This is when a user being synchronized has the exact same email address, SAM account and display name as a user already in the Project Server database, however, the AD GUIDs don't match.  We've seen this from time to time with different customers and have released a hotfix to help in this situation. Prior to the February 2010 Project Server CU, if this situation was encountered we'd end up in a situation where the sync job would never finish. Now, when this condition is detected, the user is skipped and the rest of the group is synchronized.

    Now for a little more information, first, how do we see users get into this state? A user has to be deleted from Active Directory and then recreated with the exact same Display Name, SAM account and email address. Sometimes we see this if an account had been recreated for a user during troubleshooting. Occasionally we see it when users leave a company and come back to work at a later date. So why don't we just automatically synchronize the users? There is a possibility, however remote, that a user could work on sensitive projects and then leave the company. At a later date a new hire could join the company and get the same Display Name, email address and SAM account. In that situation, if the user were added to the Project Server environment, they would get access to all the sensitive projects that the previous user had access to. We'd prefer to err on the side of security rather than have access inadvertently granted.

    We have a few recommendations to avoid this situation. First, whenever possible, don't delete users from AD if you use the AD Sync features of Project Server. Instead your should inactivate, or archive the accounts as available in your AD version. Secondly, it's definitely not recommended to reuse account names and email addresses for new individuals.

    We do have some other assistance to offer if you are in this situation, but best to open a support incident to let us guide you through the options.

    This issue steps off the beaten path a little bit from our normal Project Server planning and administration in that it's best for the PMO to get company/organizations AD Admins involved to help make sure their practices are compatible.

  • Brian Smith's Microsoft Project Support Blog

    Project Server 2010: I passed exam 70-177, Microsoft Project Server 2010, Configuring

    • 5 Comments

    Joined Christophe, and many of my support colleagues who have already passed the configuring exam for Project Server 2010 – 70-177.  As Christophe mentioned, the TechNet resources and the early books from Gary, Dale and Tony at msProjectExperts and from  Rolly Perreaux, Rolly Perreaux (updated URL) will certainly help you get through with top marks.  Nothing beats playing with the product though, to get you past those tricky questions were the answer is obvious – or is it?

    For full details of the exam, and how to take it visit the Microsoft Learning site at http://www.microsoft.com/learning/en/us/Exam.aspx?ID=70-177&Locale=en-us. This exam will gain you the following certification - Microsoft Certified Technology Specialist (MCTS): Microsoft Project Server 2010, Configuration.

    Technorati Tags: ,
  • Brian Smith's Microsoft Project Support Blog

    Project Server 2010: Copying custom Project site templates across instances

    • 4 Comments

    Interesting question came in today via the blog on my previous customization topic at http://blogs.msdn.com/b/brismith/archive/2010/03/15/customizing-the-project-site-in-project-server-2010.aspx and thought it worth a broader response, as it wasn’t something I had really thought about…  If you follow the directions at that blog then you can use the custom template in that PWA instance – but what about in other instances – or web apps or indeed other farms?  I played around a little and it is somewhat similar to the process in 2007 where you save off the template and then import – but I’ll guide you through the UI and also deal with an issue I ran in to – which I have a workaround for, but not sure why it worked on one of my sites but not another…

    If you have already used my previous article then you will have your template in a solution gallery – so browse to that gallery (Site Actions, Site Settings, Solutions (in the Galleries section) and you should see something like this:

    image

    I have two custom templates, called BaseSite and Rainbow.  If I want to use these in another PWA instance then I need to Right Click and use the “Save Target as…” option to save a WSP file (my desktop is my usual destination for such things – just so I can find them again).

    The next step is to go to the same location in your target instance, click the Solutions tab and click the Upload Solution option in the ribbon.

    image

    You can then browse to your saved .wsp file and upload.  This will bring up another dialog where you should Activate the solution:

    image

    Once activated then it should look like the first screenshot – and show Activated under the Status column.  It will then be available to be selected as the template to be used within your Enterprise Project Type definition.  Here is my selection when I updated the Basic Project Plan EPT to use my new Rainbow template.  One gotcha is that you do need to update the EPT definition – just changing the value in the Project Site Provisioning settings page will do nothing.

    image

    For me these steps were enough in one of my sites and I could successfully create and publish a new Basic Project Plan and got a ‘Rainbow’ based site.  (Just as an aside – I called this Rainbow not because it was colorful, but I was testing another scenario and had changed the values in the Issues and Risks ‘Category’ field choices list from the usual (1) Category 1… to Red, Orange, Yellow, etc.  This worked fine and these selections can be used for categorizing issues and risks – it breaks nothing, and even gets in to the reporting database without even needing to re-publish the plan – and will even be in the cube at the next build.

    Back to the main story.  For all my other sites,  I got a couple of failures in the queue when trying to create from this new template.  It appeared that the site was created but the template was not applied – as I could browse to it and it asked what template I would like…  So here are the messages, just so the search engine can have something useful to read:

    CreateWssSiteContent: Creating project site failed! Project Uid=5fd8daf5-619f-46c5-b884-8efe39b5935a, site URL=http://myserver.f.q.d.n/PWA/Test1, site name=Test1. Microsoft.SharePoint.SPException: The site template requires that the Feature {b90f23c9-68d5-4570-a3ef-4e491ee6d35a} be activated in the site collection

    WSSCreateSiteFailure (16400). Details: id='16400' name='WSSCreateSiteFailure' uid='bb9a4b90-5c77-4dc4-9bc9-2854554f6288' projectUID='5fd8daf5-619f-46c5-b884-8efe39b5935a' workspaceUrl='http://myserver.f.q.d.n/PWA/Test1/Test1' projectWorkspaceName='Test1'.

    Followed by:

    WSSWebAlreadyExists (16402). Details: id='16402' name='WSSWebAlreadyExists' uid='5703a3a1-4092-4a12-a15c-37b523ca9861'.

    There were also the usual 26000 GeneralQueueJobFailed messages too.

    From the message it appeared a feature hadn’t been activated and peeking into the content database this appeared to be something to do with AssociationForm.xsn.  This is probably related to the Dynamic Workflow solution starter I have been playing with – but you may well run in to other similar issues when moving things around so may need to activate features too.  This can be carried out via a PowerShell command – so start the SharePoint 2010 Management Shell as administrator then execute a command similar to:

    Enable-SPFeature –identity ‘b90f23c9-68d5-4570-a3ef-4e491ee6d35a’ –URL http://myserver.f.q.d.n/PWA

    where the identity will be the GUID from the first error message and URL will be the PWA instance where you want this template to work.

    Thanks to bpettersen for the question that prompted me to look deeper in to this topic.

    Technorati Tags: ,
  • Brian Smith's Microsoft Project Support Blog

    Project Server 2010: Business Intelligence Center – Behind the Scenes

    • 3 Comments

    In this posting I wanted to take a look at the structure behind the Business Intelligence Center in Project Server 2010 so that hopefully if you run in to any issues you can work out what might be wrong.  This adds to the TechNet article on configuring reporting at http://technet.microsoft.com/en-us/library/ee662106.aspx which includes some great videos, and also Treb’s blog posting on troubleshooting reporting problems http://blogs.technet.com/b/projectadministration/archive/2009/12/15/troubleshooting-business-intelligence-features.aspx.

    When you provision a new PWA site you get a Data Connection library, with folders for each language version you have loaded, then within each folder is a set of Office Data Connection (ODC) files that contain the details of the source of the data, the SQL query that will return the data, and the ID of the Target Application profile used to get the data (ProjectServerApplication is the default).  You also get the Sample Reports Library and the Templates libraries during the provision process, which also contain folders for each installed language pack.  When you build a cube you will see added another folder for each cube within each language folder for the Templates library and the Data Connections library – which again contains ODC files for the OLAP report templates added in the templates language directories at the same time the cube is built.

    So when you click on a sample report, then assuming it is in a trusted file location it will go off to the referenced ODC in the report, and assuming that too is in a trusted data connection location then this will use the credentials in the Target Application and go off and get you data.  What could possibly go wrong?

    Things can get interesting if you change Alternate Access Mappings (AAM).  Now the Sample Reports and Templates will still be there, but referenced by a different URL, so you will need to update the trusted file locations for those.  Also your data connections will be on a different URL so the trusted data connections address will also need to be updated.  So where will the report look for the ODC file?  You guessed it – in the original location.  If by pure luck or good planning the original location also happens to have a path that is still in the Alternate Access Mappings list then you will still get your report.  If not then a message will appear; The following data connection file does not exist or you do not have permissions to it: and it will look like this::

    image

    Now one answer would be to just add the AAM – but this may not be desirable or practical, particularly if the new AAM was added for Internet access and was a fully qualified domain name with SSL to replacing the original NETBIOS server name – or perhaps as in my testing you provisioned everything on one server, got it all working and then added a Web Front End.  You could of course just edit each report and update the ODC to look in the right place – but assuming you are just getting started and have not added a whole bunch of your own reports, templates and ODCs there is another way…  Delete the Business Intelligence Center!  Now obviously this is a big step, and as I said, you would only want to do this if you had added nothing of value that you didn’t mind re-creating, but by deleting the site, and then running the PWA provision ‘Edit’ option it will get re-created and the ODCs will point to wherever the default AAM is now pointing.

    To delete the BI Center (once you have re-read the paragraph above, and are really, really sure you want to do this), click on the option in the left navigation for Business Intelligence, then Site Actions, Site Settings, Delete this site (and it doesn’t go into the recycle bin!).  Once it is gone then check that your default AAM is pointing where you want it and go to the Project Service Application, select the Edit option from the drop down for the site you wish to re-create your Business Intelligence Center. then without making any changes in the page that comes up - click Edit.

    image

    You will see it go through the usual steps of provisioning, but what it is really doing is similar to a repair on a client installation – and when it find the BI Center is not there is will re-create it, but this time with the links to the ODCs now pointing to the right place.  Once the site is provisioned then go back to Business Intelligence and all will be good.  All libraries and folders for all languages will be there – even the ones for any cubes you have already built.

    I think OLAP was the most read topic of my 2007 blogs after common installation issues – so I am sure there will be more topics to add, but hopefully this background will help you understand what can and might go wrong.

    Technorati Tags: ,
Page 1 of 3 (11 items) 123