How to remove webparts from a SharePoint page programmatically using Powershell

Let’s imagine this scenario:

You need to remove a webpart from a SharePoint page in your farm.   Easy, right?  Go to the page, enter the Edit mode, click on the webpart, select Delete.  No problem!   Now what if you had 1000 sites to remove the webpart from?   Doing it by hand is impractical, so we’ll need to use Powershell.

This will be a two step process:

Step 1, you need to run an inventory script which will generate a list of webparts and their GUIDs.

Step 2, you will use the webpart GUIDs from step 1 to run a removal script to remove the webparts.

STEP 1. INVENTORY SCRIPT

Execute the script below using the SharePoint 2010 Management Shell (PowerShell console).  This script does the following:

1. Iterate through all web applications in the farm and open every every site collection in each web app

2. For each site collection, access the homepage  “default.aspx” and capture a list of webparts on the page and their GUIDs.

3. Write the results to a file called “results.txt”, located in the same directory as the Powershell script.

The page name “default.aspx” is hard-coded in the script but can be easily changed to another page name or page path.

 

Script source code


[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null

$oContentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService;

[Microsoft.SharePoint.Administration.SPWebApplicationCollection]$waColl = $oContentService.WebApplications;

$log = ".\results.txt"    # output file name and path
$pagepath = "/default.aspx"    # change page name or page path here

"Site URL; WebPart Title ; Webpart ID" | out-file $log

$waColl1 = $waColl | where-object {$_.IsAdministrationWebApplication -eq $FALSE}

foreach ($wa in $waColl1)
{

foreach ($obj in $wa.Sites) 
{

write-host "Processing: " , $siteURL

$siteURL = $obj.URL

$site=new-object Microsoft.SharePoint.SPSite($siteURL)

$pageURL = $siteURL + $pagepath  
$web=$site.Openweb()   
$webpartmanager=$web.GetLimitedWebPartManager($pageURL,  [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)   
foreach ($webpart in $webpartmanager.WebParts)
{   
$siteURL + "; " + $webpart.Title + " ;  " + $webpart.ID | out-file $log -append   
}                           
}

}

write-host "Finished."

 

STEP 2. WEBPART REMOVAL SCRIPT

This script  will programmatically remove a webpart from a SharePoint page.  It takes as arguments the target site URL and the webpart GUID.   The script targets the main page “default.aspx” but can be changed to accept any other page name or page path.

Notes: Use the results from the INVENTORY SCRIPT to create a list of webparts and their GUIDs to remove. Then build a script which calls out the WEBPART REMOVAL SCRIPT using the site URLs and webpart GUIDs as arguments.

The syntax is the following:

Execute the following command in SharePoint 2010 Management shell (Powershell console):

[WEBPART REMOVAL script file name] [site URL] [webpart GUID]

Example:

remove.ps1     http://mysharepointsite     a1b83-8tyu-6897-oiy8

 

Script source code


[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.WebPartPages") [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Publishing")

$siteURL = $args[0]  # first argument: site URL

$webpartId = $args[1]   # second argument:  webpart GUID

$pagepath =  "/default.aspx"        # change page name or page path here

$pageURL = $siteURL + $pagepath

write-host "Processing site: ", $siteURL

Write-host "Processing page: " , $pageURL

write-host "Processing webpart ID: " , $webpartID

$site=new-object Microsoft.SharePoint.SPSite($siteURL)

$web=$site.Openweb()

$webpartmanager=$web.GetLimitedWebPartManager($pageURL, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)

$webpartmanager.DeleteWebPart($webpartmanager.Webparts[$webpartId])

$web.Update()

$web.Dispose()

write-host "Finished."

Solving “The attempted operation is prohibited because it exceeds the list view threshold” error

While working in SharePoint 2010, you may receive the following error:

The attempted operation is prohibited because it exceeds the list view threshold enforced by the administrator. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: <nativehr>0×80004005</nativehr><nativestack></nativestack>The attempted operation is prohibited because it exceeds the list view threshold enforced by the administrator.

I got this error while trying to change the site URL in Site Settings.

The resolution to this error is:

1. Navigate to Central Administration.

2. Go to Application Management > Manage Web Application and click on your web application to select it.

3. In the Ribbon, click on General Settings drop-down and choose “Resource Throttling”.

4. In the “List View Threshold”, increase the value (by a factor of 2, for example) and click OK.

5. Try to replicate the error.  If the error persists, increase the value again until the error goes away.

 

Enabling full stack dumps (detailed error messages) on ASP.NET and SharePoint

When an error occurs within SharePoint, the application by default will not display a detailed error message to the end user (this is done for security reasons).  When you’re actively configuring/developing your SharePoint platform, it is sometimes useful to display detailed error messages.  

Here are the steps to do it:

You must edit several “web.config” files:

1. Each SharePoint web application you created will have its own “web.config”.  You can find these in the respective folders under “C:\inetpub\wwwroot\wss\VirtualDirectories”.

In the XML section <system.web> you have two changes to make:               

CHANGE #1:  <customErrors mode=”Off” />

( This is normally set to “On” so change it to “Off”)           

CHANGE #2:  <compilation batch=”false” debug=”true”>

(The ‘debug’ attribute is normally set to “false” so change it to “true”)
               
In the XML section <SharePoint> you have a single change to make:
CHANGE #3:  <SafeMode MaxControls=”200″ CallStack=”true”…>

(The ‘CallStack’ attribute is normally set to “false” so change it to “true”)

Remember, you must make these THREE changes in EACH of the web.config files found in the folder for each of your web applications!

2. You must also change the “web.config” that is global to SharePoint (ie:  applies to all web applications).  This file is located here:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\web.config

In the XML section <system.web> you have a single change to make:
CHANGE #1:  <customErrors mode=”Off” />

(This is normally set to “On” so change it to “Off”)

*** Thanks go to David Biersach for providing detailed background information for this post. ***

Fixing “Error in the Site Data Web Service” crawl error in SharePoint 2010

I ran into the following issue with search in SharePoint Server 2010 – the crawl job was failing to index the entire site collection. 

Crawl log error:  Error in the Site Data Web Service. (Value does not fall within the expected range.)
ULS log error:   “Error from SharePoint site: Data is Null. This method or property cannot be called on Null values.”

If you turn your diagnostic logging to Verbose, you might see the following error in the ULS log file:

GetSite fail. error 2147755542, strSiteUrl

I was able to fix the problem with the following steps:

1) Ran stsadm -o export command with -includeusersecurity switch to export the site.

2) Additionally, created a full backup of the site (just in case I needed to roll back) using stsadm -o backup command.

3) Deleted the original site collection.

4) Re-created a blank site collection with the same URL and using the same site template.

5) Ran stsadm -o import command with -includeusersecurity switch to import the site.

6) In the Search service application, deleted the original content source containing the problem site collection URL and re-created it with a different name.

7) Reset search index and run a full crawl job.

Fix “Content database with modified database schemas” issue when upgrading to SharePoint Server 2010

Problem:  You’re trying to upgrade your farm from MOSS 2007 to SharePoint Server 2010.  When you run stsadm preupgradecheck tool, it reports the following:

Issue : Content database with modified database schemas       
User modifications to the SharePoint content database, including but not limited to table schemas, index, stored procedures, are not supported and will cause upgrade to future versions of SharePoint to fail. The databases in the following list seem to have been modified from the original schema:

Data Source=YourDBServer;Initial Catalog=ProblemDB;Integrated Security=True;Enlist=False;Connect Timeout=15

If you did not make any manual changes to your database schemas, then see MS article http://technet.microsoft.com/en-us/library/cc262967.aspx.  

Otherwise, you can resolve this issue by following the steps below. Make sure to test this out in your test environment and create backups of all production databases before making any changes. 

1. Let’s say your problem database is called “ProblemDB”.  In Central Administration, in the same web application where your ProblemDB resides, add a blank content database.   Go to Central Admin site > Application Management > Content Databases.  Switch to the web application in question, click on “Add a content database”.  Use the same settings as your ProblemDB, but let’s call this database “GoodDB”.

2. Run the following command for each site collection found in the ProblemDB.  This command will move site collections from ProblemDB to GoodDB.

stsadm -o mergecontentdbs -url <site collection URL> -sourcedatabasename ProblemDB -destinationdatabasename GoodDB -operation 2

3. Go to Central Admin site > Application Management > Content Databases and confirm that ProblemDB does not contain any sites. Remove ProblemDB in CA.

4. Restart IIS.

5. Run stsadm preupgradecheck tool again to confirm that the issue has been resolved. 

Acknowledgements:  I’d like to thank Joseph Yi (Datacure, Inc.) for proposing and developing this solution.

 

Note:    If you did not make any manual changes to the database schema, you may want to reference the following Microsoft article:

From http://technet.microsoft.com/en-us/library/cc262967.aspx:

Upgrading data from SharePoint Portal Server 2003: pre-upgrade checker reports corrupted databases

When a content database in an Office SharePoint Server 2007 farm was upgraded from a Microsoft Office SharePoint Portal Server 2003 content database, you might see the following error when you run the pre-upgrade checker:

Failed : Content database with modified database schemas

If you did not make any manual schema changes to the database, you can ignore this error and continue with the ugprade. This is a residual error from the upgrade process from SharePoint Portal Server 2003 to Office SharePoint Server 2007. For more information, see the Microsoft Knowledge Base article 954772.

Some SharePoint Anagrams…

Courtesy of the Internet Anagram Server (http://wordsmith.org):

The word “SharePoint” can be re-arranged into the following phrases:

Tear Siphon
Orphan Site
Pain Others
Train Hopes
A Pot Shrine
A Shoe Print
A The Prison
A Open Shirt
A Person Hit
Share No Tip
Heat Or Snip
Hate Or Spin
Parent So Hi
Earn Oh Tips

:)

Microsoft SharePoint Part-time Professionals group on LinkedIn

This week I created a new group on LinkedIn called “Microsoft SharePoint Part-time Professionals“.  I’ve been getting quite a few requests for part-time/evening/weekend work for SharePoint developers and administrators, so I decided to start a group and post them there.   I’ll post here any side work that comes across my desk.  To join the group, do the following:

1. Log in to LinkedIn at www.linkedin.com.  If you don’t already have an account, create one, it’s free, and will do wonders for your career. 

2. In the search box in the upper right corner, search for ”Microsoft SharePoint Part-time Professionals”.

If you have any part-time/evening SharePoint projects that you need help with, post them in the Discussions area.

PowerShell script to monitor server disk space and send out email alerts

When you’re managing a large SharePoint installation, storage issues are going to be a major concern.   Whether it’s ULS logs, IIS logs,  SQL databases and transaction logs - whatever it is, when left to its own devices, SharePoint can consume a lot of space very quickly, and before you know it, your disks will be running out of space.

I found a cool PowerShell script by Colin Smith called Disk Space Monitor (see it here:  http://powershell.com/cs/media/p/1617.aspx).  For whatever reasons, I had problems getting the email component to work properly, and I also wanted to tweak the email message format.   One thing led to another, and I ended up re-writing a few other sections of Colin’s script to better suit my needs.  The final product appears below  – it reads a list of servers, checks the free space on each server, and sends out an email summary to a list of users you specify. 

How to use this script:

Step 1.  Create a simple text file with a list of your servers to audit, single column, single-spaced, like this:

server1

server2

server3

server4

Let’s call the list “list.txt”.  Save the file.

Step 2. Create a batch file (let’s call it “start.bat”) and enter the following code in it.  Make sure to enter your own path for the server list as well as the output log file.


REM  Usage:  powershell %~dp0DiskSpaceMonitor.ps1  <computer list file path>   <output log path>
powershell  %~dp0DiskSpaceMonitor.ps1 C:\Scripts\DiskSpaceMonitor\list.txt   C:\Scripts\DiskSpaceMonitor\output.txt

 

Step 3. Create a PowerShell script file in the same directory as “start.bat”,  let’s call it “DiskSpaceMonitor.ps1″, and enter the following code in it.  Make sure to specify your own list of users to email and your SMTP server name or IP address.  Save the file, and execute “start.bat”.

# This script performs the following actions:

#  1) Read a list of servers
#
#  2) For each server on the list, get disk drive information - drive letter, drive size, free space, percent free
#
#  3) Email the report to users specified by the $users variable
#
$users = "user1 @ domain.com", "user2 @ domain.com " , "user3 @ domain.com"

$server = "SMTP server name or IP address"

$port = 25

$list = $args[0]

$output = $args[1]

$computers = get-content $list

echo "SharePoint Storage Report" > $output
echo " " >> $output
echo "Note: Free space below 30% is labeled with *** " >> $output
echo " " >> $output
echo " " >> $output
echo "ServerName    Drive Letter Drive Size Free Space Percent Free" >> $output
echo "----------    ------------ ---------- ---------- ------------" >> $output
foreach ($line in $computers)
{
 $computer = $line 
 
 $drives = Get-WmiObject -ComputerName $computer Win32_LogicalDisk | Where-Object {$_.DriveType -eq 3}
 foreach($drive in $drives)
 {

 $id = $drive.DeviceID
 $size = [math]::round($drive.Size / 1073741824, 2)
 $free = [math]::round($drive.FreeSpace  / 1073741824, 2)
 $pct = [math]::round($free / $size, 2) * 100
 
 if ($pct -lt 30) { $pct = $pct.ToString() + "% *** " }

 else {  $pct = $pct.ToString() + " %" }

echo "$computer   $id  $size  $free  $pct"  >> $output

$pct = 0 

 }

}
foreach ($user in $users)
{

$to      = $user

$from    = "<a href="mailto:diskspacemonitor@domain.com">diskspacemonitor@domain.com</a>"

$subject = "Connect Storage Report"

foreach ($line in Get-Content $output)

{

$body += “$line `n”

}

# Create mail message

$message = New-Object system.net.mail.MailMessage $from, $to, $subject, $body

#Create SMTP client

$client = New-Object system.Net.Mail.SmtpClient $server, $port

# Credentials are necessary if the server requires the client # to authenticate before it will send e-mail on the client's behalf.

$client.Credentials = [system.Net.CredentialCache]::DefaultNetworkCredentials

# Try to send the message

try {      

$client.Send($message)      

"Message sent successfully"

# reset variables

$body = ""

}

# Catch an error

catch {

"Exception caught in CreateTestMessage1(): "

}

}

# End of Script

 

How to enumerate user profiles and their properties in SharePoint 2010 using PowerShell

When administering a large SharePoint 2010 deployment, there are times when you may need to take an inventory of the user profiles in your profile store – perhaps to find users with a common property or characteristic, run some comparisons of your SharePoint profiles to Active Directory, or do some other administrative task.

Here’s a simple PowerShell script that enumerates all user profiles in the context of your SharePoint site and emits some of their properties, such as Display Name, AccountName, and workEmail.

Note:  The account which will be executing this script needs to have Full Control access to the User Profile Service application.   Follow these two steps:

1) Go to  Central Administration > Manage service applications > select (highlight) your user profile application > click on Administrators button on the ribbon and add your account.

2) Go to  Central Administration > Manage service applications > select (highlight) your user profile application > click on Permissions button on the ribbon and add your account with Full Control – make sure to check the “Full Control” checkbox!


[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
# Enter your SharePoint site URL here...
$site = new-object Microsoft.SharePoint.SPSite("http://...");

$ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($site);

$ProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext)

$AllProfiles = $ProfileManager.GetEnumerator()

write-host "Display Name ;  AccountName ; Email ; "

foreach($profile in $AllProfiles)
{

$DisplayName = $profile.DisplayName

$AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value

$workEmail = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::workEmail].Value

write-host $DisplayName, ";", $AccountName, ";" , $workEmail, ";"

}
write-host "Finished."

$site.Dispose()

A full list of SP 2010 user profile properties is available on MSDN here:

http://msdn.microsoft.com/en-us/library/microsoft.office.server.userprofiles.propertyconstants_members.aspx

How to programmatically delete items in a SharePoint list

I was looking for a way to programmatically delete items in a SharePoint list, and I found this great post by DevExpert:

http://www.devexpertise.com/2009/02/04/deleting-list-items-in-a-sharepoint-list/

The author outlines four incorrect methods for doing it, and one correct method.  It turns out that you need to use a For loop with a decrementing counter, like this:

<code>

for (int i = list.Items.Count - 1; i >= 0; i--) {
    list.Items.Delete(i);
}
</code>
Great post!

Next Page »


RSS SharePoint Team Blog

  • An error has occurred; the feed is probably down. Try again later.

RSS Ben Curry’s Blog

  • I'm at the ATL users group Monday night, Nov 16th November 15, 2009
  • Upgrading to SharePoint Server 2010 November 3, 2009

RSS Bud Ratliff blog

  • An error has occurred; the feed is probably down. Try again later.

RSS SharePoint PS Blog

  • An error has occurred; the feed is probably down. Try again later.

RSS Greg Kamer’s Blog

  • An error has occurred; the feed is probably down. Try again later.

Blog Stats

  • 61,299 hits

Follow

Get every new post delivered to your Inbox.