Skip Ribbon Commands
Skip to main content

Kevin Hughes

August 15
SharePoint 2013 Promoted Links in Vertical

As a followup to my earlier blog on Display Promoted Links on Multiple Rows, I wanted to let you in on a couple other tidibits about the Promoted Links CSS. The basic styles in that post will take effect for all the Promoted Links web parts on a page. If you put it in a style sheet, then it will make that happen for the entire site.

But, what if you wanted to make sure they display vertically? Say in a right-hand column...maybe for important links or advertisements? Microsoft never gave us that option...but maybe they will...someday. Or maybe they knew ​we could style it and just never announced it.

In any case, if you constrain the width to 170px instead of the 100% from the earlier post, then you will get vertical columns.

     <style type="text/css">
           .ms-promlink-body {width:170px}
           .ms-promlink-header {visibility:hidden}
     < /style>

Or what if you wanted to place two Promoted Links web parts on the same page and display one horizontally and one vertically? Well, we're going to help you out. Still using our same CSS we just add the web part's ID, as indicated by the #.

     <style type="text/css">
          #msozonecell_webpartwpq6 .ms-promlink-body {width: 170px }
          #msozonecell_webpartwpq6 .ms-promlink-header {visibility:hidden}
     </style> Promoted Links web parts are even more useful.

Have fun!

August 11
Display Promoted Links on Multiple Rows

I have seen many people struggle with using the Promoted Links list in SharePoint 2013. This is a great way to add a small bit of pizazz to an otherwise boring list of links and it is Out-of-the-Box. J

But, if you put too many links into the list, the tiles will still only display on a single row. This will cause horizontal scroll buttons to appear between your tiles and the web part chrome. And while this does allow for a variety of screen sizes (you just see fewer tiles without scrolling left/right) it no longer looks as "cool" as you might expect. If you're looking for more of a "responsive design" feel then you might be tempted to create extra metadata columns in your Promoted Links list to be able to categorize and create multiple filtered Tile views. While this can be a workaround, it is clunky and still doesn't look "cool".

I have seen a single jQuery solution from Creative SharePoint ( it seems to frighten some even though it works well enough, but you do have to edit the script if you want to change how many tiles display in a single row before the break. So I get it. I have also found that the script only works reliably, all the time, for all users, when it is uploaded to the ~sitecollection/_catalogs/masterpage/Display Templates/ folder. If this is the case in your environment and you have permissions to place a file there, go for it.

If, however, you aren't comfy with jQuery, want a true responsive design look & feel or just want a solution you can use even if all you have permissions for is editing a single page…then consider handling this with custom styling. I've recently been trying to dig deep into this area of SharePoint and found a solution that works every time for every user.

Basically we use CSS to change set the width property of the Promoted Links web parts to 100%. This will expand the web part to take up all the horizontal space it is allowed in its location (page, rich text field, web part zone, etc.). Then when it has placed as many tiles as it can in this space it will automatically start a new row. If you have enough tiles, you may have 3, 4 or more rows this way, depending on your screen resolution and window sizing. Unfortunately, doing only this will still get us the horizontal scroll buttons. And you'll have some unexpected behavior in this situation.

So, we set another property to hide the promoted links header and the scroll buttons go away.

If you already have a custom style sheet you are calling in your site, then place the following in that custom .css file.

.ms-promlink-body {width:100%}
.ms-promlink-header {visibility:hidden}

Or, if you like, or only want this behavior on a single page, add a Script Editor Web Part to the page and put the following in the source.

<style type="text/css">
.ms-promlink-body {width:100%}
.ms-promlink-header {visibility:hidden}
< /style>

Now you have a nice clean look that is truly responsive to screen/window sizing.

Have fun. Keep Sharing.


December 16
Kerberos Tokens

It seems that more and more my clients are coming up against issues that keep them from implementing pass-through authentication via Kerberos protocols. Most often it seems the issue is in regards to authentication tokens that are too large - stemming from an Active Directory that is out of control.

This article is to summarize information from a variety of sources and my own experience to try to assist in keeping Large Token Size something that can be mitigated in your own environment.

Kerberos Primer

The Kerberos protocol is a secure protocol that supports ticketing authentication. A Kerberos authentication server grants a ticket in response to a client computer authentication request, if the request contains valid user credentials and a valid Service Principal Name (SPN). The client computer then uses the ticket to access network resources. To enable Kerberos authentication, the client and server computers must have a trusted connection to the domain Key Distribution Center (KDC). The KDC distributes shared secret keys to enable encryption. The client and server computers must also be able to access Active Directory directory services. For Active Directory, the forest root domain is the center of Kerberos authentication referrals.
Kerberos allows a client’s identity to be impersonated by a service to allow the impersonating service to “pass” that identity to other network services on the client’s behalf. NTLM does not allow this delegation.

Kerberos enabled services can delegate identity multiple times across multiple services and multiple hops. As an identity travels from service to service, the delegation method can change from Basic to Constrained but not in reverse. This is an important design detail to understand: if a backend service requires basic delegation (for instance to delegate across a domain boundary), all services in front of the backend service must use basic delegation. If any front end service uses constrained delegation, the back service cannot change the constrained token into an unconstrained token to cross domain boundary.
Protocol transition allows a Kerberos enabled authenticating service (front end service) to convert a non-Kerberos identity into a Kerberos identity that can be delegated to other Kerberos enabled services (back end service). Protocol transition requires Kerberos constrained delegation and therefore protocol transitioned identities cannot cross domain boundaries.
Constrained Delegation is required for services which leverage the Claims to Windows Token Service. Constrained delegation is required to allow protocol transition to convert claims to windows tokens.


Users may be members of many Active Directory groups, which can increase the size of their Kerberos tickets. If the tickets grow too large, Kerberos authentication can fail. It was reported that some Active Directory users were members of 1400+ Active Directory groups.

The user cannot authenticate because the Kerberos token that is generated during authentication attempts has a fixed maximum size. Transports such as remote procedure call (RPC) and HTTP rely on the MaxTokenSize value when they allocate buffers for authentication.
Kerberos uses the Privilege Attribute Certificate (PAC) field of the Kerberos packet to transport Active Directory Group membership. If there are many group memberships for the user, and if there are many claims for the user or the device that is being used, these fields can occupy lots of space in the packet. If a user is a member of more than 120 groups, the buffer that is determined by the MaxTokenSize value is not large enough. Therefore, users cannot authenticate, and they may receive an "out of memory" error message.
The behavior caused is that a user may be prompted for credentials repeatedly when attempting to access data external to SharePoint. Instead of an actual prompt, the user’s credentials may be presented multiple times via the Kerberos protocol and still may fail authentication. In many cases, Windows NTLM authentication works as expected.
This problem can occur even though the credentials you provide are valid and can be utilized to obtain access to the same computer through direct access. However, the Wininet.dll file may not allocate a sufficient buffer for containing the user's Kerberos token.
Token Size Calculation
MaxTokenSize value:
TokenSize = 1200 + 40d + 8s
This formula uses the following values:
·         d: The number of domain local groups a user is a member of plus the number of universal groups outside the user's account domain that the user is a member of plus the number of groups represented in security ID (SID) history.
·         s: The number of security global groups that a user is a member of plus the number of universal groups in a user's account domain that the user is a member of.
·         1200: The estimated value for ticket overhead. This value can vary, depending on factors such as DNS domain name length, client name, and other factors.
It was noted that the MaxTokenSize registry entry for each of the SharePoint farm servers had been increased to 65535.
Known issues for token size
1.       The Local Security Authority (LSA) service generates the user Access Token from this SID buffer. The hard-coded limit of customer definable SIDs for this token is 1,015. If you use "trusted for delegation" accounts, (Which is the case when SharePoint is using pass-through authentication via Kerberos protocol) the buffer requirement for each SID may be doubled. In these scenarios, you can only store approximately 800 Domain Local Group SIDs when a MaxTokenSize value of 64K is used.
2.       The Internet Information Server (IIS) uses a reduced request buffer size to mitigate a denial of service attack vector of 64 KB. However, a Kerberos Ticket in an HTTP request is encoded as Base64 (six bits expanded to eight bits). Additionally, and the Kerberos Ticket is using 133 percent of its original size. Therefore, when the maximum buffer size is 64 KB in IIS, 48 KB of a Kerberos Ticket can be used.
If you set the MaxTokenSize registry entry to a value that is larger than 48000, and the buffer space is used for SIDs, an IIS error may occur. However, if you set the MaxTokenSize registry entry to 48000, a Kerberos error may occur.

November 09
Gearing up for SPC12

The Microsoft SharePoint Conference 2012 is beginning in just a couple of days. I am attending and am looking forward to the break from work. However, I don't feel a part of the SP Community as I did for SPC09. Since taking this consulting job, I've had little time for user groups, SharePoint Saturdays or other conferences. I don't have Twitter access from most client sites, so can't keep up on the daily topics. And while I used to blog about all sorts of SharePoint issues, I find that what I want to blog about now is part of company intellectual property so always am walking a thin line when I do post a new blog.

There will be some familiar faces – familiar to me anyway – at SPC12. And perhaps some will even be friendly. This conference is supposed to be huge, so I don't envision having a lot of "face" time with individuals.

I've filled my daily schedule with educational sessions and left little time for running around the Exhibitor floor. I have volunteered to spend some time in the Community Hub and maybe that will be fun. I imagine the evenings will be filled to overflowing with people trying to make connections and push the envelope of propriety just because they are in Las Vegas and feel they can get a bit wild. The Bon Jovi concert should be fun…at least the music should be good.

For all the organized fun, the training, and the throngs of people – it will likely be a time of finding out just how much the community has moved on without me over the past three years. Not that even my ego would be big enough to think that I was essential, but perhaps at least a welcome part.

So, I journey this weekend to Las Vegas with mixed feelings. Maybe by the end of the week there will be more good memories than blah or bad.

See you in Vegas!

February 22
Send Calendar Event Email to Outlook Calendar

I have had many instances where users wanted to be able to not only see a SharePoint calendar in MS Outlook, but also wanted the ability to add an event in a SharePoint calendar to their own personal calendar.

I'll leave the interface for making this happen up to you, but here is the description of the mechanics of a workflow that will achieve this - either making it automatic or a choice.
In a workflow, you can automatically send an email to the user, and then within the email, there can be a link that will add the item to their own personal calendar.

How to obtain this link? Well, open up any calendar item, and right-click on "Export event", and copy that URL so that you can use it. Then, you dissect the URL...
See where it says ID=8 in there? Well, 8 is the list item's ID number. So, in the URL within your email, just replace that number with the lookup or variable that represents that ID field. You can pretty it up by adding HTML href encoding if you wish.
Then, when users receive the email, they can simply click that link to be prompted to add the item to their calendars.


It's that easy.​

November 04
How Security Affects What You Can See in SharePoint

SharePoint security can often be the subject of many a long day of planning, implementing and/or troubleshooting. And as more companies become security-conscious, having the right security in your SharePoint sites is essential to insuring a smoothly running collaborative environment.

This is the first installment of a series on SharePoint security. It is written for the end-user and the site administrator alike. In future installments we will explore the topics of permissions levels, SharePoint groups vs. Active Directory groups, and permissions inheritance.

Anyone that has navigated around Microsoft SharePoint sites shall have noticed that they have different options available to them on different sites or even different locations within the same site. And perhaps even the Help feature was not enough as the instructions referred to menu options that you just could not see. This is not an attempt to frustrate.

SharePoint only shows you the sites, site content, and menu options to which you have been granted permissions to see or successfully use. This is referred to as a security trimmed user interface (UI).

SharePoint security can be assigned to allow actions through an entire site, or fine-tuned to have different permissions on each list or library in the site or even each document in a library. Your permissions can differ between sites and can differ between the content on the same site, such as: lists, libraries, items in lists, and files in libraries. As such, menu options you have on one site, library or item may not be available in a different location.

Following are a couple of examples to help show how a security trimmed UI affects users with different permissions for a SharePoint site and its content. The examples assume the default installation of a SharePoint site and its content, your site may have different menu options.

Site Actions Menu

You may or may not have seen the Site Actions button in the upper corner of a SharePoint site. The Site Actions menu contains options that potentially affect the entire site by adding additional content or changing site settings. Here are two examples of what options are displayed when the Site Actions menu button is clicked. The menu options vary depending on the features active within the SharePoint site and the permissions of the user that selects the menu. Assuming a typical site with typical default features active, we have the following example.


Site Owner Menu

Figure 1 - Site Owner

Site Member Menu

Figure 2 - Site Member

When William, the site administrator for Sales, clicks the Site Actions menu on the Sales site, the options available to him are represented in Figure 1 – Site Owner. William has permissions to perform all of these options.

William is a member of the default Site Owners group for the Sales site. The Site Owners group has the Full Control permission level for the site. This is a common permission level for a person who manages a SharePoint site. Users with the Full Control permission level can do almost anything they want to a site and its content.

When Elizabeth, a member of the Sales team, clicks the Site Actions menu on the Sales site, the options available to her are represented in Figure 2 – Site Member. Elizabeth has permissions to perform all of these options.

Any options in the Site Actions menu that would allow editing the site settings or structure are not available for Elizabeth, like they were for William. Elizabeth has the Contribute permission level, which isn't sufficient to perform actions such as create sites or document libraries, change site settings or edit with SharePoint Designer, so the menu options are not displayed for her.

Elizabeth is a member of the default Site Members group for the Sales site. The Site Members group has the Contribute permission level for the site. This is a common permission level for people who add, edit, and delete content on a SharePoint site. They have no permissions to change the overall layout of the site, site settings or site security.

When Louis, an accountant in the company, visits the Sales site, the Site Actions menu is not displayed for him.

Louis is a member of the default Site Visitors group for the Sales site. The Site Visitors group has the Read permission level for the site. This is a common permission level for people who need to read content on a site but not make any changes to it. The Read permission level isn't sufficient to perform actions that change the entire site, so the Site Actions menu is not displayed for him.

Library Ribbon

William, from the preceding example, goes to the Shared Documents library of the Sales site. Here are the Document options available to him in the ribbon menu. William has permissions to perform all of the options listed in the menus. * You may not see identical menu options; they also depend on the features of your SharePoint environment.

Figure 3 – Site Owner Documents Menu

And if William selects the Library menu, he will have the following Ribbon menu available to him.

Figure 4 - Site Owner Library Menu

Elizabeth goes to the same library as William. Elizabeth has the Contribute permission level. With this permission, Elizabeth has almost all the same abilities for documents in a library as a site owner as can be seen in Figure 5.

Figure 5 - Site Member Documents Menu

However, since the Contribute permission level has no rights to change any of the Document Library settings, any options on the Library ribbon menu that would allow such editing are not available. Elizabeth's Library options are limited to those which pertain to different ways to view the library, but not making any changes to it.

Figure 6 - Member Library Menu

Louis goes to the same library as William. As a site visitor Louis has the Read permission level, which does not allow him to add or edit document in the library, so few Ribbon menu options are available to him. These basically allow Louis to open the document, view its properties or download a copy of the document. No options that allow any changes or creation of new content are available.

Figure 7 - Visitor Document Menu

Finally, when Louis chooses the Library ribbon menu, his options as a visitor with Read permissions are even more limited than Elizabeth's.

Figure 8 - Visitor Library Menu

Any ability to view the library in a different manner mostly rely on doing so in external applications. Louis cannot even create a customized personal view of the Library.

As before, the options which actually display on your ribbon menus may differ due to different features being active in your site(s).

In this article, we have explored the reasons behind differences in menus and options based on the permissions assigned to different users of a SharePoint site. In future articles in this series we will delve deeper into SharePoint security with topics aimed more for site administrators in hopes of demystifying security and assisting them to create their own security-trimmed collaborative environment.

October 07
Updating Quick Launch Links via PowerShell

I have often had clients that had entered the same information on multiple SharePoint sites. In this client's case, they had created a manual entry in their Quick Launch and given it an absolute URL to point to a custom list (Named "Links" ) within that site. They then used this site as a template, which meant this absolute URL was propagated through hundreds of sites. And then it came time to change the URL as their FQDN was changing and the old one would no longer work.

So, instead of hunting through hundreds of sites to update this one Navigation item, I came up with this little script in PowerShell. I'll show the script then explain it.

$site = Get-SPSite

$site | get-spweb -limit all | foreach-object{

$webURL = $_.url

$web = Get-SPWeb $webURL

$NewURL = $WebURL + "/lists/links/allitems.aspx"

$navigationNodes = $web.Navigation.QuickLaunch


ForEach ($Node in $NavigationNodes)



     if($node.Title -eq "Lists")



        $PreviousChild = $node.children | where {$_.Title -eq "Tasks"}

        $childnode = $node.children | where {$_.Title -eq "Links"}


        If($Childnode -eq ""){continue}    

        [Microsoft.SharePoint.Publishing.Navigation.SPNavigationSiteMapNode]::UpdateSPNavigationNode($ChildNode, $PreviousChild, "Links", $NewURL, "", "", "", $false)








The intent of this script is:

  1. Iterate through all the sites in a site collection
  2. Find entries in the Quick Launch menu that equal "Links"
  3. Update the URL for that entry with the information constructed in the script.

First we identify the site collection. Then we find the site collection's current URL property and append it to the path to create our new URL ($NewURL).

Then we find all the sub-sites (webs) within that site collection. We step through each web and look at the Quick Launch menu in each web. Then for each Navigational element (node) in the Quick Launch menu, we look at it to find the heading of "Lists". Then we look at all the child navigational elements under "Lists" looking for on named "Links" ($Childnode). Since we're going to use the UpdateSPNavigationNode method to change our URL, the entry is actually re-created – effectively making a new entry. So we need to identify the navigational item we wish our new "Links" entry to follow ($PreviousChild).

We allow for the possibility that a site might not have a "Links" entry in the "Lists" section. If not, the script will throw an error on the UpdateSPNavigationNode method as $ChildNode will be kinda Null. (Kinda null because there will be no node value entered into the $childnode variable – but, it will have a blank value of "". So we can't use $null.)

We've mentioned it and looked at it, now let's tell you what the UpdateSPNavigationNode method will be doing for us. The C# syntax is:

public static SPNavigationNode UpdateSPNavigationNode(

    SPNavigationNode node,

    SPNavigationNode previous,

    string name,

    string url,

    string description,

    string target,

    string audience,

    bool forceCreate


This means our first value is the SPNavigationNode value of our "Links" item. Next is the SPNavigationNode value of the "Tasks" item, which our new "Links" will come behind. Followed by the name that will be displayed "Links", the URL we created ($NewURL). The description, target, and audience are not required, but we must allow for their space, hence blank values of "". Finally the forceCreate property which is either $false (default) or $true. If left to $false, the properties of the navigation element will be updated. Remember, though, that since we are changing the URL, we will be re-creating this navigation entry anyway, so go ahead and leave it $false.

Then we step on to the next sub-site and do it all over again.

With each successful update, you will see a set of properties display in the PowerShell window. Setting other properties is a whole other lesson.

Good luck! And keep sharing!


August 25
SharePoint 2010 Certification

I finally broke down and decided to take the 70-667 (TS) and 70-668 (PRO) Microsoft SharePoint 2010 certification tests. I looked over the MOC for a couple of days and then scheduled the tests back to back last Wednesday.

I didn't really find them that difficult, but didn't ace them either. I did note that the MOC was no real preparation for either test. In fact, the MOC seemed to be just the opposite of what MS has said it was designed to do. MS had stated the MOC was designed to take someone with 2-3 years experience with a product and teach them to translate that experience into a test environment.

However, I found that the MOC for SP 2010 was more designed to teach the basics of the product and related technologies and less about how to translate your experience into a test environment.

I would surmise that if one had spent 2-3 years administering half a dozen cutting edge SP 2010 farms which utilized 90% of SP2010's capabilities one could pass the TS (70-667) without test prep. And by the same method - if one had spent 2-4 years designing, building and doing governance and DR for a few dozen different SP2010 environments which utilized 90% of SP2010's capabilities and interacted with related systems and LoB apps, then one could pass the PRO (70-668) without test prep.

Of course, test prep could help if you don't have such wide experience. There are probably sources for the exact questions on the test if one wished to try to memorize the test pool instead of learning the product.

I will say, though, that no longer could one just read a book and pass these tests. That's good. But, I am sure people will still cheat to get the credentials. So, what are they really worth?

Keep sharing!​

June 06
Programmatically creating a new permission level in SharePoint 2010

When the out-of-the-box permission levels do not suit your needs, SharePoint 2010 allows you the capability to create new combinations of permissions that can then be assigned to individuals and/or groups. This is easy enough to accomplish via the SP2010 GUI, so I won't cover that here. In fact if all you need to do is create a permission level for a single site collection or site it is most likely faster to do this through the GUI than programmatically…it isn't something most do very often anyway.

However, what if you have 5000 site collections that already exist in a web application? It certainly doesn't make sense to go to each one and manually create a permission level for each site collection. And while you may use Policies for Web Applications to assign global "full read" or "full control", if you need more fine-tuned permissions, then that won't work either.

What's a SharePoint Guru to do? Enter PowerShell!

We prepare our PowerShell script in two steps.

First we write the part to create our custom permission level. Our goal in this example is to create a permission level that allows all the permissions of the OOTB Contributor permission level minus the ability to delete. Below is the code to create just such a permission level. Use your own web application URL.

$spWeb = Get-SPWeb #This is just an example Web App

$spRoleDefinition = New-Object Microsoft.SharePoint.SPRoleDefinition

$spRoleDefinition.Name = "NoDelete"

$spRoleDefinition.Description = "Can Create and Modify Items, Not Delete"

$spRoleDefinition.BasePermissions = "






















Note that we must enumerate all the permissions we will give the custom permission level and we must not forget any prerequisite permissions else this custom permission level will not function. Where do we get the prerequisite permissions? How do we know which permissions are even a part of the Contributor permission level?

I use the GUI for finding out which permissions are part of a permission level. From Site Settings, click on Site Permissions under Users and Permissions. In the ribbon click on Permission Levels. Click on the Contribute (for example) level and you will see all the different permission assigned to this level.

To get a list of all the permissions available to assign to a level run the following PowerShell command in the SharePoint Management Utility:



Alright. Now we can do this once. But how do we insert this permission level into our 5000 existing site collections?

We get loopy!

//Name of the web application

$webapp = Get-SPWebApplication #This is an example web application


//Loop through each site collection within the web application

foreach ($SPSite in $webapp.sites)


//Open the web

$OpenWeb = $SpSite.OpenWeb()


$spWeb = Get-SPWeb $OpenWeb.url


$spRoleDefinition = New-Object Microsoft.SharePoint.SPRoleDefinition

$spRoleDefinition.Name = "NoDelete"

$spRoleDefinition.Description = "Can Create and Modify Items, Not Delete"

$spRoleDefinition.BasePermissions = "



























In this script we identify the web application, then use PowerShell to get a list of the site collections, loop through them and in each one create our custom permission level. Then, as always when using the OpenWeb method, we dispose of it to clean up our code.

To take this a step further, suppose we wanted to assign a user or an Active Directory group to use this permission level in every site collection?

We would add the following code inside our "Foreach" brackets just before the //cleanup portion:

#Assign domain\domain users to custom permission level

New-spuser $NoDelete -web $OpenWeb.url -PermissionLevel "NoDelete"

This gives explicit permissions for the "NoDelete" permission level to the AD Domain Users security group throughout the site collection.

Obviously, you can take this example and apply it to numerous specific scenarios. But, the basic principle is sound enough to use for lots of things.

I will revisit the idea of looping as I write up more examples that have allowed me to more easily manage very large SharePoint 2010 farms.


March 03
Programmatically Close or Open a SharePoint Web Part

For many of the large scale SharePoint deployments I have architected over the last several months I have often run into change orders. Some of these have required the removal of web parts from pages in a site. While having a single web part on a single SharePoint site is not going to be even a moderate effort when it comes to removing a web part from a page, when we are speaking of 5000+ site collections with the same web part deployed to the default.aspx layout page of each site, we are talking about a major effort. And when this modification will only be temporary – that you’ll need to put it back after some issue is resolved – then you really need a solution you can reverse just as easily.


Some web parts are coded very well to allow for just such an eventuality and by merely performing the normal remove process from the farm scope the web part code will clean up all instances of its occurrence. Ok..who am I kidding? I’ve never seen a web part coded that well.
So, I’ve learned to programmatically remove a web part from a page using PowerShell in the SharePoint 2010 Management Shell. I know you’re saying, “Kevin? Coding?” And I say, “Yes, but it’s really scripting…it just looks like real coding.”
I’ve seen a few posts on doing this very thing, but I wanted to clear up a couple things I’ve run into. First, let me show you the code I use to Close the web part. Some people will recommend that you never Close a web part, that you should always delete it and then you can add it back to the page if you need to do so. That’s all well and good if you have a small number of sites. But, if you are working with thousands, or if the solution needs to be repeatable and reversible, then you definitely want to Close the web part. It is much easier to reverse.
Here’s the code to delete a single web part from the default.aspx page :
[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null 
# set-up working variables...
      #define your site URL
      #define your page URL
      write-host "Deleting Web part"
       $spSite = new-object Microsoft.SharePoint.SPSite($targetSiteUrl) 
       $webpartmanager=$web.GetLimitedWebPartManager($pageURL,  [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
        foreach ($webpart in $webpartmanager.WebParts)
              if ($webpart.Title -eq "Web part Title")
                     # Perform the close function
      write-host "Web part deleted."
Now, what is different about my code than others? First, it can be used for more than one web part on a page – especially if you want to close all but a single web part. Second, the other examples of similar code use an equals sign (=) in the If statement. I found that this sets the Title Property on ALL web parts on your page to whatever is in quotes – then disables them all since all will evaluate to True after that. So, I replaced the (=) with the PowerShell comparator  –eq. This just compares and doesn’t try to set values.
What tipped me off on why this was happening was that I tried to use other web part properties to try to keep it from happening. When I used ID the page was unloadable because there were then two web parts with the same GUID. When I used DisplayTitle I got a bit more of an epiphany. I got an error that the property was Read Only and so could not be set. That told me that the script was setting the value before it tried to compare it.
And if I need to reopen that closed web part again, I run the same code but change the CloseWebPart method to OpenWebPart. It’s that simple.
So, this works for one web site. But, what if I need to iterate through 100 or 1000 or 10000 sites to do the same thing?
All I need to do is insert this code into code that loops through all my sites. Personally, I prefer to use a Comma-separated Value (.csv) file to store all the URLs for my site collections. Then I use code very much like the following:
$file = Import-CSV "C:\ps\testbatchsites1.csv"
#Initialize Variables
#Iterate through rows
foreach ($row in $file)
                [System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null 
        # set-up working variables...
      #define your site URL
      $targetSiteUrl = $row.targeturl
      #define your page URL
      $pageURL= $row.targeturl + "/default.aspx"
     Write-Host $pageURL
      write-host "Deleting Webpart"
       $spSite = new-object Microsoft.SharePoint.SPSite($targetSiteUrl) 
       $webpartmanager=$web.GetLimitedWebPartManager($pageURL,  [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
        foreach ($webpart in $webpartmanager.WebParts)


                     if ($webpart.Title -eq "Client Information")


                     # Perform the Web Part Close operation
      write-host "Webpart Deleted"
Again, if you need to reopen the closed web parts on all your site collections just change CloseWebPart to OpenWebPart and rerun your script against the same .csv file.
So, hope this helps you get a little further with an issue or two.
Sharing the Wealth


1 - 10Next

 ‭(Hidden)‬ Admin Links

9/4/2014 5:45 PM   KCOG Meeting 
9/9/2014 7:00 PM   SharePoint - Kansas City Users Group 
10/2/2014 5:45 PM   KCOG Meeting 
10/14/2014 7:00 PM   SharePoint - Kansas City Users Group 
11/6/2014 5:45 PM   KCOG Meeting 
11/11/2014 7:00 PM   SharePoint - Kansas City Users Group 
12/4/2014 5:45 PM   KCOG Meeting 
12/9/2014 7:00 PM   SharePoint - Kansas City Users Group 
1/1/2015 5:45 PM   KCOG Meeting 
1/13/2015 7:00 PM   SharePoint - Kansas City Users Group 
(More Events...)

 ‭(Hidden)‬ Send Feedback