SharePoint Dragons

Nikander & Margriet on SharePoint

Tag Archives: Powershell

Where are the SharePoint 2013 Search Suggestions?

What to do when search suggestions don’t show up? Run the “prepare query suggestions” timer job!

If you set up search suggestions (as described in http://technet.microsoft.com/en-us/library/jj721441.aspx ) you may notice that no suggestions drop down from the search bar. That makes sense, because they only appear after the “prepare query suggestion” timer job has run. You can force this via PowerShell like this:

Start-SPTimerJob -Identity “prepare query suggestions”

We’ve added the following TechNet Wiki page that describes how to do that: http://social.technet.microsoft.com/wiki/contents/articles/16640.sharepoint-2013-tips-for-troubleshooting-search-suggestions.aspx It will contain any updates to this tip.

Credits

Based on the content of: http://social.technet.microsoft.com/Forums/en-US/sharepointsearch/thread/33265dfd-1316-4c57-92b9-31f0d8f0078c

Add a multivalued taxonomy field to the default view in a custom list thru PowerShell

The title says it all, really. There was one particularly tricky part, where the view needed to be stored in a separate variable, like so:

$view = $myCustomList.DefaultView

Because $myCustomList.DefaultView resulted in the creation of a new View object every time, causing any changes you made to a previous object instance to be lost. The code is here, and it requires you to set up a managed metadata service instance (ours is called Managed Metadata Service), the following blog post can help you with that: http://chakkaradeep.com/index.php/sharepoint-2010-content-type-hubs-publish-and-subscribe-to-content-types/

$TestSiteUrl = “http://demosrv/sites/Wilmie”
$Web = Get-SPWeb -identity $TestSiteUrl

#Dev: remove list and create it every time anew
$List = $Web.Lists[“CustList”]
$List.Delete()

$listTemplate = [Microsoft.SharePoint.SPListTemplateType]::GenericList
$lstId = $Web.Lists.Add(“CustList”,”Cust Descr”,$listTemplate)
write-host “list ” $ListName ” created successfully” $ListName -ForegroundColor Green  

$myCustomList = $Web.Lists[“CustList”]

#Example simple text field (without taxonomy field, this makes testing easier)
#$firstNameColXml = “<Field Type=’Text’ DisplayName=’FirstName’ Required=’TRUE’ MaxLength=’255′ StaticName=’FirstName’ Name=’FirstName’ />”
#$myCustomList.Fields.AddFieldAsXml($firstNameColXml,$true, [Microsoft.SharePoint.SPAddFieldOptions]::AddFieldToDefaultView)  
#$myCustomList.Update()

$taxonomySite = Get-SPSite “http://demosrv:1971″
$taxonomySession = Get-SPTaxonomySession -site $taxonomySite
$termStore = $taxonomySession.TermStores[“Managed Metadata Service”]
write-host “Connection made with term store -“$termStore.Name
$termStoreGroup = $termStore.Groups[“MyTermStoreGroup”];
$termSet = $termStoreGroup.TermSets[“MyTermSet”];

Add-Type -Path ‘C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.SharePoint.Taxonomy.dll’
$taxonomyField = [Microsoft.SharePoint.Taxonomy.TaxonomyField] $myCustomList.Fields.CreateNewField(“TaxonomyFieldTypeMulti”, “Location”)
$taxonomyField.Required = $false
$taxonomyField.StaticName = “my_static_name”
$taxonomyField.SspId = $termStore.Id
$taxonomyField.TermSetId = $termSet.Id
$myCustomList.Fields.Add($taxonomyField)
$myCustomList.Update()
Write-Host “Added field ” $taxonomyField.Title ” to list ” $myCustomList.Title -ForegroundColor Green

$field = $myCustomList.Fields[“Location”];
# PLEASE NOTE: It’s important to store the view in a variable, because calling list.DefaultView results in the creation of a NEW view object every time,
# if you do that, new columns will NEVER be added succesfully to the view.
$view = $myCustomList.DefaultView
$view.ViewFields.Add($field)
$view.Update()
$myCustomList.Update()

Write-Host “Added field ” $field.Title ” to default view” -ForegroundColor Green

Write-Host “Finished set metadata”

Setting default content type column values for a library via PowerShell

Setting default column values for content type columns, the equivalent of [Document Library] > Document Library Settings > Column Default value settings, was surprisingly hard to build in PowerShell. The main gotcha has to do with the fact that you can’t do this via the SPContentType type, instead, you have to do it via the more obscure MetadataDefaults type, located in the Microsoft.Office.DocumentManagement.dll. Here’s the script:

Cls
Write-Host “Initializing SharePoint PowerShell Environment”

$SnapIn = “Microsoft.SharePoint.PowerShell”
if ( get-pssnapin $SnapIn -ea “silentlycontinue”)
{
  Write-Host “Remove SharePoint snap-in” 
  remove-pssnapin $SnapIn
}
if ( get-pssnapin $SnapIn -registered -ea “silentlycontinue”)
{
  Write-Host “Add SharePoint snap-in” 
  add-pssnapin $SnapIn
}

Write-Host “Start Setting default value for content type column”

Add-Type -Path ‘c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.Office.DocumentManagement.dll’
$ProjectWeb = Get-SPWeb -Identity “http://demosrv/sites/Wilmie”
$List = $ProjectWeb.Lists[“1. Project Management”]

$ContentType = $List.ContentTypes[“TestContentType”]

$ColumnDefaults = New-Object -TypeName Microsoft.Office.DocumentManagement.MetadataDefaults $List                 
$ColumnDefaults.SetFieldDefault($List.RootFolder, “TestColumn”, “TestValue from PS”)
$ColumnDefaults.Update()

Write-Host “End setting default value”

Getting values of SharePoint Hyperlink and Person or Group columns

The next PS script shows how to do it:

$ProjectWeb = Get-SPWeb -Identity $ProjectWebName

foreach ($Item in $ProjectList.Items)
{
$SiteCollLink = New-Object Microsoft.Sharepoint.SPFieldUrlValue($Item[“SiteCollectionURL”])
$Url = $SiteCollLink.Url

$Owner = New-Object Microsoft.Sharepoint.SPFieldUserValue($ProjectWeb, $Item[“Owner”])
$OwnerName = $Owner.User.LoginName
$OwnerEmail = $Owner.User.Email
}

 

Please Note SiteCollectionURL is the name of a Hyperlink column, Owner is the name of a Person or Group column.

Adding users and groups to SharePoint 2010 Lists via PowerShell Braindump

A braindump follows the train of thought of a person solving a problem. This process allows you to optimize through processes and reasoning patterns, and as such can be a useful and entertaining exercise. What follows is the braindump of adding users and groups to SharePoint 2010 Lists via PowerShell.

Let’s start by firing the SharePoint 2010 Management Shell and see what I can learn about SharePoint related PS commands.

I know that such commands contain “sp” in it, so I’ll do:

help *sp*.

Ah, that’s too much. I assume that I need to retrieve a list before I can add permissions, but in order to do that I’ll probably need to get hold of the correct site collection and site first. In that case, I’ll just go ahead and look for cmdlets that have get in it. I do:

help get-sp*

There they are, on the first page, Get-SPSite and Get-SPWeb. They look promising. Let’s see if I can get a site directly by using Get-SPWeb. But in order to do that, I first need to find out how to use it. I want to read the documentation, so I do:

help get-spweb -full

Hmm, if I take a look at the -Identity parameter, it seems to be enough to get hold of a specific site. Let’s try it.

get-spweb http://moon

Ok, got it. That wasn’t too bad. I notice that now i have an SPWeb object. Now, let’s see what I can do with a site, there should be a way to get a specific list. I do:

get-spweb http://moon | gm | more

Either the GetList or the GetListFromUrl method should help me to get a list. Let’s switch to MSDN at http://msdn.microsoft.com and look for:

spweb getlist

As it turns out, this method needs a server-relative URL for a list, for example, /sites/MySiteCollection/Lists/Announcements. That’s good enough for me. Once I have an SPList object, I’ll see what I can do with that. I’ll change the PS code a bit, so that I’ll have references to the various objects. I do:

$web = get-spweb http://moon
$list = $web.getlist(“/Lists/TheTestList”)

Let’s see that I really got it and try:

$list.Title

Fine, let’s find out about the list object then. I do:

$list | gm | more

Hmm, things are getting a little bit more complicated. Time to fire up Windows PowerShell ISE and work from there. That won’t do me any good unless I load the SharePoint PS snap in first. So, I do:

$snapIn = “Microsoft.SharePoint.PowerShell”

if ( get-pssnapin $snapIn -ea “silentlycontinue”)
{
  remove-pssnapin $snapIn
}

if ( get-pssnapin $snapIn -registered -ea “silentlycontinue”)
{
  add-pssnapin $snapIn
}

$web = get-spweb http://moon
$list = $web.getlist(“/Lists/TheTestList”)

The traditional PowerShell approach is getting too cumbersome by now. Instead of continuing going down this road, let’s find some C# code which does what I want and convert it to PowerShell.

$snapIn = “Microsoft.SharePoint.PowerShell”

Write-Host “Initializing SharePoint PowerShell Environment”
if ( get-pssnapin $snapIn -ea “silentlycontinue”)
{
  Write-Host “Remove SharePoint snap-in”
  remove-pssnapin $snapIn
}

if ( get-pssnapin $snapIn -registered -ea “silentlycontinue”)
{
  Write-Host “Add SharePoint snap-in”
  add-pssnapin $snapIn
}

Write-Host “Get web”
$web = get-spweb http://moon
Write-Host “Get list”
$list = $web.getlist(“/Lists/TheTestList”)

#Reset permissions
Write-Host “Reset to original security settings”
$list.BreakRoleInheritance($False)
$list.ResetRoleInheritance()
Write-Host “Break role inheritance”
$list.BreakRoleInheritance($True)

# Remove all current assignments.
Write-Host “Remove all Role assignments”
Write-Host “Count:” $list.RoleAssignments.Count
while ($list.RoleAssignments.Count -gt 0)
{
  Write-Host “Removing a specific assignment for” $list.RoleAssignments[0].Member.Name
  $list.RoleAssignments.Remove(0)
}
Write-Host “Count:” $list.RoleAssignments.Count

$userName = “lc\Administrator”
$user = $web.EnsureUser($userName)
Write-Host “user:” $user
$userRole = New-Object Microsoft.SharePoint.SPRoleAssignment($user)
$builtInRole = $web.RoleDefinitions[“Read”]
Write-Host “Built in role” $builtInRole.Name

$userRole.RoleDefinitionBindings.Add($builtInRole)
$list.RoleAssignments.Add($userRole)

$groupName = “SharePoint Dragons Owners”
$group = $web.SiteGroups[$groupName]
Write-Host “Group:” $group
$groupRole = New-Object Microsoft.SharePoint.SPRoleAssignment($group)
$groupRole.RoleDefinitionBindings.Add($builtInRole)
$list.RoleAssignments.Add($groupRole)

Write-Host “Finished”

Ah, there’s my proof of concept that I can later convert to Enterprise-level code. Now, let’s write that blog post.

Appreciating a simple idea about running PowerShell Scripts from SharePoint

It’s a simple idea to want to be able to execute PowerShell scripts from code, as you can see in http://social.technet.microsoft.com/Forums/en-US/sharepointdevelopment/thread/318429d9-fc63-479b-a20a-62883c9132fa. The code is something similar to this:

PowerShell ps = PowerShell.Create();

string scriptText = “Add-PSSnapin Microsoft.SharePoint.Powershell Enable-SPFeature -Identity PublishingSite -URL ” + siteAddress + ” -Force”;

Runspace runspace = RunspaceFactory.CreateRunspace();

runspace.Open();

Pipeline pipeline = runspace.CreatePipeline();

pipeline.Commands.AddScript(scriptText);

pipeline.Commands.Add(“Out-String”);

Collection<PSObject> results = pipeline.Invoke();

runspace.Close();

StringBuilder stringBuilder = new StringBuilder();

foreach (PSObject obj in results)

{

stringBuilder.AppendLine(obj.ToString());

}

return stringBuilder.ToString();

}

In the blog post http://blog.karstein-consulting.com/2011/08/04/sharepoint-powershell-timer-jobs-run-powershell-scripts-in-sharepoint-timer-service-context/ this idea is taken to the next level by allowing you to run PowerShell scripts in the SharePoint Timer Service context. Really useful, and elegantly done!

Getting the right set of permissions when creating a custom permission level in PowerShell

Despite all its power and flexibility, developing PowerShell scripts feels like a dev experience that could be had 15 years ago. Often, we find ourselves creating prototypes in VS.NET first, before diving into the murky waters of visual PowerShell editors. Having that off our chest, suppose you’re creating a PS script that creates a new SharePoint permission level. The code is not too hard, something like:

$CustomPermissions = New-Object Microsoft.SharePoint.SPRoleDefinition
$CustomPermissions.Name = “TheName”
$CustomPermissions.Description=”A Descr”
$CustomPermissions.BasePermissions=”ViewListItems, AddListItems, EditListItems, OpenItems, ViewVersions, ManagePersonalViews, ViewFormPages, Open, ViewPages, CreateSSCSite, etc., etc.”
$RootWeb.RoleDefinitions.Add($CustomPermissions);

Now, what’s the easiest way to get to the permission mask you want? We do this:

  1. Create it first via the SharePoint UI (Site Actions > Site Settings > Site Permissions > Permission Levels).
  2. Create a C# program in Visual Studio that loops thru all permission levels until you find the one you created.
  3. Add the object holding the permission level to the QuickWatch window.
  4. Open the XML property using the XML visualizer.
  5. Copy the value of the BasePermissions attribute and use that string value in your PS script.

The C# code (run from a C# Console Application) looks like this:

using (SPSite site = new SPSite(“http://moon”))
{
  using (var web = site.OpenWeb())
  {
    foreach (SPRoleDefinition roleDef in web.RoleDefinitions)
    {
      Console.WriteLine(roleDef.Name);
    }

}

Silverlight PowerShell Command Builder

We forgot all about this tool: a Silverlight app that allows you to build PowerShell commands for SharePoint 2010: http://www.microsoft.com/resources/TechNet/en-us/Office/media/WindowsPowerShell/WindowsPowerShellCommandBuilder.html It’s real easy to use and quite cool, although it actually goes against our principles. Trying to build PS cmds this way will actually prevent you from getting to learn PowerShell: not a good thing!

Can’t use PowerShell to create a site using a site template

Just stumbled across this. It’s not possible to use PowerShell to create a site based on a site template.

In this example, we’ve created a site template called “mytemplate” based on the “STS” template. Normally, you can use the new-spweb cmdlet and specify a template like so:

new-spweb http://moon/sites/sc1/autosite1 -template “mytemplate”

(Or add –whatif to the end if you’re getting cold feet).The –tempate parameter accepts a piped spwebtemplate object, which can be retrieved via:

Get-SPWebTemplate | more

As you will see, a site template saved in the site collection solution catalog won’t show up here. As an alternative, you can try to establish the template that was used to create an existing web site, like so (please note, we’ve created a site called “myinstance” using the “mytemplate” site template:

$web = get-spweb http://moon/sites/sc1/myinstance

write-host “Web Template:” $web.WebTemplate ” | Web Template ID:” $web.WebTemplateId

$web.Dispose()

If you experiment with this, you will find that the web template it still the underlying parent of the saved template. In my case “mytemplate” was based on the “STS” template, so that’s still the one that is actually the web template of “myinstance”.

PowerShell script for monitoring SharePoint WFE’s and SQL Server back-ends

Choosing, and automating the monitoring of, the correct set of performance counters for monitoring SharePoint WFE’s and back-ends is a daunting task, and this is my attempt:

http://gallery.technet.microsoft.com/PowerShell-script-for-59cf3f70