Blog Stats
  • Posts - 44
  • Articles - 0
  • Comments - 10
  • Trackbacks - 0


Saturday, December 7, 2013

Saving A SharePoint site as a template when the . link is not available under Site Actions

Saving A SharePoint site as a template when the . link is not available under Site Actions

Microsoft disabled the link for publishing sites even though the action is still available. This because they fear that one will use the template in a different site collection that may or might not be “publishing” enabled.

Well, I have invested time in building a site to my liking and do not want to repeat the effort time and again. I know that practice makes perfect, but I am not a concert pianist and “Practice makes tired” and “Doing it again makes error” are the idioms come to my mind. So we observe, learn and… Cheat!

In sites where the link is available we look at what happens to the URL when we click it. Then it becomes obvious.

A little change in the site URL does it. Here is how:

This is the site I want to create a template from:

Here is the URL I used to make the template:

Get rid of the default.aspx and replace it with _layouts/savetmpl.aspx

That’s all folks

Friday, December 6, 2013

Shakespearean Sonnets and doing SharePoint in the Pharmaceuticals

When my love swears that she is made of truth
I do believe her, though I know she lies,
That she might think me some untutor'd youth,
Unlearned in the world's false subtleties.
Thus vainly thinking that she thinks me young,
Although she knows my days are past the best,
Simply I credit her false speaking tongue:
On both sides thus is simple truth suppress'd.
But wherefore says she not she is unjust?
And wherefore say not I that I am old?
O, love's best habit is in seeming trust,
And age in love loves not to have years told:
   Therefore I lie with her and she with me,
   And in our faults by lies we flatter'd be.

Shakespeare Sonnet 138

Shakespearean Sonnets and doing SharePoint in the Pharmaceuticals

I had the privilege of building SharePoint sites for a Pharmaceutical company whose name will remain hidden to protect the guilty. Not that this company is much guiltier than any other of the same ilk and not that they really have a choice but to be the way they are (and if that is not a convoluted statement, it is only because I have made some by far more convoluted than this).

Regardless of blame or lack thereof, as a consultant in the Pharma industry my hands are tied. I am not even an admin on my own PC and have to beg for every privilege no matter how important it is for a successful performance of my tasks.

So what does all of this have to do with the Shakespearean sonnet? A LOT!!

The Surrey sonnet better known as the Shakespearean sonnet consists of 14 lines, each of 10 syllables and divided into 3 quadruplets and a couplet. The general rhyming form is abab, cdcd, efef, gg. The last two lines (gg) generally sum up the first twelve.

Did you notice how many rules the author has to observe and obey? The rules are not as simple as one might think. Writing in 10 syllables is actually extremely hard. Shakespeare himself “Cheated” a lot by swallowing extra syllables (e.g. o’er instead of over) and taking poetic license with the way words are pronounced so that he could preserve the rhymes (note the young – tongue in lines 5 and 7 above and even more so with lies - subtleties in lines 2 and 4).

When I was a young student, my love for Math did not reduce my joy of poetry and when English (as a second language) was added to my curriculum, I started to write poetry. One of my self-training tasks was to mimic the poetic forms of the poets that I admired. Among them A.E. Housman, Robert Louis Stevenson, and Lewis Carroll – yes “Alice in Wonderland” and “Through the Looking Glass” contain many a wonderfully constructed poems as does the “Hunting of the Snark”. Did I mention Shakespeare? Yes, I tried my hand in Shakespearean sonnets too. Little did I know that the sonnetic (my word with a self-granted poetic license) limitations and the unavoidable bending of the rules that they entail will become useful so many years later when I needed to build a few especially equipped yet codeless sites for the Pharmaceuticals.

Sonnet 18 is possibly the most quoted and mentioned of all the sonnets. Look it up. Here is how my own poor imitation looks.

Shall I compare thee to a firm round grape?
Thou art more lovely and much more divine.
For it can only keep its young firm shape
In the summer, upon the fruitful vine.
Thy true beauty, being all internal
Compares to that of the good vintage wine;
Like the amber liquid it's eternal,
With a taste that lingers pure and sublime.
And I the lusty taster can't refrain
From sipping on your excellent sweet taste,
Forging my will trying to contain
And rule the urge of drinking you with haste.
  For you, dear soul, as delicate as lace,
  Are only to be sipped with careful grace.

That’s All Folks!!

Sunday, May 19, 2013

SharePoint QuicLaunch Maker with PowerShell

At times I create so many sites and sub-sites that the Top-Nav cannot handle it. It is better to add the new links to the Quick Launch.

The function below makes it a snap.

Here is how it is used:

The first line inserts a heading "OrgSites" under the "Lists" heading (already there) in the QuickLaunch.

New-SPNode -Web $siteurl -NodeText "OrgSites" -NodeLink "Head" -NodeParent "Lists"

TAnd this line inserts the URL of a site named $web1name and the URL $web1url unter the new "OrgSites" heading

New-SPNode -Web $siteurl -NodeText $web1name -NodeLink $web1url -NodeParent "OrgSites"

Here (FINALLY!!) is the function

# New-SPNode creates an entry in the QuickLaunch navigation
# $Web is the URL of the site
# A node is made of text - $NodeText and link - $NodeLink
# If the link says "Head", then the node is a heading, else it is assumed a URL
# If "Head" then the heading is added immediately under The parent heading ($NodeParent)
# No checking for a URL being a URL
# Nodes are always added last
# Nodes are added under $NodeParent

function New-SPNode {
string]$NodeText, #"Head" if Heading
Start-SPAssignment -Global
= Get-SPWeb -Identity $Web
= $SPWeb.Navigation.QuickLaunch # QuickLaunch
= $QL | where {$_.Title -eq $NodeParent}
# Check if heading
($NodeLink -eq "Head")
$NewHead = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode($NodeText, "")      $QL.Add($NewHead, $PrevHead) | Out-Null



$NewNode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode($NodeText, $NodeLink)

      Write-Host "New-SPNode: " $Web " " $NodeText " " $NodeParent -ForegroundColor Blue -Backgroundcolor magenta
$PrevHead.Children.AddAsLast($NewNode) | Out-Null
Stop-SPAssignment -Global


That's All Folks!!

PowerShell Idiosyncrasy Explained

Doug Finke, A PowerShell MVP tested it in .Net where it fails as well. He explained that The call is ambiguous between the following methods or properties: 'System.Math.Floor(decimal)' and 'System.Math.Floor(double)'

My understanding is that PowerShell convert variables as it "pleases". 1/5 will most likely convert to float.

There maybe another approach to doing it w/o the [Math]::Floor. It is the format it with "{0:N0}", then use the D2 format.

$i = 1
$j = "{0:N0}" -f $i/5
$k = "{0:D2}" -f $j

AND IT WORKS!! This is probably better than the [Math]::Floor

That’s All Folks

Thursday, May 9, 2013

PowerShell Format Idiosyncrasy

Here is a piece of code I tested for the conversion of the numbers 0 thru 99 into 20 strings of exactly 2 digits. The first is 04, the next 09, then 14,19,24,29, etc. all the way to 94, 99.


The code: "{0:D2}" -f $d formats each number to exactly 2 digits.

The $i used in the “for” loop is interpreted by PowerShell – it automatically assigns it to a float. So when dividing by 5, we get fractions. I needed it to be whole numbers, hence the [math]::floor($i/5).


for ($i = 0; $i -lt 100; $i++)
    $n = [math]::floor($i/5)
    $d = $n * 5 + 4
    "{0:D2}" -f $d

I erroneously assumed that the result $d will be formattable ("{0:D2}" -f $i renders the desired result), alas this results in the following error:


Error formatting a string: Format specifier was invalid..

At E:\HA\testformat.ps1:6 char:2

+ "{0:D2}" -f $d

+ ~~~~~~~~~~~~~~

+ CategoryInfo : InvalidOperation: ({0:D2}:String) [], RuntimeException

+ FullyQualifiedErrorId : FormatError

I tried all sorts of things, but the error was persistent, then I tried coercing – the PowerShell term for casting. I used [float] and [decimal] to no avail, but my 3rd (and obviously last*) attempt was [int] and it worked.


for ($i = 0; $i -lt 100; $i++)


$n = [math]::floor($i/5)

[int]$d = $n * 5 + 4

"{0:D2}" -f $d


Generated the desired results.

* Why is it that we always find what we look for in the VERY LAST place we looked?


That’s all Folks

Wednesday, December 19, 2012

Comparing WFE servers

Comparing WFE servers

One of the SharePoint farms I am involved with has a load balanced pair of WFE. One of the web parts had acted sporadically – at times working well, at others not at all and I suspected that it might be because it was set wrongly on one of the servers and correctly on the other. Well, I went and checked the GACs on both servers. I did this by writing a PowerShell script that garners the assemblies and outputs them into a spreadsheet. Now with two spreadsheets in my hand I proceeded to examine them for differences.

NB the item count itself it was obvious that the twain were not similar, but I needed detail and with hundreds of items in each and but a pair of eyes – tired eyes – the task was daunting.

Well, I obviously assumed that like we do with Word, I could use the Diff. Alas Microsoft did not build this into the system. A variety of packages that I found on the web did not do such a bright job either. I did not need to see the differences in editing in cells, or whether one cell had a macro and another did not. All I needed was to find which assemblies are common to the two servers and which are unique to each.

Again PowerShell came to the rescue. I love this thing and I enjoy learning new thing about it, so I wrote a little PowerShell script that highlights the differences.

I tested my script using the two sheets below. The asterisks in column E identify the unique entries in each. Entries lacking this asterisk are common. Note that the sheets are also of different lengths.


Finding common and unique rows is an easy enough task. The spreadsheets have to be sorted (both ascending) and compared.

Here is a piece of history. Before personal computers and local area networks, we had central computing. There were Mainframes in the very beginning and then minicomputers. The PC is just about 36 years young. In the very beginning we did not even have dumb terminals by which people could get or feed information into the beast. Instead we used punched tape, punched cards, magnetic tape and disk (much bigger in size, much more expensive and much smaller in capacity). Jobs were run as batches. Still, data processing needed to be done and the sorting and merging of files was a major part of the effort.

I have taken the old IBM mainframe sort-merge algorithm, actually the merge part, and twisted it a little to match the task of comparing files. The compare part is the major ingredient in the merge algorithm, but here I used it for reporting rather than merging.

Enough with history. How is it done? You read the 1st line from both files. If A is less than B, you report A as unique and read A again (and compare again). If B is less than A, you report B as unique and read B. whoever is smaller is reported as unique and its next line is read. If the lines are equal, report them as common and read from both.

I used these two sheets and ran the script. Below are the results. Notice the use of color to accentuate and make it easier to read. The script also produces the same report in rtf format.


I also ran the report on a real set of two GAC lists from two WFE. The screenshot below shows the result of their comparison. The report has hundreds of lines in it so I only showed the end.


Finally the code.

There are two scripts involved. Find them in the following links:

Garnering the GAC assembly list in:

Comparing the Csvs in:

Before you run them, change the extensions from ‘txt’ to ‘ps1’

Also note that because my site is hosted on a Unix system, the links are case sensitive. You may be better off just clicking on them.

That’s All Folks

Oh, it is best to view code in a smart editor, so change the extension and view the code in Notepad++ or PowerGui Script Editor (or another good editor of your choice)

Sunday, October 21, 2012

New CodePlex Project–SPDeployRetract


I have just finished a new CodePlex project named SPDeployRetract. This is a sophisticated PowerShell script that allows you to to deploy solutions and InfoPath forms with ease. It is especially beneficial because once you set up the instructions in the xml input, you can repeat the process in farm after farm without error.

The script also allows for easy retraction. You may always retract the last deployment by setting the instructions to do so. This is possible because every action taken is recorded and old versions of each WSP are backed up for redeployment.

Look it up in:

That’s all Folks!!

Tuesday, June 26, 2012

Twice as long and half as long

We are in a project and we hit some snags. What’s a snag? An activity that takes longer than expected. Actually it takes longer than the time assigned to it by an over pressed PM who accepts an impossible time table and tries his best to make it possible, but I digress (again!). 

So we have snags and we also have the opposite. Let’s call these “cinches”.
The question is: how does a combination of snags and cinches affect the project timeline?

Well, there is no simple answer. It depends on the projects dependencies as we see in the PERT chart. If all the snags are in the critical path and all the cinches are elsewhere then the cinches don’t help at all. In fact any snag in the critical path will delay the project.  Conversely, a cinch in the critical path will expedite it. A snag outside the critical path might be serious enough to even change the critical path. Thus without the PERT chart, we cannot really tell.

Still there is a principle involved – Time and speed are non-linear! Twice as long adds a full unit, half as long only takes ½ unit away.

Let’s just investigate a simple project. It consists of two activities – S and C - each estimated to take a week. Alas, S is a snag and really needs twice the time allotted and – a sigh of relief – C is a cinch and will take half the time allotted, so everything is Hun-key-dory, or is it?  Even here the PERT chart is important. We have 2 cases:

1: S depends on C (or vice versa) as in when the two activities are assigned to one employee. Here the estimated time was 1 + 1 and the actual time was 2 + ½ and we are ½ week late or 25% late.

2: S and C are done in parallel. Here the estimated time was 1, but the actual time is 2 – we are a whole week or 100% late.

Let’s change the equation a little. S need 1.5 and C needs .5 so in case 1, we have the loss fully compensated by the gain, but in case 2 we are still behind.

There are cases where this really makes no difference. This is when the critical path is not affected and we have enough slack in the other paths to counteract the difference between its snags and cinches – Let’s call this difference DSC. So if the slack is greater than DSC the project will not suffer.

Conclusion: There is no general rule about snags and cinches. We need to examine each case within its project, still as we saw in the 4 examples above; the snag is generally more powerful than the cinch.

Long live Murphy!
That’s All Folks

Deploying InfoPath forms – idiosyncrasies

Well, I have written a sophisticated PowerShell script to expedite the deployment of InfoPath forms - .XSN file.  Along the way by way of trial and error (mostly error and error), I discovered a few little things. Here they are.
•    Regardless of how the install command is run – PowerShell or the GUI in Central Admin – SharePoint enwraps the XSN inside a solution – WSP, then installs and deploys the solution.
•    The solution is named by concatenating “form-“ with the first 16 characters (or less if the file name is shorter than 16) of the file name and the required WSP at the end. So if the form name was MyInfopathForm.xsn the solution name will be form-MyInfopathForm.wsp, but for WithdrawalOfRequestsForRefund.xsn it will be named form-WithdrawalOfRequ.wsp
•    It only gets worse! Had there already been a solution file with the same name, Microsoft appends a three digit number to the name, like MyInfopathForm-123.wsp. Remember a digit is a finger, I suspect a middle finger, so when you deploy the same form – many versions of it, or as it was in my case – testing a script time and again, you’ll end up with many such digit (middle finger) appended solutions, all un-deployed except the last one. This is not a bug. It’s a feature!


Well, there are ways around it. When by hand, remove the solution from the solution store before deploying the form again. In the script I do the same thing.

And finally - an important caveat; Make sure that all your form names are unique in the first 16 characters. If you also have a form with the name forWithdrawalOfRequestForRelief.xsn, you’re in trouble!

That’s all folks!

Friday, June 1, 2012

PowerShell Try Catch Finally

PowerShell Try Catch Finally

I am a relative novice to PowerShell and tried (pun intended) to use the “Try Catch Finally” in my scripts. Alas the structure that we love and use in C# (or even – shudder of shudders - in VB) does not always work in PowerShell. It turns out that it works only when the error is a terminating error (whatever that means).

Well, you can turn all your errors to the terminating kind by simply setting -

$ErrorActionPreference = "Stop", And later resetting it back to “Continue”, which is its normal setting.

Now, the lazy approach is to start all your scripts with:

$ErrorActionPreference = "Stop"

And ending all of them with:

$ErrorActionPreference = "Continue"

But this opens you to trouble because should your script have an error that you neglected to catch (it even happens to me!), your session will now have all its errors as “terminating”. Obviously this is not a good thing, so instead let’s put these two setups in the beginning of each Try block and in the Finally block as seen below:


That’s All Folks!!



Copyright © PointsToShare