Thursday, April 16, 2009

Portfolio server 2007 User Passwords expire quickly

Just a quick one. Most of my users are using Windows auth but I have a few forms auth users for testing. The passwords on these accounts seemed to expire very quickly and I didn't see any options for changing this. Turns out there is a 'hidden' set of settings available only when you log in as 'super user'. This is the account you installed Portfolio server under.

Login in as that account and you will see the following under settings.
Under this you will have a setting for password expiration. This defaults to 1!
This can be reset to whatever value you require. Note the grace period as well. This defaults to 7. If the password is expired for more than 7 days, the account is locked. Before this, once authenticated, the user will be prompted to change password.

Wednesday, April 08, 2009

Automating Project Server 2007 timesheets with Powershell

I needed to import some ‘support’ time that was being tracked from outside of project server. We had reports that combined the two but that seemed messy. I don’t really program though so I needed to work it out in powershell. I believe I have all the major functionality done. Still to be determined are all the issues around data overwrites, timing etc but here is a short walkthough of connecting to Project Server 2007 PSI with powershell, querying users, querying timesheets, updating a line on a timesheet and queuing an update.

Lots of help from the SDK

http://msdn.microsoft.com/en-us/library/websvctimesheet.timesheet.queueupdatetimesheet.aspx

I also referenced some of the chrisfie, code from codeplex. It was in c# but it gave some good direction.

Still very rough, maybe I will post more as I polish it out. As I spent a good part of my day today on this, hopefully it will help somebody else.

On to the powershell:

#set up some env variables. this is largely to find wsdl and csc, maybe other libraries, i stole it from the web.

$env:VSINSTALLDIR="$env:ProgramFiles\Microsoft Visual Studio 9.0"

$env:VCINSTALLDIR="$env:ProgramFiles\Microsoft Visual Studio $obj\VC"

$env:DevEnvDir="$env:VSINSTALLDIR\Common7\IDE"

$env:FrameworkSDKDir="$env:VSINSTALLDIR\SDK\v2.0"

$FrameworkPath=$([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())

$env:FrameworkDir=$(split-path $FrameworkPath -Parent)

$env:FrameworkVersion=$(split-path $FrameworkPath -Leaf)

$env:PATH="$env:VSINSTALLDIR\Common7\IDE;$env:VCINSTALLDIR\BIN;$env:VSINSTALLDIR\Common7\Tools;$env:VSINSTALLDIR\Common7\Tools\bin;$env:VCINSTALLDIR\PlatformSDK\bin;$env:FrameworkSDKDir\bin;$env:FrameworkDir\$env:FrameworkVersion;$env:VCINSTALLDIR\VCPackages;C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin;$env:PATH"

$env:INCLUDE="$env:VCINSTALLDIR\ATLMFC\INCLUDE;$env:VCINSTALLDIR\INCLUDE;$env:VCINSTALLDIR\PlatformSDK\include;$env:FrameworkSDKDir\include;$env:INCLUDE"

$env:LIB="$env:VCINSTALLDIR\ATLMFC\LIB;$env:VCINSTALLDIR\LIB;$env:VCINSTALLDIR\PlatformSDK\lib;$env:FrameworkSDKDir\lib;$env:LIB"

$env:LIBPATH="$FrameworkPath;$env:VCINSTALLDIR\ATLMFC\LIB"

#I tried to start w/ the connect-webservice from the orielly cookbook but it was giving me errors and this just worked.

# connect to the Proj Serv Interface (PSI) and create a timesheet object to manipulate timesheets

wsdl.exe http://<SNIP>/pwa/_vti_bin/psi/timesheet.asmx?WSDL

csc /t:library TimeSheet.cs

[Reflection.Assembly]::LoadFrom("$pwd\timesheet.dll")

$objTS = New-Object TimeSheet

$objTS.UseDefaultCredentials = $true

# connect to the Proj Serv Interface (PSI) and create a resource object to manipulate resources

wsdl.exe http://<SNIP>/pwa/_vti_bin/psi/resource.asmx?WSDL

csc /t:library Resource.cs

[Reflection.Assembly]::LoadFrom("$pwd\Resource.dll")

$objRes = New-Object Resource

$objRes.UseDefaultCredentials = $true

#we will need a date mathable datetime for calc in a bit so setup a date

$today = date

#get a list of all active users

$lstRes = $objRes.ReadUserList("Active")

#you could loop through the resource list but I will set it to just me for troubleshooting.

# the full list of users can obtained with: $lstRes = $objRes.ReadUserList("Active")

#method def:

#public TimesheetListDataSet ReadTimesheetList (Guid resUID,DateTime startDate,DateTime finishDate,int select))

# the “int select” is from this table, values are added together if you need multiples.

# Acceptable Value=4. Select timesheets with Acceptable status.

# AllExisting Value=31. Select all timesheets.

# AllPeriods Value=32. Select all timesheets plus an empty record for each period with no timesheet.

# Approved Value=8. Select timesheets with Approved status.

# CreatedByMe Value=64. Select timesheets you created.

# InProgress Value=1. Select timesheets with InProgress status.

# Rejected Value=16. Select timesheets with Rejected status.

# Submitted Value=2. Select timesheets with Submitted status.

$lstTS = $objTS.ReadTimesheetList($objRes.GetCurrentUserUid(), $today.addDays(-50), $today, 31)

#we now have all the timesheets in our date range.

$lstTS.TimeSheets

#you can get a specific timesheet

$ts = $objTS.ReadTimeSheet($lstTS.Timesheets.Item(2).TS_UID)

$ts

#there are two main items here. Lines are the rows you see in your timesheet view. actuals are the items in the columns

#check your lines with

$ts.Lines

#get a specific line. NOTE: Do Not use $line variable here. That is a PS variable and it will be reset every time you hit tab.

$tsLine = $ts.Lines.Item(2)

#you will use this in a bit to get your line UID. this is what you attach your actual to.

#now check your actuals

$ts.actuals

#create a new actual to attach

$myActual = $ts.Actuals.NewActualsRow()

#note I am working on GMT and my server is on EST so it is likely the reason why the times are 5 hours off, i didn't bother to check into it too much

$myActual.TS_ACT_START_DATE = [datetime]"4/7/2009 5:00:00 AM"

$myActual.TS_ACT_FINISH_DATE = [datetime]"4/8/2009 4:59:59 AM"

$myActual.TS_ACT_VALUE = 90000 # this looks like a lot of time but for some reason PS stores data as 1000 units/min so 90,000 = 1.5 hours.

$myActual.TS_LINE_UID = $tsLine.TS_LINE_UID

#add my actual to the actuals list

$ts.Actuals.AddActualsRow($myActual)

#add my ts to the update queue

$objTS.QueueUpdateTimesheet([Guid]::NewGuid(), $ts.Headers.Item(0).TS_UID, $ts)

#check your timesheet, man, it's updated.

Friday, April 03, 2009

Portfolio server 2007 Wish List

I am sure there will be more but I have put this project aside for a bit so I will put what I have up now.

Setup
- Give me some defaults

General
- Show me who I am logged on as
- give me a real group structure so users can be part of multiple groups
- sync users/groups w/ AD
- poor button names. In project import, does 'Finish' mean 'import', several other instances.
- tab order on pages is not always what I would expect, especially tabbing from a form field to the 'update' button.


Optimizer
- turn of the damn graph unless I ask for it. Stepping through the optimizer opens an excel graph on each page which is unnecessary and just slows things down.

Portfolio server 2007 Attribute Calculation

This bugged me for a bit. Hopefully this will help somebody save the half hour it cost me.

I wanted to add a few new attributes calculated from other attributes. I added the attribute under settings -> Attrib and indicator management -> attribute definition. I set up my automatic calculation and saved the attribute. I even went back in to verify everything saved correctly. B)

But when I added the new attribute to my dashboard, I only got a bunch of 'NA's when viewing the dashboard. meh, ok, eventually I realize I forgot to associate it. But once i associated, now they were all blank. awesome.

Long story short, the new attributes don't seem to be calculated until you load the project. Even just selecting 'edit' on a project and going back to the dash board was enough to trigger a recalc of the fields.
Update: Even just viewing the project will calculate the attributes.

Once everything is associated and you get your initial calculation, it seems to be more automatic. If I update my formulas, the updated values show up when I reload the dashboard. ie, I don't have to open the projects again.

on a side note. I would have really preferred some basic attributes to be defined. There must be a common set that most companies would use. I am thinking about optomizer attributes for budget and resource usage, for example. The tools seem pretty powerful but an option to load a basic configuration (or even the config defined in the docs, workflow, I am looking in your direction) would have been a big plus. I will get around to a real wish list someday.

Thursday, April 02, 2009

100 characters for a project scope?

Apparently Microsoft Portfolio Server 2007 thinks you only need 100 characters to enter your Projects Objectives, business need, in scope, out of scope, etc...

I know we are living in a world of outrageous disk costs and even 100 characters of text should be a luxury. Err wait, that was 1980, when was this thing designed? Do I really want my project managers trying to plan in txt speak? "PJT gr8 OMG bnfts"

Given the small size of the portfolio server database, I am maxing these fields out. According to a post on the project server newsgroup (http://www.microsoft.com/communities/newsgroups/list/en-us/default.aspx?dg=microsoft.public.project.server&tid=f1e4971d-7390-4aba-bf1e-701de1f87df1&cat=&lang=&cr=&sloc=&p=1), we max out at 3950. I see that the application objective field is set to 3900 by default so I am going with that.

To implement, navigate to - settings -> Attribute and Indicator Management -> Attributes Definition. Click the Show Default Attributes button. Now search for your fields. Check the attribute in question and click edit. Update Maximum Text Length from 100 to what ever you want it to be. I didn't test w/ values larger than 3900.

I had to change:
PORTFOLIO_OBJECTIVES
OBJECTIVE
PROGRAM_OBJECTIVES
PROGRAM_IN_SCOPE
INSCOPE
PROGRAM_OUT_OF_SCOPE
OUT_OF_SCOPE
PROGRAM_BUSINESS_NEED
BUSINESS_NEED
PORTFOLIO_ASSUMPTIONS
PROGRAM_ASSUMPTIONS
ASSUMPTIONS
DEPENDENCIES
PROGRAM_DEPENDENCIES

With, as far as I could see, absolutely no rhyme nor reason, these were already set to 3900.
APPLICATION_OBJECTIVE
PORTFOLIO_IN_SCOPE
PORTFOLIO_OUT_OF_SCOPE
PORTFOLIO_BUSINESS_NEED
PORTFOLIO_DEPENDENCIES


I would guess there will be more. I will update this post with further details if I find them.

Friday, March 27, 2009

Portfolio server and Groups

Another thing I ran into when I started w/ Project Portfolio Server 2007 was that I couldn't populate the 'Project Initiators', Contributors and 'project Managers' groups. The answer is actually pretty obnoxious. You have to create very specifically named groups that contain the users you want to be available in these boxes. There is a similar issue with applications and portoflios. To see the 'magic' group name that will allow these to be populated, you need to dig into the aspx. Open WWWROOT\default\project.aspx. About 30 lines down you will see the following 3 lines:
cell position="1" usergroup="GRP_INITIATORS" label="Project Initiators....
cell position="2" usergroup="GRP_PROJECT_MANAGER" label="Project Manage....
cell position="1" usergroup="GRP_CONTRIBUTORS" label="Contributors" ....

I have snipped the end of the lines for display purposes. Drop the GRP_ from the name and that is your necessary group name. In this case, "Initiators", "Project Manager", "Contributors".

You have 2 options. Create a group called Initiators and populate it or you can rename the usergroup attribute to be whatever your group is called. For projects I created the groups. For applications, my application initators were the same as my projects 'Initiators'. So I changed the line:
cell position="1" usergroup="GRP_APPLICATION_INITIATOR" label="....
to:
cell position="1" usergroup="GRP_INITIATORS" label="....


This allowed my users that were considered project Initiators, to be selected as application Initiators.

This is only necessary due to the, IMHO, serious oversight of allowing users to belong to only one group.

Note that I tried to just set all 3 groups to GRP_CONTRIBUTERS but there seems to be internal logic preventing this.

A corollary issue I ran into was that some of my users would be project initators on one project buy project managers on another. Or contributors on one and project managers on another. Since I can't have users belong to more than one group, This presents a problem. A work around I found, but that I am not really satisfied with, was to assign people to different groups at different levels of the org.

Our organization structure has three levels
- Corp
-- Local Business Unit
--- IT Operations
--- QA, etc
I can assign users to be Project managers at one level and contributors at another. They then show up in the project bubbles for each type. Note that this gets into sticky issues with permissions, hence why i don't like the solution.

I am also likely going to need to narrow the number of groups. I have a small enough team that some of the portfolio managers are going to be Project managers and contributors. I can use the org trick a bit but not if I have to manage 9 different groups.

Cant wait for office 14, probably the first place that will be fixed.

Portfolio server project classes

OK, i have been having a heck of a time working w/ Project Portfolio Server 2007. There really isn't a lot out there in terms of discussion. I have run into a few things that I will start posting here for others benefit. There are plenty of items I don't know about so if anybody knows good resources, don't hesitate to point them out.

Anyway, one thing I ran into, was how to rename the project classes. When you are creating a project, you define a class for that project. The class defines which workflow the project will follow. They default to CLASS 1, CLASS 2 and CLASS 3. That isn't very helpful for my users. I saw how to link workflows to classes (under workflow management) but the naming of the CLASS es was annoying me.

I eventually found this under Settings->Attribute and Indicator Management -> Attributes defintion. Select to see default attributes. The Attribute is called Project Class.

I renamed mine to '>6 month projects', '2-6 month projects', and '<2>

Monday, August 20, 2007

Dublin, again


IMG_0206
Originally uploaded by cornasdf
Not even back a week before I shipped off again. This time to Dublin for an install. The install was on Monday so I headed out Sunday to get a bit of Dublin sight seeing in. Last time I was here I saw the temple bar and the Guinness brewery. Turns out, I am not sure what else to see in Dublin. By the time I got in and settled it was too late to do the bus tour. It was a nice day though so I just wandered Dublin for a couple of hours in the sun. Even Dublin gives me more sun than London. I went to see the Book of Kells, which is some old manuscript. Seems a bit dull but it was a really old, ornate manuscript. Saw some book making techniques of olden days. There was a ‘long hall’ at the end with lots of very old books. That in itself wasn’t that interesting but in there they had a bunch of recruitment posters from WWI. One of the most interesting was a dialog about how this was the generation would be defined by what you did during the war, be a man and have a good answer.

Got the install done the next day but didn’t have any time to do anything fun. Having a Guinness in the airport and finally catching up on my blogging (I wrote a bunch last night too).

Vibing: Sophomore Year


Magic Bus
Originally uploaded by cornasdf
We headed out to Vibes in a pair of matching Zip Cars. Apparently, this is a much better deal than renting from Avis or similar. Noted for next time. Vibes this year was in a large park on the ocean in Bridgeport, Connecticut. Much different than my first vibes in Mariasville which was in a very rural setting, this one was basically in the projects. The park itself was very nice but it wasn’t the nicest neighborhood around it. It’s ok, we didn’t ever leave the grounds and there were no problems that I heard of. The locals must have thought us quite crazy, especially Friday. They could sit there in their warm apartments and watch all these idiots (us) huddle in the cold rain. It did cross my mind to go knocking on doors at one point on Friday and see if I could watch some tv and get a warm shower.

Thursday was nice, lines to get in weren’t too bad and we caught a bit of good music. The thing didn’t really start until Friday. Friday, as I mentioned, was rough. It was cold and rainy. We tried to brave the weather and watch some music for a bit but it was pretty brutal. Even our shelter wasn’t keeping us dry. We ended up retreating to Marks large tent and playing risk for most of the day. As Matt put it, “if I didn’t have it on good authority that it would be nicer tomorrow, I would have to pack it in.” The weather did have it as clearing up on Saturday and it was right. It actually cleared up just as Karena showed up on Friday night. Just in time for PFunk.

Well, almost in time for P Funk. We got to the field, set up our area and I headed into the crowd to start dancing. I think George saw me coming b/c as I went out there, he stopped playing. Doh! Luckily, the next band, deep banana blackout was very funkified as well. They were also doing a James Brown tribute show so they played a bunch of JB covers. Sweet. The weekend has turned around.

Saturday started off exactly opposite Friday. Just as Friday was cold and dreary, Saturday was beautiful. Sunday too. I spent the rest of the weekend dancing, hacking and throwing a Frisbee around. Carmel brought her hoops again so their was always a party of people hoping around our group. Really made for a great weekend.

Driving back, Matt and I got into the wine (Carmel was driving). Then when we got back, Carmel could join and it got to be a bit messy. I caught a cab to my Newark hotel around 1am and was out again at 6 for my flight. All this made my flight a bit less productive than I hoped but it was still a winning weekend.

London weather held true as usual. This is the third trip in a row I have returned from Beautiful sunny weather to London only to find I need a jacket and umbrella for days. Ugh, this is killing me.

NY in August: The interim weekend


IMG_0102
Originally uploaded by cornasdf
Having been freed from work by various fuckups and incompetence, I had a free weekend. For Saturday, I headed up to the catskills. We took the dog swimming in some beaver pond which was hugely refreshing. It made me realize how much I miss the wilderness.

The next day was skydiving. A work colleague was having a bachelor party that involved jumping out of a plane. This was something I was very keen on doing for years but had largely forgotten about. This seemed like a good opportunity but I was still unsure. The tipping point was when Mason, another work colleague and veteran of 1000s of jumps, said, “if you do this, you will smile about it for a week”. Ok, how can I resist.

The whole episode took maybe 20 minutes in the plane and 10 minutes in the air. It was great fun but not a new hobby. The most amazing part, for me, was that initial feeling of leaving the airplane. You are high enough that it isn’t so much a heights thing but watching the plane, your lifeline, speeding away from you was curious. The freefall lasted about 20 or so seconds and then we floated down for another 10 minutes or so. Slide on your ass in for the landing and you are done.

And since we had to drive out to East Stroudsburg, PA for it, we even got cheese steaks (or pizza steaks in my case).

analytics