How to download a WSP file from the Farm Solution Store

I’m following several migration projects during the last months, especially from SharePoint 2007 to SharePoint 2010, and of course I’m trying to stay within the standard approach as much as I can.

By “standard” I mean (roughly):

  • Premigration check
  • Deploy code customizations
  • Apply farm and webapp configurations
  • Perform a content database attach

This can be smooth or can be painful, especially during the last phase.

But… well, things can start to go wrong early, and unfortnuately not only during the premigration check.

For example, more than often we found a ton of wsps deployed, then ask our customer to provide us the wsp (the package, not necessarily the source code) and this fails with a sad “I don’t know where they are”. Or, which may be even worse, we get a different version of the package, which may or may not work as ecpected.

That’s why I wrote these 5 lines of PowerShell code that let us download the exact wsp package that is deployed.

This script is supposed to run on a SharePoint 2007 farm (that’s why I cannot leverage the commandlets included in the SharePoint 2010 PowerShell SnapIn).

Here it is:

[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”)

$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local

$solution = $farm.Solutions[“nameofthewsp.wsp”]

$file = $solution.SolutionFile

$file.SaveAs(“c:\wsp\nameofthewsp.wsp”)

With some extra work, you could make this script iterate over all installed solution packages and, maybe, save them as a single zip file for convenience.

Extract Crawled Properties Mappings

Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue

$searchapp = Get-SPEnterpriseSearchServiceApplication “Search Service Application Name Here”

$category = Get-SPEnterpriseSearchMetadataCategory –Identity “Category Name Here” -SearchApplication $searchapp

$properties = Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $searchapp -Category $category

foreach ($crawled in $properties)

{

$name = $crawled.Name

$managedProperties = $crawled.GetMappedManagedProperties()

foreach ($managed in $managedProperties)

{

$managedName = $managed.Name   

ac “c:\search.csv” “$name,$managedName”

}

}

I definitely love PowerShell 🙂

Measuring HTTP requests response time

Needless to say, this topic is complex, first of all because the total response time varies due to network congestion, server load, amount of bytes transfered just to name a few.

Anyway, if you just need to get a raw indication, you could just try out this small script:

function GetRequestTime([string]$url)

{

  $wc = new-object System.Net.WebClient

  $wc.Credentials = [System.Net.CredentialCache]::DefaultCredentials

  $start = get-date

  $output = $wc.DownloadString($url)

  $span = (get-date).Subtract($start)

  return $span.TotalMilliseconds

}

function ShootRequests([string]$url, [int]$count)

{

  $totalTime = 0

  1..$count |% { $totalTime += GetRequestTime($url)}

  return $totalTime / $count

}

What it does is firing for a request a configurable number of times and return the average response time. Here’s how you may invoke this function:

ShootRequests http://blog.claudiobrotto.com 50

Just a few notes, though:

  • It does not consider any client-side caching (you could easily overcome this issue by passing some query string parameter that makes the client consider it a brand new resource)
  • It does not download automatically any resource defined in the HTML of the page (i.e. if a page contains img tags that force the browser to download 10MB of content… this script just ignores that)
  • The rendering time is completely transparent too (you may have pages with a small network footprint but with a lot of JS code that slows doen the browser rendering)

Managing IIS settings through PowerShell

Do you miss the IISAPP command line tool that was available with IIS6?

Do you feel that APPCMD is not enough?

Enter the WebAdministration PowerShell module!

Its usage is straightforward, as it it leverages the concept of providers and drives that the PowerShell engine uses to unify the way you access resources on your server. And it provides several commandlets that can help you automate most (if not all) of the web administration tasks.

In order to use the WebAdministration module, you need to launch PowerShell with elevated rights, then just import the module:

Import-Module WebAdministration

A quick Get-Command will show you that there’s something to try!

gcm -Module WebAdministration | Measure-Object

In my environment, this shows a total count of 74 items (71 commandlets, 2 aliases and one function).

I’ll let you explore the list of commandlets yourself, while I spend some other words about the function, whose name is “IIS:”.

Just like C:, D: etc, which are indeed just functions that set the current location to the root of the C or D drives, the IIS: function uses the Set-Location commandlet to “move” to the IIS: drive.

Which, of course, is not a drive based on the FileSystem provider, but is relies on the WebAdministration PowerShell provider that you get inside the WebAdministration module.

Thanks to this approach, you can easily “navigate” within IIS settings just by using “dir” or “cd” (which, btw, are aliases too). For examples, if you need to list the IIS Web Sites on the local server, just try with this syntax:

dir IIS:\Sites

Or if you need to get, say, the list of running w3wp.exe processes for a specific application pool, you can type something like this:

dir IIS:\AppPools\<NameOfTheAppPool>\WorkerProcesses

Nice, isn’t it?

PowerShell string escaping

Ok, this is probably a very very basic topic to tal about, but anyway…

String escaping has always been cumbersome and tricky in – I guess – most of the programming languages I have used. You need a way to represent special characters, most of the times you do this by defining them through an escape sequence, and most of the times the escape sequence is made up of an escape character followed by another character (or a character code). You know that \n stands for “newline” in ANSI C syntax, right?

PowerShell follows these widely adopted standards, with a couple of gotchas.

First off, the escape character is the backtick (`), which is 0x60 (96) ASCII code and the U+0060 Unicode code.

Which is fine, I mean, using a backslach or a backtick… it doesn’t matter.

Well, yes, it does’t matter, although I’m using the Italian keyboard layout and we have no grave accent (back tick) character anywhere. Sgrunf 🙁

Second: in PowerShell we can use both single quote and double quote characters to enclose string literals.

The difference stands in the way the string is interpreted before being used.

Consider, as an example, the MSSQL$SHAREPOINT string.

If you use single quotes (‘MSSQL$SHAREPOINT’), you get exactly what you have typed within the single quotes.

If you use double quotes, and try to print-out the string variable:

Write-Host “MSSQL$SHAREPOINT”

You get, guess what, just MSSQL on your output stream.

The reason for this behavior is due to the automatic variable substitution that the PowerShell intepreter performs and strings literals escaped by double quotes: variable names, in PowerShell, are prefixed by the $ char, which means that the previous string is resolved as MSSQL concatenated with the value of the SHAREPOINT variable, which in my case is just null.

Sometimes, even simple things get tricky!