SharePoint Snippets

 

Following along with my previous post about Powershell Snippets, here is my post for my own SharePoint Snippets, some of which are “PowerShelly.”

View SharePoint 2010 Developer Dashboard Setting:

[Microsoft.SharePoint.Administration.SPWebService]::ContentService.DeveloperDashboardSettings

Change SharePoint 2010 Developer Dashboard

(supports On,Off,OnDemand) (use single line)

[Microsoft.SharePoint.Administration.SPWebService]::
ContentService.DeveloperDashboardSettings.DisplayLevel = 
([Enum]::Parse([Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel], “Off”));
[Microsoft.SharePoint.Administration.SPWebService]::
ContentService.DeveloperDashboardSettings.Update()
Advertisements

Reliably Deploying SharePoint 2010 Taxonomies

One a recent project for Slalom Consulting, my employer, we had a project that made use of SharePoint 2010 Managed metadata including groups, term sets and terms. As we began to create new environments, one of the laborious tasks was to populate the Taxonomy Term Store using the term store manager page accessible via Central Administration or the related site collection (“_layouts/termstoremanager.aspx”). The terms are loaded into the Taxonomy Term Store via CSV file that adheres to a specific format that you can see via the url of your SharePoint Central Administration site: http://centraladminurl/_layouts/1033/ImportTermSet.csv

To manually import a file, you must first create group, then click on that group and chose “Import Term Set”:

image

You are then presented with a dialog box where you can select a CSV file that adheres to the required format to import:

image

This process is fine if you only have one or two terms to load but as your continue to build out a solution and have to do this process over and over again, it can be come tedious. The following is my PowerShell script that loops through all the .csv files in the same directory as the PowerShell script. The caution is the script deletes the terms each time, so any site columns you create from this will need to adjusted if you delete and recreate the term set. However, this is useful during setting up environments during the development process as you create site collections. Use with caution Smile.  I am also very much open to feedback on the PowerShell script and how to improve it.

try

{

 if(((Get-PSSnapin | foreach {$_.Name}) -contains "Microsoft.SharePoint.PowerShell") -eq $false)

 {

 Add-PSSnapIn Microsoft.SharePoint.PowerShell -ErrorAction Stop

 }

}

catch

{

 Write-Host -ForegroundColor "red" "This script only works on machines with SharePoint 2010 installed.`n"

 Exit

}

 

function Pause ($Message="Press any key to continue...")

 {

 # The ReadKey functionality is only supported at the console (not is the ISE)

 if (!$psISE)

 {

 Write-Host -NoNewLine $Message

 $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

 Write-Host ""

 }

 }

 

function AddCSVToTermSet([string] $termGroup, [string] $termSetCSVPath)

{

$termStore = $session.TermStores[$mmdServiceName]

if ($termStore.Groups[$termGroup] -eq $null) {

    $group = $termstore.CreateGroup($termGroup);

    $termStore.CommitAll() 

}

else {

    $group = $termStore.Groups[$termGroup]

}

# Import Taxonomy 

# Create an instance of ImportManager

$Importer = $termStore.GetImportManager()

$varImported = ""

$varMessages = ""

$reader = [System.IO.File]::OpenText($termSetCSVPath) 

 

# Syntax: ImportTermSet(TermGroup, TextReader, out isImported, out errorMessage)

$Importer.ImportTermSet($group ,$reader, ([REF] $varImported), ([REF] $varMessages))

}

 

$termGroup = "Location"

$centralAdminUrl = $(Get-spwebapplication -includecentraladministration | where {$_.IsAdministrationWebApplication} | Select-Object -Property Url).Url

$session = Get-SPTaxonomySession -site $centralAdminUrl

$mmdServiceName = $(((Get-SPFarm).ServiceProxies | Where {$_.TypeName -eq "Managed Metadata Web Service Proxy"}).ApplicationProxies | Select-Object -Property DisplayName).DisplayName

 

#delete all previous, 

#use with caution as any site solumns created with this will lose their relationship if the terms are deleted

 

$termStore = $session.TermStores[$mmdServiceName]

$termStore.Groups[$termGroup].TermSets | ForEach-Object {$_.Delete() }

$termStore.Groups[$termGroup].Delete()

$termStore.CommitAll() 

 

#process all CSV in same directory

$files = Get-ChildItem "." | Where {$_.extension -eq ".csv"}

Foreach ($csv in $files) {

    AddCSVToTermSet $termGroup $csv.FullName

}

 

Pause

SharePoint 2010 Web Applications

 

As a consultant, I get to help companies with various projects. A recent project included migrating a SharePoint 2010 site running on Beta 2 software (10.0.4536.1000) to RTM software (10.0.4762.1000). This presented many challenges as the original server build and configuration steps were long gone. My job was to document to necessary steps to migrate the content from the production site to a new site on RTM software. That story aside, a publishing site master page on the site injected an IFrame with a source of a .htm file that was stored within a document library. On the production site, everything worked fine. However, on the site I created from scratch, I continually got either a “Information Bar” warning or a download file dialog (based on my browser (IE 8.0) settings):

image

image

After Binging and Googleing with no easy answers , and based on the advice of a colleague, I pulled out Fiddler, which I should have done at the start. After finding the IFrame in the page and the subsequent browser get request, I saw the responsefor the file come back. At first glace, the response seemed fine. However, comparing it with the production site, the recreated site response headers had extra “stuff” in them. Here are the two response headers, the current production site first and the recreated site second in my favorite comparison software WinMerge:

image

image

Besides the date, time and various GUIDS, the only differences are the extra headers:

  • X-Content-Type-Options: nosniff
  • Content-Disposition: attachment; filename=filename.htm
  • X-Download-Options: noopen

Wikipedia-ing these gives a little detail to the first two of their purpose and the final one being defined on an IE 8 security blog:

Field name Description Example
X-Content-Type-Options[4] The only defined value, “nosniff”, prevents Internet Explorer from MIME-sniffing a response away from the declared content-type X-Content-Type-Options: nosniff
Content-Disposition An opportunity to raise a “File Download” dialogue box for a known MIME type

Content-Disposition: attachment; filename=fname.ext

X-Download-Options When the new X-Download-Options header is present with the value noopen, the user is prevented from opening a file download directly; instead, they must first save the file locally. When the locally saved file is later opened, it no longer executes in the security context of your site, helping to prevent script injection

X-Download-Options: noopen

The fact that the headers from the server are different even with the same browser shows that the server has some setting that is sending this “additional” headers.

Google-ing these headers produces some hits and the most documented one is:

http://blog.brainlitter.com/archive/2010/05/19/sharepoint-2010-treats-pdf-and-other-file-types-as-insecure.aspx

It turns out it is it is a setting on the Web Application from within Central Administration:

image

However, it does not list what file types generate this behavior, instead only listing “certain types of files”.

Now that I know the area of what is producing this behavior, lots of sites have also documented the solution  to my problem but I could not find them when I needed them Smile

Still to be determined is why “.htm” is blocked even though it is not in the blocked file extensions in Central Administration. Any takers?

The blocked file types extension in SharePoint Central Administration/Security/BlockedFileTypes does not list .htm as blocked.

Powershell confirmed it as well:

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

$wa = [Microsoft.SharePoint.Administration.Spwebapplication]::Lookup($URL)

$wa.GetType().GetProperty(“InternalWebFileExtensions”,$bindingFlags).GetValue($wa,$null)

$wa.GetType().GetProperty(“InternalWebFileExtensions”,$bindingFlags).GetValue($wa,$null)

Ideas?

SharePoint 2010, RemoveFieldRef and Inherits=”true”

I am brand new to the Visual Studio 2010 templates for SharePoint, having relied on the WSPBuilder toolkit in the past for all my previous SharePoint work. I created what I thought would be a simple ContentType definition inheriting from Item (0x01) using Visual Studio and this is what I got:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:   <!-- Parent ContentType: Item (0x01) -->
   4:   <ContentType ID="0x01005ac69ad99b164765a7fcb7610c5bfa92"
   5:                Name="SolutionPackage - ContentType1"
   6:                Group="Custom Content Types"
   7:                Description="My Content Type"
   8:                Inherits="TRUE"
   9:                Version="0">
  10:     <FieldRefs>
  11:     </FieldRefs>
  12:   </ContentType>
  13: </Elements>

I added two new fields to the FieldRefs element as well as one RemoveFieldRef to remove the title column as it did not really fit my scenario. I published to my SharePoint 2010 development environment and was bothered that my Title column was not removed. Here was what I published that did not immediately work:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:   <!-- Parent ContentType: Item (0x01) -->
   4:   <ContentType ID="0x01005ac69ad99b164765a7fcb7610c5bfa92"
   5:                Name="SolutionPackage - ContentType1"
   6:                Group="Custom Content Types"
   7:                Description="My Content Type"
   8:                Inherits="TRUE"
   9:                Version="0">
  10:     <FieldRefs>
  11:       <RemoveFieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title"/>
  12:       <FieldRef ID="{4c56a001-732d-4605-b7ac-1106de977439}" Name="PlantNames" DisplayName="Plant Names" />
  13:       <FieldRef ID="{e0e4af84-4013-4f43-a21b-b3862da37ce1}" Name="OperationsSection" DisplayName="Operations Section"/>
  14:     </FieldRefs>
  15:   </ContentType>
  16: </Elements>

 

After spending more time that I would expect to remove the title field, something which I had done many many times, I looked up on MSDN for the ContentType definition to see what I was missing:

http://msdn.microsoft.com/en-us/library/aa544268.aspx

What stand out now, is the Inherits="TRUE" section that is new to SharePoint 2010 foundation. If you look at the previous version on the ContentType definition for Windows SharePoint Services 3, you will that Inherits is not there:

http://msdn.microsoft.com/en-us/library/aa544268(v=office.12).aspx.

Inherits is defined as:

Inherits
Optional Boolean. The value of this attribute determines whether the content type inherits fields from its parent content type when it is created.

If Inherits is TRUE, the child content type inherits all fields that are in the parent, including fields that users have added.

If Inherits is FALSE or absent and the parent content type is a built-in type, the child content type inherits only the fields that were in the parent content type when SharePoint Foundation was installed. The child content type does not have any fields that users have added to the parent content type.

If Inherits is FALSE or absent and the parent content type was provisioned by a sandboxed solution, the child does not inherit any fields from the parent.

So, to remove the Title field using the RemoveFieldRef element, you must also remove the Inherits attribute entirely (or set Inherits=”False”) in the content type definition:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:   <!-- Parent ContentType: Item (0x01) -->
   4:   <ContentType ID="0x01005ac69ad99b164765a7fcb7610c5bfa92"
   5:                Name="SolutionPackage - ContentType1"
   6:                Group="Custom Content Types"
   7:                Description="My Content Type"
   8:                Inherits="False"
   9:                Version="0">
  10:     <FieldRefs>
  11:       <RemoveFieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title"/>
  12:       <FieldRef ID="{4c56a001-732d-4605-b7ac-1106de977439}" Name="PlantNames" DisplayName="Plant Names" />
  13:       <FieldRef ID="{e0e4af84-4013-4f43-a21b-b3862da37ce1}" Name="OperationsSection" DisplayName="Operations Section"/>
  14:     </FieldRefs>
  15:   </ContentType>
  16: </Elements>

(Always read MSDN when in doubt!)