Back to Cleverworkarounds mainpage
Visit - A Seven Sigma Initiative
 

Dec 14 2009

SharePoint, Debategraph and Copenhagen 2009 – Collaboration on a global scale

Note: For those of you who do not wish to read my usual verbose writing, then skip to the last section where there is a free web part to download and try out.

Unless you are a complete SharePoint nerd and world events don’t interest you while you spend your hours in a darkened room playing with the SP2010 beta, you would no doubt be aware that one of the most significant collaborative events in the world is currently taking place.

The United Nations climate change conference in Copenhagen this month is one of the most important world gatherings of our time. You might wonder why, as a SharePoint centric blog, I am writing about this. The simple answer is that this conference in which the world will come together to negotiate and agree on one of the toughest wicked problems of our time. How to tackle international climate change in a coordinated global way. As I write this, things do not seem to be going so well :-( .

image

Climate change cuts to the heart of the wellbeing expected by every one of us. Whether you live in an affluent country or a developing nation, the stakes are high and the issues at hand are incredibly complex and tightly intertwined. It might all seem far away and out of sight/out of mind, but it is clear that we will all be affected by the outcomes for better and worse. The spectre of the diminishing window of opportunity to deal with this issue means that an unprecedented scale of international cooperation will be required to produce an outcome that can satisfy all stakeholders in an environmentally, economically and social bottom line.

Can it be done? For readers who are practitioners of SharePoint solutions, you should have an appreciation of the difficulty that a supposedly “collaborative tool” actually is to improve collaboration. Therefore, I want you to imagine your most difficult, dysfunctional project that you have ever encountered and just try and now multiply it by a million, gazzilion times. If there are ever lessons to be learned about effective collaboration among a large, diverse group on a hugely difficult issue, then surely it is this issue and this event.

Our contribution

My colleagues and I became interested in sense-making and collaboration on wicked problems some time back, and through the craft of Dialogue Mapping, we have had the opportunity to help diverse groups successfully work through some very challenging local issues. I need to make it clear that much of what we do in this area is far beyond SharePoint in terms of project difficulty, and in fact we often deal with non IT projects and problems that have significant social complexity.

Working with people like city planners, organisational psychologists, environmental scientists and community leaders to name a few, has rubbed off on myself and my colleagues. Through the sense-making process that we practice with these groups, we have started to see a glimpse of the world through their eyes. For me in particular, it has challenged my values, social conscience and changed the entire trajectory of where I thought my career would go. I feel that the experience has made me a much better practitioner of collaborative tools like SharePoint and I am a textbook case of the the notion that the key to improving in your own discipline, is to learn from people outside of it.

We have now become part of a global sense-making community, much like the global SharePoint community in a way. A group of diverse people that come together via common interest. To that end, my colleague at Seven Sigma, Chris Tomich has embarked on a wonderful initiative that I hope you may find of interest. He has enlisted the help of several world renowned sense-makers, such as Jeff Conklin of Cognexus and David Price of Debategraph, and created a site, http://www.copenhagensummitmap.org/, where we will attempt to create a global issue map of the various sessions and talks at the Copenhagen summit. The aim of this exercise is to try and help interested people cut through the fog of issues and understand the points of view of the participants. We are utilising IBIS, the grammar behind dialogue mapping, and the DebateGraph tool for the shared display.

image

How you can help

If you feel that issue mapping is for you, then I encourage you to sign up to Debategraph and help contribute to the Copenhagen debate by mapping the dialogue of the online sessions (which you can view from the site).

Otherwise, Chris has written a simple, free web part, specifically for Copenhagen which can be downloaded “Mapping tools” section of the Copenhagen site. The idea is that if you or your organisation wish to keep up with the latest information from the conference, then installing this web part onto your site, will allow all of your staff to see the Copenhagen debate unfold live via your SharePoint portal. Given that SharePoint is particularly powerful at surfacing data for business intelligence, think of this web part as a means to display global intelligence (or lack thereof, depending on your political view :-) ).

Installing is the usual process for a SharePoint solution file. Add the solution to central admin, deploy it to your web application of choice and then activate the site collection scoped feature called “Seven Sigma Debategraph Components”. The web part will be then available to add to a page layout or web part page.

image

The properties of this web part allow you some fine grained control over how the Debategraph map renders inside SharePoint. The default is to show the Debategraph stream view, which is a twitter style view of the recent updates as shown in the example below.

image

Stream view is not the only view available. Detail view is also very useful for rationale that has supplementary information, as shown in the example below.

image

By the way, you can use this web part to display any Debategraph debate – not just Copenhagen. The Debategraph map to display is also controlled via the web part properties.

For information on how to change the default map, then check out this webcast I recorded for the previous version here.

I hope that some of you find this web part of use and look forward to any feedback.

 

Kind regards

 

Paul Culmsee

www.sevensigma.com.au

No Tags



Sep 05 2009

Missing metadata with Office 2003 – yet another “duh” moment…

I had a problem this week that got resolved with something quite obvious, but I learned a lot in the process, so I am detailing it here.

Symptoms: Using MOSS 2007 SP2 and Office 2003 SP3, users complained that metadata on documents went missing. Consider the scenario below where we have a sample document library.

image

Our user opens the “Memo to Council re Convenor” document into Word 2003, makes a change and saves it. Note the difference. Where’s my metadata?

image

I asked about this on the ozmoss mailing list, and others noted the same issue. Some had applied the June 2009 cumulative update for WSS3 and the problem was solved for them. I applied this update, and it improved the situation, but did not cure the problem totally.

Upon further investigation, we were able to ascertain that the problem would only happen on certain PCs. The same user could update the same document on a different PC and it would work fine. A fiddler trace of the process allowed me to narrow down the issue and understand the sequence of events. The root cause of the issue was incorrect handling of HTML/JavaScript by Office 2003 and/or Internet Explorer. This manifests itself in an inconsistency in the display of properties in the Office “Web File Properties” dialog box (file->properties in an office 2003 app). Consider the example below.

clip_image002  clip_image002[5]

Note that the first dialog shows that values for the metadata columns are blank or default. Now consider the same document opened on a different PC. Well what do you know – we have metadata!

Fiddler confirmed that when saving a document to SharePoint from an Office 2003 application, the same HTTP request is made to SharePoint as is done when displaying the document properties in the above example.

In both cases, A HTTP GET request is made to the owssvr.dll  (WSS RPC)  and the dialogview method is called. Therefore, the root of my problem has something to do with the fact that the data returned by this call was not being parsed properly by MSWord on one PC (as illustrated by the first of the above dialog box screenshots). When a user than saved their edits, blank or default values are being written back to SharePoint, in effect “losing” the metadata.

So let’s take a look at the HTTP call and the data returned. The call to owssvr.dll  looks like this.

GET /somesite/_vti_bin/owssvr.dll?location=My%20Committee/Agenda%20attachment%20July%2009.doc&dialogview=SaveForm HTTP/1.1

The output returned by SharePoint is a bunch of HTML and JavaScript that MSWord then renders by calling the Internet Explorers rendering framework programmatically. (I’ve included sample output at the end of the post for the hardcore nerds).

So the question now becomes, what was preventing the correct HTML rendering on one PC and not the other? This was a difficult question to answer because I was unable to find a way to debug JavaScript when the output was rendered in Office 2003 apps.

When you think about it, there can be many potential causes here. Given that Internet Explorer is effectively doing the work (WinINet), this whole process could be adversely affected by add-ins, zone settings, AD policies, virus scanning, etc. On one affected PC I disabled all all-ins to Internet Explorer and retried without success. After around half an hour of frustration, I decided to reset IE’s configuration as shown below.

image

After accepting the various warnings, I retried the test and it all worked! Metadata was now being properly saved. “Awesome”, I thought. I’m not quite sure what the true root cause is, but at least I know how to cure it.

Then it suddenly dawned on me that I’d been stupid. For all of my low level examination of the office 2003/RPC interaction with SharePoint, picking the brain of gurus like MCM Spence Harbar, I’d never thought to clear the temporary internet files cache. Doh!

On the next affected PC I did so, and the problem also went away instantly.

*Blush*

In my defence of my dumbness however, I had never examined the behind the scenes integration with Office 2003 and SharePoint, and it did not even twig that Internet Explorer would be involved in the picture. Given that this problem manifests itself within Office 2003 applications, it is not immediately obvious that your temporary internet files would cause an issue here – but now I know better :-) .

And now I get it…

Now Office 2007 is not affected by this because it does not use this method at all. In 2007, the document information panel uses InfoPath to render metadata. At the time I naively thought that was a dumb idea because the document information panel cannot display custom column types. For example, let’s say you created a custom column type to hold a phone number with the correct formatting for country code and the like. In a SharePoint site you can display it fine, but in the Office 2007 document information panel, you will never see it. InfoPath only will work with the out of the box in column types.

My rationale was that if Office 2007 instead used JavaScript and HTML, then it should be able to display these sorts of custom columns. That may actually be true, but it is irrelevant. When you think of the sheer number of ways that the rendering of the code could be interfered with (Temporary Internet Files being one precedent), you can see why the Office team might have opted for the safety of InfoPath instead.

Now that I understand that this is how Office 2003 does it, I can plainly see that it leaves too much room for error.

So even though my problem was solved by a simple clearing of the cache, it still remains that things like a bad add-in or a bad AD policy setting could interfere with the Office 2003/SharePoint integration. So if you ever have this issue crop up, try the temporary internet files thing or reset IE’s configuration completely. It may save you a lot of time and pain troubleshooting.

Thanks for reading

Paul Culmsee

www.sevensigma.com.au

 

 

 

<html dir="ltr">
<HEAD>
    <META Name="GENERATOR" Content="Microsoft SharePoint">
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    <META HTTP-EQUIV="Expires" content="0">
    <!-- _locID="id_PageTitle" _locComment="{StringCategory=TTL}" -->
    <Title ID=onetidTitle>File Properties</Title>
<Link REL="stylesheet" Type="text/css" HREF="/_layouts/1033/styles/core.css">
    <META Name="Microsoft Theme" Content="default">
    <META Name="Microsoft Border" Content="none">
<script src="/_layouts/1033/init.js"></script>
<script src="/_layouts/1033/core.js"></script>
 
<script src="/_layouts/1033/bform.js"></script>
 
</HEAD>
<Script ID="Form_Validate">
function Form_Validate(fVisible)
{
    if (frm.FValidate(fVisible))
        document.OWSForm.IsFormValid.value="true";
    else
        document.OWSForm.IsFormValid.value="false";
}
</Script>
<Script ID="Update_UI_From_Values">
var bFormFieldsInited = false;
function Update_UI_From_Values()
{
    frm.SetFirstFocus(bFormFieldsInited);
    bFormFieldsInited = true;
    frm.DataBind();
    DefaultControls();
}
</Script>
<Script ID="Update_Values_From_UI">
function Update_Values_From_UI()
{
    frm.SetFirstFocus(bFormFieldsInited);
    bFormFieldsInited = true;
    frm.FValidate(false);
}
</Script>
<script language="JavaScript">
L_tooltipfile_Text = "";
L_tooltipfolder_Text = "";
selectedElement = null
inChangeSelection = false
slElem = null;
oldSelection = "";
bIsFileDialogView = true;
function selectrow()
{
    if (slElem) {
        slElem.className=oldSelection;
        slElem.title="";
        }
    selectedElement = window.event.srcElement;
    while (selectedElement.tagName!="TR") {
           selectedElement=selectedElement.parentElement;
           }
    slElem = selectedElement;
    oldSelection=slElem.className;        
    slElem.className="ms-selected";
    if (slElem.getAttribute("fileattribute") == "file")
        slElem.title=L_tooltipfile_Text;
    else
        slElem.title=L_tooltipfolder_Text;
    document.selection.empty();
}
function checkScroll()
{
    if (document.body.scrollHeight > document.body.offsetHeight ||
        document.body.scrollWidth > document.body.offsetWidth)
       document.body.scroll="yes";
}
</script>
<BODY marginwidth=0 marginheight=0 onload="checkScroll()" onresize="checkScroll()" scroll=no>
<!-- Banner -->
<TABLE  CELLPADDING=0 CELLSPACING=0 BORDER=0 WIDTH="100%" >
  <TR>
   <TD COLSPAN=3 STYLE="width:100%">
    <TABLE class=ms-bannerframe CELLPADDING=0 CELLSPACING=0 BORDER=0 STYLE="width:100%">
     <TR>
      <TD VALIGN=BOTTOM WITDH=25>
      <font size=1>&nbsp;</font>
      </TD>
     </TR>
    </TABLE>
   </TD>
  </TR>
</table>
<table width=100% cellpadding=4 cellspacing=0>
 <tr>
  <td>
   <TABLE CELLPADDING=0 CELLSPACING=0 BORDER=0 WIDTH="100%" >
    <tr>
     <td>
      <table cellpadding=0 cellspacing=0 style="margin-left: 3px;margin-bottom:2px">
       <tr>
        <td nowrap class="ms-titlearea">Some User</td>
       </tr>
       <tr>
        <td ID=onetidPageTitle nowrap class="ms-pagetitle">My Committee</td>
       </tr>
      </table>
     </td>
    </tr>
    <tr>
     <td>
      <table border=0 width=100% cellpadding=0 cellspacing=0 style="margin-left: 3px;margin-bottom: 3px">
       <tr>
        <td class="ms-sectionline" height=1><img src="/_layouts/images/blank.gif"></td>
       </tr>
      </table>
     </td>
    </tr>
        <!-- Item Form -->
        
<SCRIPT>
var frm = new OWSForm("OWSForm", false, "http:\u002f\u002fintranetdev\u002fsomesite\u002f_layouts\u002f");
</SCRIPT>
 
<SCRIPT> frm.dopt.chDateSep = "\u002f"; frm.dopt.chTimeSep = ":"; frm.dopt.SetTimeFormat(0); frm.dopt.SetDateOrder(1); frm.dopt.SetDOW(0); frm.dopt.stAM = "AM"; frm.dopt.stPM = "PM"; frm.dopt.TimeMarkPosn = 0; frm.dopt.webTZOffsetMin = -480;  frm.nopt.chDigSep = ","; frm.nopt.chDecimal = "."; frm.nopt.chMinus = "-"; frm.nopt.iNegNumber = 1; frm.nopt.SetGrouping("3;0"); 
frm.stFieldPrefix = "urn:schemas-microsoft-com:office:office#";
frm.stImagesPath = "\u002f_layouts\u002fimages\u002f";
frm.wBaseType = 1;
</SCRIPT><Form Name="OWSForm" id=OWSForm EncType="multipart/form-data" Action="http://intranetdev/somesite/_vti_bin/owssvr.dll?CS=65001" Method=POST onSubmit="return false;">
<INPUT Type=Hidden Name="_charset_" Value="utf-8">
<INPUT ID=onetidCmd Type=Hidden Name="Cmd" Value="Save">
<INPUT ID=onetidIsFormValid type=hidden name="IsFormValid">
<INPUT ID=onetidFormWasPosted type=hidden name="FormWasPosted">
<INPUT ID="MustUpdateForm" type=hidden name="MustUpdateForm" value="true">
<INPUT type=hidden name="NextID" id="NextID" value="-1">
<INPUT type=hidden name="NextUsing" id="NextUsing" value="">
<SPAN id='part1'><INPUT ID=onetidIOHidden TYPE=HIDDEN NAME="List" VALUE="{EF494645-1D24-4761-A874-0CB866FA494C}">
<INPUT ID=onetidIOHidden TYPE=HIDDEN NAME="ID" VALUE="New">
<TABLE border=0 cellpadding=2>
<SCRIPT>var _g_tp_fNewForm = true;</SCRIPT>
<TR style="display:none"><TH nowrap valign=top class="ms-formlabel"><nobr>Comment<font color=red></font></nobr></TH><TD class="ms-formbody"><SCRIPT>fld = new NoteField(frm,"Comment1","Comment","");fld.stNumLines = "20";fld.IMEMode="";fld.BuildUI();</SCRIPT>&nbsp;<br><SPAN class="ms-formdescription"></SPAN></TD></TR><TR style="display:none"><TH nowrap valign=top class="ms-formlabel"><nobr>Document&nbsp;Status<font color=red></font></nobr></TH><TD class="ms-formbody"><SCRIPT>fld = new ChoiceField(frm,"Corro_x0020_Status","Document Status","Not Started"); fld.format = "Dropdown"; fld.AddChoice("Not Started", "");fld.AddChoice("No Action Required", "");fld.AddChoice("In Progress", "");fld.AddChoice("Completed", "");fld.AddChoice("Deferred", "");fld.AddChoice("Waiting on someone else", "");fld.IMEMode="";fld.BuildUI();</SCRIPT><SPAN class="ms-formdescription"></SPAN></TD></TR><TR style="display:none"><TH nowrap valign=top class="ms-formlabel"><nobr>Content&nbsp;Type<font color=red></font></nobr></TH><TD class="ms-formbody"><SCRIPT>fld = new ChoiceField(frm,"ContentType","Content Type","LSWA Document"); fld.format = "Dropdown"; fld.AddChoice("LSWA Document", "");fld.AddChoice("Folder", "");fld.IMEMode="";fld.BuildUI();</SCRIPT><SPAN class="ms-formdescription"></SPAN></TD></TR><TR style="display:none"><TH nowrap valign=top class="ms-formlabel"><nobr>Committee&nbsp;Document<font color=red></font></nobr></TH><TD class="ms-formbody"><SCRIPT>fld = new ChoiceField(frm,"Committee_x0020_Document","Committee Document",""); fld.format = "Dropdown"; fld.AddChoice("Agendas", "");fld.AddChoice("Minutes", "");fld.AddChoice("Actions", "");fld.AddChoice("Administration", "");fld.IMEMode="";fld.BuildUI();</SCRIPT><SPAN class="ms-formdescription"></SPAN></TD></TR><TR style="display:none"><TH nowrap valign=top class="ms-formlabel"><nobr>Document&nbsp;Type<font color=red></font></nobr></TH><TD class="ms-formbody"><SCRIPT>fld = new ChoiceField(frm,"Document_x0020_Types","Document Type",""); fld.format = "Dropdown"; fld.AddChoice("Incoming Correspondence", "");fld.AddChoice("Outgoing Correspondence", "");fld.AddChoice("Internal Document", "");fld.AddChoice("Fax", "");fld.AddChoice("E-mail", "");fld.AddChoice("Memo", "");fld.IMEMode="";fld.BuildUI();</SCRIPT><SPAN class="ms-formdescription"></SPAN></TD></TR><TR style="display:none"><TH nowrap valign=top class="ms-formlabel"><nobr>Year<font color=red></font></nobr></TH><TD class="ms-formbody"><SCRIPT>fld = new ChoiceField(frm,"Year","Year",""); fld.format = "Dropdown"; fld.AddChoice("2000", "");fld.AddChoice("2001", "");fld.AddChoice("2002", "");fld.AddChoice("2003", "");fld.AddChoice("2004", "");fld.AddChoice("2005", "");fld.AddChoice("2006", "");fld.AddChoice("2007", "");fld.AddChoice("2008", "");fld.AddChoice("2009", "");fld.AddChoice("2010", "");fld.IMEMode="";fld.BuildUI();</SCRIPT><SPAN class="ms-formdescription"></SPAN></TD></TR></TABLE>
<script type="text/javascript">
_g_tp_rgctNames = new Array;
</script><SCRIPT>var _tp_rgctfld = null;var _tp_ctfld = null;var _g_tp_rgcts = new Array;</SCRIPT>
<script type="text/javascript">
_g_tp_rgctNames.push("LSWA Document");
</script>
 
            <SCRIPT>
            _tp_rgctfld = new Array;
            
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="ContentType";
                _tp_ctfld.fRequired = BoolFromString("");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="SelectFilename";
                _tp_ctfld.fRequired = BoolFromString("");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="FileLeafRef";
                _tp_ctfld.fRequired = BoolFromString("TRUE");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Created";
                _tp_ctfld.fRequired = BoolFromString("");
                _tp_ctfld.fHidden = BoolFromString("TRUE");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Title";
                _tp_ctfld.fRequired = BoolFromString("FALSE");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("FALSE", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("TRUE", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Modified";
                _tp_ctfld.fRequired = BoolFromString("");
                _tp_ctfld.fHidden = BoolFromString("TRUE");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Modified_x0020_By";
                _tp_ctfld.fRequired = BoolFromString("");
                _tp_ctfld.fHidden = BoolFromString("FALSE");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Created_x0020_By";
                _tp_ctfld.fRequired = BoolFromString("");
                _tp_ctfld.fHidden = BoolFromString("FALSE");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Comment1";
                _tp_ctfld.fRequired = BoolFromString("");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Corro_x0020_Status";
                _tp_ctfld.fRequired = BoolFromString("");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Committee_x0020_Document";
                _tp_ctfld.fRequired = BoolFromString("FALSE");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Document_x0020_Types";
                _tp_ctfld.fRequired = BoolFromString("FALSE");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="Year";
                _tp_ctfld.fRequired = BoolFromString("FALSE");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("");
                _tp_ctfld.stDisplay ="";
                    _tp_rgctfld.push(_tp_ctfld);
                
                _tp_ctfld = new Object(null);
                _tp_ctfld.stName="MoveDocu";
                _tp_ctfld.fRequired = BoolFromString("FALSE");
                _tp_ctfld.fHidden = BoolFromString("");
                _tp_ctfld.fShowInNewForm = BoolFromString2("", true);
                _tp_ctfld.fShowInEditForm = BoolFromString2("", true);
                _tp_ctfld.fReadOnly = BoolFromString("TRUE");
                _tp_ctfld.stDisplay ="Move Document";
                    _tp_rgctfld.push(_tp_ctfld);
                
            _g_tp_rgcts.push(_tp_rgctfld);
            </SCRIPT>
            
<script type="text/javascript">
_g_tp_rgctNames.push("Folder");
</script>
 
            <SCRIPT>
            _tp_rgctfld = new Array;
            _g_tp_rgcts.push(_tp_rgctfld);
            </SCRIPT>
            
<script type="text/javascript">
function _FixMpCt2Flds()
{
    var frm = frmCurrent;
    var rgn1 = frm.rgctNames;
    var rgn2 = _g_tp_rgctNames;
    var rgctflds = _g_tp_rgcts;
    if (rgctflds.length < rgn1.length)
    {
        var rgnew = new Array;
        var i;
        var j = 0;
        for (i = 0; i < rgn1.length; i++)
        {
            var n1 = rgn1[i];
            var n2 = rgn2[j];
            if (n1 != n2)
            {
                rgnew.push(new Array);
            }
            else
            {
                rgnew.push(rgctflds[j]);
                j++;
            }
        }
        _g_tp_rgcts = rgnew;
    }
}
_FixMpCt2Flds();
</script>
 
</SPAN></form>
<SCRIPT>
</SCRIPT>
 
        <!-- FooterBanner closes the TD, TR, TABLE, BODY, And HTML regions opened above -->
&nbsp;
</td></tr></table></PlaceHolder></TD></TR>
</TABLE>
</BODY>
</HTML>

No Tags



Jun 04 2009

New book preview – SharePoint 2007 Developers Guide to the Business Data Catalog

I’ve been busy on a number of fronts and some of the fruits of that work will appear soon enough, but I thought that I would pop up to let you know about a forthcoming book written by Brett Lonsdale and Nick Swan on a SharePoint component that has until now, been seriously under-represented in the plethora of SharePoint books out there in the marketplace.

The Business Data Catalog is one of those SharePoint components that is easy enough to understand conceptually, but then will scare the utter crap out of you when you delve into the guts of its XML based complexity.  At least that was my experience the first time I toyed with it in early 2007. Luckily for me, my ass was saved by a tool that had just been released as a public beta called BDC MetaMan. I downloaded this tool and within around 15 minutes I used it to set up a BDC connection to Microsoft’s Systems Management Server v4 to pull software package details into a SharePoint list and felt very proud of myself indeed. 

Fast forward to mid 2009 and BDC MetaMan has come a hell of a long way, as have its creators. Nick and Brett are about as world-authoritative as you can possibly get on the BDC and if you wish to become a Jedi in the dark arts of the BDC “force” then you now have your official bible. This book is absolutely crammed with detail and the expertise of the authors in this feature shines throughout.

The book is split up across 11 chapters and although it is not explicitly stated by the authors, seems to be made of 3 broad parts. Chapter 1 introduces the BDC, how it is architected (web parts, BDC column, BDC Search, and integration with User Profile import and the SDK). Also covered is the range of data sources, an introduction to Application Definition Files (ADF) and how it all integrates into the Shared Service Provider model.

Once the intro chapter is done with, Brett and Nick don’t waste too much time in diving deep. 

Chapters 2 and 3 deal with the structure of BDC Application Definition (ADF) files, and follows up with the complex world of how authentication plays out with the BDC. Chapter 2 delves far more into the ADF files than I ever wished to tread, but Nick and Brett somehow manage to describe a long, boring XML file in a logical, easy to follow manner and there was a lot of stuff that I learned here that I had simply missed from trawling MSDN articles. The authentication chapter is covered in excellent detail in Chapter 3 and goes way beyond the usual NTLM/Kerberos double-hop stuff. Authentication in the Microsoft world has become very complex these days, and there are various options and trade-offs. This chapter covers all of this and more, brilliant stuff.

After the deep dive of ADF and authentication, we surface a little from the previous two chapters into what I think really, is part 2 of this book. That is, several chapters that deal with how you leverage the BDC once you have connected to a line of business application. Chapter 4 introduces the built-in web parts that come with the BDC, shows how they are used and how they can be modified either using SharePoint Designer or tweaking XSL styles directly. Chapter 5 explores the BDC column type, how it can be used in the Office document information panel, in SharePoint Designer workflows, as well as its limitations. Chapter 6 explains how to leverage the BDC for allowing SharePoint to crawl your back-end line of business data and present it in search results. In addition to this, chapter 6 has a lot to offer just from the point of view of customising the search experience, whether using BDC or not. Finally, Chapter 7 examines how the BDC can be utilised to add data into user profiles that is leveraged via audience targeting.

Next we dive back into “real programmer” territory and what I think makes part 3 of this book. Chapter 8 delves deep into the BDC object model, for those times when the out of the box stuff just won’t quite cut it for you. The example used to demonstrate this object model is a web service that exposes BDC data via several methods. Chapter 9 then covers the creation of a custom web part that is in effect, an Ajax version of the out of the box “Business Data List web part” that refreshes data every few seconds without requiring a page load. Chapter 10 is particularly interesting because it examines how the BDC is used in conjunction with another oft overlooked suite of technologies known as “Office Business Applications”. The combination of BDC and OBA offer many interesting capabilities and among the examples, there are examples of Excel and Word leveraging the BDC as well as creating custom task panes, custom ribbons and the like. Finally, chapter 11 deals with using the BDC to write data back to the line of business applications and finishes with a great example of using InfoPath to submit data to a line of business application via a webservice that calls the BDC. That is hellishly cool in a nerdy developer kind of a way.

Phew! First up, *man* these guys are smart! I have to say this is the hardest SharePoint book that I have reviewed. It is obviously aimed at developers but it has so much to offer beyond the BDC. The content is very technical at times and obviously low-level. That, itself, is not the problem. Conversely, complex topics are handled really well and everything is extremely logically organised and flows well. The book is simply very, very comprehensive! There is plenty of meat for developers to sink their teeth into and this book will keep you going for a long time.

The preface of the book states that it has been written for an audience of “Microsoft SharePoint 2007 Information Workers and Developers who need to learn how to use, customize and create solutions using the Business Data Catalog”. I would agree with this, but I hope that information workers do not get put off by chapter 2 (and to some extent, chapter 3). This book dives deep straight off the bat and it is actually the middle chapters that offer the sort of insights that information workers will find the most useful.

So, if you think that the BDC deserves more than one single chapter towards the back of a SharePoint book, then this is your answer. As well as becoming an expert on the BDC, It will open your eyes to many possibilities beyond it.

Thanks for reading

Paul Culmsee

No Tags



May 22 2009

Developers who do a “Russell Crowe”

Hi all

If you were going to slot me into a little stereotype box, then you would slot me into the “IT pro” side of the fence. My coding is okay, but my real vein of expertise lay in infrastructure and over my career, I developed what I think is a reasonable troubleshooting instinct.

I’ve also worked with developers for the whole of my career and have the scars to prove it. The thing about developers is that they have this in-built reflex that until yesterday I did not have a word for. Then it came to me.

All developers have a little Russell Crowe inside of them!

imageWhy do I think this? Am I suggesting that developers are handsome, rugged types who melt your heart with their piercing eyes?  Oh, please. Allow me to explain with a simple mythical conversation with Mr Crowe. Let’s pretend you are a movie director.

You: “Hey Russell, we need to do another take, your dialogue wasn’t quite right.”

Russell: “Yes it was.”

You: “No seriously, I think if you had a look you’ll find that you missed a word or two.”

Russell: “Completely impossible. You are obviously an amateur and have no idea about acting.”

You: “I’ve directed twenty films and…”

BAM!!!  (Flying telephone hits you in the head at high speed, knocking you unconscious.)

Russell: (2 days later). Okay, so there was a minor issue with my dialogue, but the script was bad to begin with”

 

 

 

This exchange is somewhat representative of how programmers can occasionally be when it comes to troubleshooting. I remember one case where I was the “Cisco guy” who had problems with a developer who was so utterly fixated on “the network” being the cause of problems with his media streaming application. This created the classic “dev vs infrastructure guy” showdown, which we all know is usually won by the person whose home turf the battle is fought on. Therefore, the developer blaming “the network” and then going up against the “Cisco guy” is like Microsoft trying to win search market share off Google. The battle is so one sided it’s almost cruel to participate – but you feel it is your duty to put the little upstarts in their place anyway.

I have won the majority of such battles, not because I am any good, but because the developers have thrown the metaphorical phone at me before I’ve finished asking them if they would like a coffee. As a result of their inner Russell Crowe hurling the phone so quickly, their aim is way off, and the phone usually misses me, bounces off the wall and takes out their boss or some other authoritative figure.

So, they cop some heat and sulk in the corner for awhile, but do developers learn from this? Hell, no! The reason why this is so, is because little Russell doesn’t like to lose, and when he re-emerges, he causes temporary amnesia of all previous battles. Of course, his opponent remembers all, and the next battle is even more cruel that the previous one and the outcome is assured.

So, yesterday, my friend and colleague did his first “Russell Crowe” for some time. He hit a problem, and misinterpreted the cause and went down a path that led him to a very tunnel-vision view of what was wrong and what the solution was. He described the problem he was having to me and it didn’t feel “right”, but he was pretty insistent he was on the right path. So, I asked Twitter and got back a couple of suggestions and as soon as I put one to him… BAM!! Russell Crowe appeared and threw a phone at me.

“Well, they are obviously amateurs and haven’t a clue about the SharePoint SDK” was the gist of the response.

One of the respondents was Bjorn Furuknap, who I can assure you is *not* an amateur :-) .

Anyway a few minutes later we found a different way to troubleshoot which pretty quickly pinpointed the problem. My colleague was very contrite and good natured about it as I teased him mercilessly. I later mentioned to Bjorn that I had just dodged a metaphorical flying phone and he said this wonderful quote which I think sums it up.

“Of course. He’s a developer. We’re all like that. It is always some else’s fault!”

 

Thanks for reading

 

Paul Culmsee

www.sevensigma.com.au

No Tags



Apr 01 2009

Review – Understanding SharePoint Journal

I have been a huge fan of Bjørn Furuknap ever since I first read his amazing series of posts on on customising the user experience at SharePointMagazine.

What struck me about Bjørn is the quality of his content and his fluid, entertaining and accessible style of writing. Although I can code okay enough, I am not a serious developer by any stretch. But Bjørn’s ability to weave his way through some large, fairly prickly programming topics and at the same time keep a part-timer like me, not only following it all, but really interested from start to finish, is a testament to his skill as a writer and trainer.

Learning SharePoint with USP Journal

So when I found out he had started a series of SharePoint journals, I was very keen to provide a review and asked him nicely if I could :-) .

In short, I’m glad I did.

This debut edition starts on a relatively simple premise. “How do we see who is logged into my SharePoint site at any time”? We learn pretty quickly that this is not as simple as it sounds, but Bjørn deftly teases apart this question into the true problem statement, via basic user stories and easy to understand examples. The proposed solution is described at a high level, with a description on what you need to solve the problem and then summarises it with a mission statement, covering the goals of the solution and the “rules of engagement”

The “rules of engagement” are clear and have a strong governance/assurance affinity (brings a tear to my eye). The rules are;

  • Use only supportable methods and not harm a single Microsoft-provided file
  • Use the least amount of effort as possible
  • Utilize SharePoint native techniques as much as possible

I’m sure that “Governance man” would approve…

The final component of the introduction is a preview of the completed project (with screenshots – including one that I have pasted here).

image

Chapter 2-5 gets right into the think of things. Bjørn doesn’t assume too much (he skips programming 101 stuff like SharePoint features), but takes the time to explain setting up your project in Visual Studio for each component of this solution. He balances the theory with the practical extremely well, and manages to pack in a whole bunch of really important tools and key concepts such as:

  • WSPBuilder
  • DelegateControl (I love DelegateControl and I‘m not even a developer :-) )
  • List creation via feature (and code)
  • FeatureReceivers
  • SharePoint Manager 2007
  • CAML
  • Feature scopes and dependencies (via the object model)
  • Custom application pages
  • CustomAction methods

All chapters come with review questions to ensure key concepts have been learned. Even better still, all code from the journals are posted on codeplex so you can download the complete solutions. Brilliant stuff!

All in all, I have to say that of all of the development oriented authors that I read, Bjørn is one of the best writers out there, If you liked his work on SharePointMagazine and his own blog, then you will love these journals. If you are starting out your career in SharePoint development and want to learn a whole lot of different concepts in a fashion that is underpinned by sustainable development practices, then I strongly suggest that you grab yourself a copy.

Well done mate, great work!

Paul Culmsee

www.sevensigma.com.au

No Tags



Feb 27 2009

Mike’s code-monkey "SharePoint suitability" quiz

Ah – this is exactly my sense of humour. My colleague Mike Stringfellow wrote a post called "Code Monkey Hates SharePoint" where he presents a quick multi-choice questionnaire of seemingly innocent questions that allows you to determine how predisposed your code-monkey is to completely butchering your SharePoint environment. Apparently there is not much difference between "the ideal SharePoint developer" and a serial killer :-)

Good stuff – you can check it out here

No Tags



Feb 25 2009

Boy bands – how to understand the site definition/template debate

Hi all

I’ve read a few blogs on site definitions vs site templates and reading some development centric articles, particularly the alternative presented by Raymond, and expanded by Mike and summarised neatly by Chris. Being a part time developer, I found that the explanation were a little…shall we say… geeky and I had to expend far too many brain cells.

So to assist the rest of the SharePoint community who are not developers, I am going to attempt to explain the whole sorry debate to you using a more suitable analogy – boy bands. That way you do not have to worry about developer-speak.

image image image

Boy-band "definition"

There are several mandatory characteristics of being a boy band.

  1. All have to be pretty-boys
      One is permitted to be tough in a non threatening way
      One is sensitive
  2. There must be 5 members
  3. All must be able to dance
  4. Playing a musical instrument is not permitted
  5. Clothes are always the latest fashion
  6. Members do not write their own songs
  7. Must do exactly what the record company tells them

When you create a new boy-band, you audition a bunch of hopefuls, using this core set-up and then just give them a nice radio friendly name.

Now, it really doesn’t matter which band it is, this is the formula that is followed by record producers with staggering success. But there is a catch! Change any of these parameters and the whole thing falls apart. For example, if we replace the non-threatening tough guy with a fat kid who can’t dance, teenage girls will rebel and the band will have to break up. It makes no difference which boy-band we are taking about either. You have broken the fundamental structure of how they work and the whole thing will disintegrate.

This, my friends, is a *site definition*.

Also – this is very important to note. The "boy-band" definition is an out-of-the box definition. In other words, no matter what environment that you are operating in, you will always find that the boy-band definition is there.

Boy-band templates

However, just because you have to follow this definition doesn’t mean you can’t make some changes here and there. For example, you can safely change a boy-band’s musical style from pop to light opera and "New Kids On the Block" effectively turns into "Il Divo". If "Il Divo" turns out to be popular among the user population, then the record company will want to produce more operatic boy bands. If we could take "Il Divo" and somehow save them as a template, then we can create new operatic boy-bands quickly and easily.

But the core fact remains that if you modify the original boy-band definition, this new template will crash and burn as well.

"Operatic boy-bands" and "Pop boy-bands" are therefore examples of "site templates".

Both bands are based on the underlying "boy-band" definition and as a result, cannot exist independently without that definition. So what if we want to use the "Operatic boy-band" template in another location?

Not a problem, because as I described earlier, the boy-band definition is out of the box in all locations, and therefore the templates will always be able to be used in other locations.

Unfortunately, sometimes there are limitations with boy-band templates. The bands themselves have "grown" and now realise the original *definition* they have based their template on is too restrictive and will not scale with their future "artistic requirements". There is only so much that you can do when tweaking the more limited options provided by the template model. But since they are based on the underlying boy-band definition, then we are stuck.

New Kids On The block are a great case in point. In 1994, when they released their 4th studio album, they attempted to write their own songs to the detriment of their boy-band career. As we now know that violates rule 6 of the boy-band site definition and as expected, the group split up shortly after.

New site definitions and portability

image image image

So let’s just say that we want to make the first ever "hybrid death-metal boy band". We know that we cannot do this with a template alone because it will violate the boy-band definition and the world will explode. So we have to make up a new definition to accommodate this unique requirement. Suddenly we are faced with a lot more complexity here. Instead of just re-using a template we have to come up with a brand new definition and this requires specialised expertise. We already know that once we have made up our new definition that it can never be changed, so we had better make sure that we have it right the first time.

Now, let’s say that we create our first death-metal boy band called "New Kids on the Cannibal Corpse" and launch them in Sweden – where all the good metal bands come from. We create our new definition and then set up a new record label, hire PR guys, roadies, stylists, personal assistants and it all goes terrific. Sweden loves this new music sensation. But then when they try and break into the UK scene, it fails miserably. Why? Because we don’t have a record label there. They do not know how to properly deal with a new band based on this hybrid death-metal boy band definition because they have never seen this definition before.

This is one of the problems with making up new site definitions. Since it is not out of the box, if you try and move "New Kids on the Cannibal Corpse" to a new operating environment such as the UK, the definition is missing and therefore they have no idea how to handle it. This creates a dependency issue. Before "New Kids on the Cannibal Corpse" can be launched in the UK, we have to set up the "hybrid death-metal boy band" definition there *first*. Contrast this to "Il Divo" which can tour anywhere because the "boy band" definition is out of the box and therefore already set up by default at all locations.

Future Directions

Musical tastes change over time. Fads come and go, and alas, even boy-bands go out of favour. To achieve real longevity, all bands have to occasionally reinvent themselves – in effect go through a complete upgrade process and emerge as something completely new. The one advantage that boy bands have is that their popularity among teenyboppers means that the record industry will provide assistance to help them emerge as something new.

Unfortunately, the same cannot be said with our poor hybrid death-metal boy band, who, being a custom designed product, will have no guarantees that the record company will help them reinvent.

Therefore, there are disadvantages to a custom band definition. Future upgrades are tougher. But if you have managed to remain on the boy-band definition, despite working with the reduced flexibility of being a customised template, you should be able to upgrade to a newer version with much less pain.

This is important because although you might have more flexibility when freed from the confines of a boy-band definition, you pay for it with future upgrade uncertainty.

Conclusion

So now you should be full-bottle on the difference between site definitions and site templates. So, which one should you use? At the end of the day, it depends on whether you want to be a one-hit-wonder or achieve long term staying power. However, remember the most important thing above all else…

Under no circumstances should you *ever* listen to boy-bands!

 

Thanks for reading

Paul Culmsee

No Tags



Oct 31 2008

Free open source WCM for WSS

I have to say, Perth is home to some great SharePoint Talent. MVP Sezai is one prime example and Jeremy Thake is another.

But there is also another colleague of mine who you may or may not know – Tommy Segoro, who is one of those mild-mannered guys who simply gets down to it and produces great things.

Tommy has released a free, open source CMS that sits on top of WSS. Publishing pages, page layouts, the page editing toolbar, all on WSS, without having to upgrade to MOSS at great expense to get the publishing feature.

http://www.codeplex.com/completesharepoint

http://www.completesharepoint.net/Home/Pages/Default.aspx

check it out for yourself!

No Tags



Aug 09 2008

"Ain’t it cool?" – Integrating SharePoint and real-time performance data – Part 2

Hi again

This article is the second half of a pair of articles explaining how I integrated real-time performance data with an SharePoint based IT operational portal, designed around the principle of passive compliance with legislative or organisational controls.

In the first post, I introduced the PI product by OSIsoft, and explained how SQL Reporting services is able to generate reports from more than just SQL Server databases. I demonstrated how I created a report server report from performance data stored in the PI historian via an OLE DB provider for PI, and I also demonstrated how I was able to create a report that accepted a parameter, so that the output of the report could be customised.

I also showed how a SharePoint provides a facility to enter parameter data when using the report viewer web part.

We will now conclude this article by explaining a little about my passively compliant IT portal, and how I was able to enhance it with seamless integration with the real-time performance data stored in the PI historian.

Just to remind you, here is my conceptual diagram in "acoustic Visio" format

The IT portal

This is the really ultra brief explanation of the thinking that went into my IT portal

I spent a lot of time thinking about how critical IT information could be stored in SharePoint to achieve the goals of quick and easy access to information, make tasks like change/configuration management more transparent and efficient, as well as capture knowledge and documentation. I was influenced considerably by ISO17799 as it was called back then, especially in the area of asset management. I liked the use of the term "IT Assets" in ISO17799 and the strong emphasis on ownership and custodianship.

ISO defined asset as "any tangible or intangible thing that has value to an organization". It maintained that "…to achieve and maintain appropriate protection of organizational assets. All assets should be accounted for and have a nominated owner. Owners should be identified for all assets and the responsibility for the maintenance of appropriate controls should be assigned. The implementation of specific controls may be delegated by the owner as appropriate but the owner remains responsible for the proper protection of the assets."

That idea of delegation is that an owner of an asset can delegate the day-to-day management of that asset to a custodian, but the owner still bears ultimate responsibility.

So I developed a portal around this idea, but soon was hit by some constraints due to the broad ISO definition of an asset. Since assets have interdependencies, geeks have a tendency to over-complicate things and product a messy web of interdependencies. After some trial and error, as well as some soul searching I was able to come up with a 3 tier model that worked.

I changed the use of the word "asset", and split it into three broad asset types.

  • Devices (eg Server, SAN, Switch, Router, etc)
  • IT Services (eg Messaging, Databases, IP Network, etc)
  • Information Assets (eg Intranet, Timesheets,
image

The main thing to note about this model is to explain the different between an IT Service and an Information Asset. The distinction is in the area of ownership. In the case of an "Information Asset", the ownership of that asset is not IT. IT are a service provider, and by definition the IT view of the world is different to the rest of the organisation. An "IT Service" on the other hand, is always owned by IT and it is the IT services that underpin information assets.

So there is a hierarchical relationship there. You can’t have an information asset without an IT service providing it. Accountabilities are clear also. IT own the service, but are not responsible for the information asset itself – that’s for other areas of the organisation. (an Information Asset can also depend on other information assets as well as many IT services.

While this may sound so obvious that its not worth writing, my experience is that IT department often view information assets and the services providing those assets as one and the same thing.

Devices and Services

So, as an IT department, we provide a variety of services to the organisation. We provide them with an IP network, potentially a voice over IP system, a database subsystem, a backup and recovery service, etc.

It is fairly obvious that each IT service consists of a combination of IT devices (and often other IT services). an IP network is an obvious one and a basic example. The devices that underpin the "IP Network" service are routers, switches and wireless access points.

For devices we need to store information like

  • Serial Number
  • Warranty Details
  • Physical Location
  • Vendor information
  • Passwords
  • Device Type
  • IP Address
  • Change/Configuration Management history
  • IT Services that depend on this device (there is usually more than 1)

For services, we need to store information like

  • Service Owner
  • Service Custodian
  • Service Level Agreement (uptime guarantees, etc)
  • Change/Configuration Management history
  • IT Devices that underpin this service (there is usually more than 1)
  • Dependency relationships with other IT services
  • Information Assets that depend on this IT service

Keen eyed ITIL practitioners will realise that all I am describing here is a SharePoint based CMDB. I have a site template, content types, lists, event handlers and workflows that allow the above information to be managed in SharePoint. Below is three snippets showing sections of the portal, drilling down into the device view by location (click to expand), before showing the actual information about the server "DM01"

image image

image

Now the above screen is the one that I am interested in. You may also notice that the page above is a system generated page, based on the list called "IT Devices". I want to add real-time performance data to this screen, so that as well as being able to see asset information about a device, I also want to see its recent performance.

Modifying a system page

I talked about making modifications to system pages in detail in part 3 of my branding using Javascript series. Essentially, a system page is an automatically generated ASPX page that SharePoint creates. Think about what happens each time you add a column to a list or library. The NewForm.aspx, Editform.Aspx and Dispform.aspx are modified as they have to be rebuild to display the new or modified column.

SharePoint makes it a little tricky to edit these pages on account of custom modifications running the risk of breaking things. But as I described in the branding series, using the ToolPaneView hack does the job for us in a safe manner.

So using this hack, I was able to add a report viewer web part to the Dispform.aspx of the "IT devices" list as shown below.

image image

imageimage

Finally, we have our report viewer webpart, linked to our report that accesses PI historian data. As you can see below, the report that I created actually is expecting two parameters to be supplied. These parameters will be used to retrieve specific performance data and turn it into a chart.

image

Web Part Connection Magic

Now as it stands, the report is pretty much useless to us in the sense that we have to enter parameters to it manually, to get it to actually present us the information that we want. But on the same page as this report is a bunch of interesting information about a particular device, such as its name, IP Address, location and description. Wouldn’t it be great if we could somehow pass the device name (or some other device information) to the report web part automatically.

That way, each time you opened up a device entry, the report would retrieve performance information for the device currently being viewed. That would be very, very cool.

Fortunately for us it can be easily done. The report services web part, like many other web parts is connectable. This means that it can accept information from other web parts. This means that it is possible to have the parameters automatically passed to the report! 

Wohoo!

So here is how I am going to do this. I am going to add two new columns to my device list. Each column will be the parameter passed to the report. This way, I can tailor the report being generated on a device by device basis. For example, for a SAN device I might want to report on disk I/O, but a server I might want CPU. If I store the parameter as a column, the report will be able to retrieve whatever performance data I need.

Below shows the device list with the additional two columns added. the columns are called TAGPARAM1 and TAGPARAM2. The next screen below, shows the values I have entered for each column against the device DM01. These values will be passed to the report server report and used to find matching performance data.

image image

So the next question becomes, how do I now transparently pass these two parameters to the report? We now have the report and the parameters on the same page, but no obvious means to pass the value of TagParam1 and TagParam2 to the report viewer web part.

The answer my friends, is to use a filter web part!

Using the toolpane view hack, we once again edit the view item page for the Device List. We now need to add two additional web parts (because we have two parameters). Below is the web part to add.

image

The result should be a screen looking like the figure below

image

Filter web parts are not visible when a page is rendered in the browser. They are instead used to pass data between other web parts. There are various filter web parts that work in different ways. The Page Field filter is capable of passing the value of any column to another web part.

Confused? Check out how I use this web part below…

The screen above shows that the two Page Field filters web parts are not configured. They are prompting you to open the tool pane and configure them. Below is the configuration pane for the page field filter. Can you see how it has enumerated all of the columns for the "IT device" list? In the second and third screen we have chosen TagParam1 for the first page filter and TagParam2 for the second page filter web part.

image image image

Now take a look at the page in edit mode. The page filters now change display to say that they are not connected. All we have done so far is tell the web parts which columns to grab the parameter values from

image

Almost Home – Connecting the filters

So now we need to connect each Page Field filter web part to the report viewer web part. This will have the effect of passing to the report viewer web part, the value of TagParam1 and TagParam2. Since these values change from device to device, the report will display unique data for each device.

To to connect each page filter web part you click the edit dropdown for each page filter. From the list of choices, choose "Connections", and it will expand out to the choice of "Send Filter Values To". If you click on this, you will be promoted to send the filter values to the report viewer web part on the page. Since in my example, the report viewer web part requires two parameters, you will be asked to choose which of the two parameters to send the value to.

image image

Repeat this step for both page filter web parts and something amazing happens, we see a performance report on the devices page!! The filter has passed the values of TagParam1 and tagParam2 to the report and it has retrieved the matching data!

image

Let’s now save this page and view it in all of its glory! Sweet eh!

image 

Conclusion (and Touchups)

So let’s step back and look at what we have achieved. We can visit our IT Operations portal, open the devices list and immediately view real-time performance statistics for that device. Since I am using a PI historian, the performance data could have been collected via SNMP, netflow, ping, WMI, Performance Monitor counters, a script or many, many methods. But we do not need to worry about that, we just ask PI for the data that we want and display it using reporting services.

Because the parameters are stored as additional metadata with each device, you have complete control over the data being presented back to SharePoint. You might decide that servers should always return CPU stats, but a storage area network return disk I/O stats. It is all controllable just by the values you enter into the columns being used as report parameters.

The only additional thing that I did was to use my CleverWorkArounds Hide Field Web Part, to subsequently hide the TagParam1 and TagParam2 fields from display, so that when IT staff are looking at the integrated asset and performance data, the ‘behind the scenes’ glue is hidden from them.

So looking at this from a IT portal/compliance point of view, we now have an integrated platform where we can:

  • View device asset information (serial number, purchase date, warranty, physical location)
  • View IT Service information (owners, custodians and SLA’s)
  • View Information Asset information (owners, custodians and SLA’s)
  • Understand the relationships between devices, services and information assets
  • Access standards, procedures and work instructions pertaining to devices, services and information assets
  • Manage change and configuration management for devices, services and information assets
  • Quickly and easily view detailed, real time performance statistics of devices

All in all, not a bad afternoons work really! And not one line of code!

As i said way back at the start of the first article, this started out as a quick idea for a demo and it seems to have a heck of a lot of potential. Of course, I used PI but there is no reason why you can’t use similar techniques in your own IT portals to integrate your operational and performance data into the one place.

I hope that you enjoyed this article and I look forward to feedback.

<Blatant Plug>Want an IT Portal built in passive compliance? Then let’s talk!</Blatant Plug>

cheers

Paul Culmsee

 

 

 

 

OSISoft addendum

Now someone at OSISoft at some point will read this article and wonder why I didn’t write about RTWebparts. Essentially PI has some web parts that can be used to display historian data in SharePoint. There were two reasons why I did not mention them.

  1. To use RTWebparts you have to install a lot of PI components onto your web front end servers. Nothing wrong with that, but with Report Services, those components only need to go onto the report server. For my circumstances and what I had to demonstrate, this was sufficient.
  2. This post was actually not about OSISoft or PI per se. It was used to demonstrate how it is possible to use SharePoint to integrate performance and operational information into one integrated location. In the event that you have PI in your enterprise and want to leverage it with SharePoint, I suggest you contact me about it because we do happen to be very good at it :-)

 

No Tags



Jul 31 2008

Latest article on SharePoint Magazine posted…

The second article in the tribute to the humble leave form series has just been posted at SharePoint Magazine.

I eagerly await the "cease and desist" letter Matt Groenings legal team :-)

Enjoy!

image

No Tags



Next Page »

Today is: Tuesday 16 March 2010 |