PowerShell to activate a SharePoint 2010 feature on every site collection in a web app

I recently was given a WSP to add to our farm.

In this case after the WSP was installed and deployed we needed to activate the feature at the site collection level.
Thats usually easy enough to do through the UI, but in this particular case we had a web application which had over a dozen site collections.

ie:

  • http://jack.com
  • http://jack.com/blog
  • http://jack.com/marketing
  • 10 more like the above…

Activating it at http://jack.com from the UI was fine, but when the user navigated to http://jack.com/blog they were stumbling onto another site collection, and the feature wasn’t activated there.

To activate it on every Site collection meant that I’d have to a) know what each site collection was, and b) visit that site, and activate the feature.

Too much work.

What was needed was a simple script that would loop though each site collection, enabling the feature on each one.

The script below is a result of that need…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
 # this script enables a feature on every site collection on a given web app
 
 Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue
 $webs =  get-spsite -webapplication "http://www.yoursharepointURL.com"
 $feature = "YourFeatureName" #this might not be what you expect it to be, best to do get-spfeature | Select displayname
 
  Foreach ($oneweb in $webs)
  {
    write-host $oneweb
    $siteFeature = get-spfeature -site $oneweb | Where {$_.displayname -eq $feature}
    if ($siteFeature -eq $null)
    {
      Write-Host "Activating Site level Features at $oneweb" -foregroundcolor Yellow
      Enable-SPFeature -Identity $Feature -URL $oneweb.URL -Confirm:$False
    }
    else
    {
      Write-Host "Feature $feature is already activated on $oneweb" -foregroundcolor green
    }
  }

If you look at the simple logic, you’ll see you can run it more than once – and the second time you run it, it should display an all green list indicating that all the site collections already have the feature activated.

Powershell to test a URL against UAG rulesets

Many companies use Microsoft Forefront Universal Access Gateway (UAG) to publish sharepoint sites to the public internet.

We recently had a problem where office (word, excel, powerpoint) documents would not open through a sharepoint published site Via UAG in the office app on the end users home PC.

In UAG there’s a bunch of rules that match the URL in question via a regex.
We needed a quick way to test our URL against the regex in each and every rule so we knew which rules applied.

There currently isn’t a way to do that in UAG (there should be)
So as an alternate to doing these manually, I used the “Export rules” feature, then wrote the following powershell script to parse the exported file, gather the RegEx’s of each, and test the URL in question against each RegEx so you can see what rule is actually being applied.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# if you run from ISE and get a permissions error copy and paste everything to a new tab.
# or run get-executionpolicy (take note what it is) then run (as an administrator): set-executionpolicy unrestricted
#set theses two variables -
$ExportedRuleSetFile = get-content 'c:\PS\PRD_URLset.txt'
$URLtoFind = "/get/content/from/sharepoint.aspx"
Function FindAMatch($Rulefile, $URL)
{
	$table = New-Object system.Data.DataTable "RegExList"
	$col1 = New-Object system.Data.DataColumn Section,([string])
	$col2 = New-Object system.Data.DataColumn Name,([string])
	$col3 = New-Object system.Data.DataColumn RegEx,([string])
	$table.columns.add($col1)
	$table.columns.add($col2)
	$table.columns.add($col3)
 
	$row = $table.NewRow()
	$row.Section = "Section"
	$row.name = "Name"
	$row.RegEx = "Regex"
 
	foreach ($line in $Rulefile )
	{
		if ($line[0] -eq "[")
		{
			$table.Rows.add($row)
			$row = $table.NEwRow()
			$row.Section = $line
		}
		elseif ($line.substring(0,7) -eq "m_regex")
		{
			$row.RegEx = $line.substring(8)
		}
		elseif ($line.substring(0,7) -eq "m_name=")
		{
			$row.Name = $line.Substring(7)
		}
	}
	$table.Rows.add($row)
 
	write-host Note: this only searches SharePoint Rules
	# note the select statement is needed because many of the records don't have regex values
	foreach ($record in $table.select("name like 'SharePoint%'"))
	{
		if ($url -match $record.regex)
		{
			Write-host $url found in $record.name via regex matching $record.regex
		}
	}
} #end function
FindAMatch $ExportedRuleSetFile $URLtoFind

Sample output looks like this:

Note: this only searches SharePoint Rules
/get/content/from/sharepoint.aspx found in SharePoint14AAM_Rule1 via regex matching (/[^"#&*+:<>?\\{|}~]*)/?
/get/content/from/sharepoint.aspx found in SharePoint14AAM_Rule47 via regex matching (/[^"#&*+:<>?\\{|}~]*)*/[^"#&/:<>?\\{|}~]*\.aspx
/get/content/from/sharepoint.aspx found in SharePoint14AAM_Rule48 via regex matching /
/get/content/from/sharepoint.aspx found in SharePoint14AAM_Rule60 via regex matching (/[^"#&*+:<>?\\{|}~]*)/?

As a side note, we were able to pinpoint the rule that applied to our URL which made fixing it much easier!