Category Archives: PowerShell

SharePoint Powershell | Get Detailed Information about Correlation IDs in ULS

I use this often enough I thought I’d write a quick post about it.  Basically, whenever an issue occurs on SharePoint we get a nice friendly error message with a correlation ID, which is great for troubleshooting the issues assuming that we have a nice timeframe for when the issue occurred.  We can quickly open the ULS Viewer, locate the correct log file, and filter for the correlation ID.   Unless of course we don’t have a time frame or we run a large farm, then it becomes more of a biblical “seek and ye shall find” approach.

That is where the beauty of PowerShell comes in.  There is a great command called Get-SPLogEvent which allows us to access the ULS logs through PowerShell and returns results from a Unified Logging Service (ULS) trace log.

Now, this is a great tool in general for being able to write monitoring scripts for SharePoint by using the following:

Get-SPLogEvent -MinimumLevel "Error"

Use the StartTime and EndTime flags and you can basically monitor your system every couple of minutes and if an Error level item is returned you can send yourself an email using the Send-MailMessage command.

However, what inspired this post is that I yet again received an e-mail with a screenshot of a friendly SharePoint error page telling me “An unexpected error has occurred.” (Do we every have an expected error?).  So, logging into the server and firing up my handy PowerShell windows I can use the following to find the specific Correlation ID in the ULS to quickly diagnose the issue.

Bring up the SharePoint 2010 Management shell on your server and enter the following:

Get-SPLogEvent | ?{$_.Correlation -eq "Correlation ID of Error"} | ft Category, Message -Autosize

Substituting the “Correlation ID of Error” string for the GUID in your screenshot.

If you want more detail than just the Category  and Message, just select the additional fields:

Get-SPLogEvent | ?{$_.Correlation -eq "Correlation ID of Error"} | select Area, Category, Level, EventID, Message | Format-List

and if you want to pipe it into a file so you can email it off to your SharePoint support group (because sometimes in large organizations there is more than just one person responsible for the SharePoint farm) you can use this to create a file:

Get-SPLogEvent | ?{$_.Correlation -eq "Correlation ID of Error"} | select Area, Category, Level, EventID, Message | Format-List > c:\SPCorrelationErr.log

And just like that, easy ways to extract the information you are looking for to help troubleshoot your SharePoint farm.

Microsoft Gallery | My PowerShell Script Reaches 100 downloads

Back when I was doing a lot of testing with loading test data into sharepoint lists and then dumping them to run another set of test data, the traditional method of deleting one at a time from the list was really slow, so I created a script to use the ProcessBatchData command to create an XML command structure to delete the items in batches so I could run several automated tests over with different conditions.  Worked well enough that I went ahead and uploaded it to the MS gallery for others to use who were in the same situation.  Just checked and we’ve passed the 100 downloads milestone.  So yeah!  Glad people find it useful

The Truncate all Items in an SPList in SharePoint Using ProcessBatchData Command contribution has been downloaded 100 times from the Office TechNet Gallery. Awesome!

Gallery | 5 days ago

Recently I’ve been working on some other PowerShell scripts to walk a website and record broken links for SharePoint 2010, so once it’s a little more bulletproof I’ll have to post that as well.

SharePoint 2010 | Crawl Not Starting Due To Missing Search Temp Directories

I was working on a search server recently and started getting errors that the crawl component was failing to “CreateTempFolderForCacheFiles”

As it turns out, the environment I was working on was an extremely secure farm where permissions were locked down and often shares were not permitted and accounts were allowed the minimum permissions they needed in order to run.  In  this case, the local temporary folder where the index files are created had been deleted, and the search service did not have permissions to recreate the folder.  This was blocking the crawls from proceeding and they were just sitting there.

In order to fix the issue, the folders need to be recreated.  What is nice is that using PowerShell you can quickly recreate the folders in the correct location using the following script:

$app = Get-SPEnterpriseSearchServiceApplication "<my SSA>"
$crawlComponents = Get-SPEnterpriseSearchCrawlComponent -CrawlTopology $app.CrawlTopologies.ActiveTopology | where {$_.ServerName.ToLower().Equals($Env:COMPUTERNAME.ToLower()) }
foreach ($component in $crawlComponents)
{
    $path = $component.IndexLocation + "\" + $component.Name
    if ( Test-Path $path -pathType container)
    {
        Write-Host "Directory " $path " already exists"
    }
    Else
    {
        Write-Host "Creating Directory: " $path
        New-Item $path -ItemType directory | write-output
    }
}

PowerShell 3.0 (KB2506143) and SharePoint 2010, Not There Yet

So a bit of a rant, but as it turns out installing the Windows Management Framework 3.0 (KB2506143) on a SharePoint 2010 server is not such a good idea.

After installing the Windows Management Framework 3.0 on a SharePoint 2010 Server I can’t use the "SharePoint 2010 Management Shell" anymore.  SharePoint uses .NET 3.5 and PowerShell 3.0 uses .NET 4, so when I try to open the SharePoint management console and run a SharePoint cmdlet I get some fun errors that Microsoft SharePoint is not supported by Version 4.0

A PlatformNotSupportedException occured while trying to acquire the local farm: System.PlatformNotSupportedException: Microsoft SharePoint is not supported with version 4.0.30319.586 of the Microsoft .Net Runtime. at Microsoft.SharePoint.Administration.SPConfigurationDatabase.get_Farm() at Microsoft.SharePoint.Administration.SPFarm.FindLocal(SPFarm& farm, Boolean& isJoined)

The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.

So thanks for the lack of warning… but the fix is easy enough:

  1. Open the Installed Updates on the server
  2. search for KB2506143
  3. Uninstall
  4. Reboot
  5. Open PowerShell and type “(Get-Host).version”, you’ll see it is now running in 2.0 mode again.

You would think that during the install process of the WMF 3.0 it might check for SharePoint components and at least give a warning, but as the PowerShell team says here: http://connect.microsoft.com/PowerShell/feedback/details/746908/powershell-3-0-and-sharepoint-2010

Posted by Microsoft on 6/7/2012 at 12:34 PM

This is not an issue with Windows PowerShell. This is an issue with SharePoint 2010. The SharePoint team is aware of this compatibility issue and plans to address it in an upcoming release or service pack.

Truncate all Items in an SPList in SharePoint Using ProcessBatchData Command

This came up recently in regards to some of our test systems, where we were testing one of our systems that used large amounts of rows in an SPList.  As we were adding items through a scripted process “someone” (ok, it was me…) fat-fingered one of the scripts and next thing I knew we had roughly 30K rows from the wrong test bank sitting in our testing system.  Rather than just delete the SPList and start over I thought that there must be a better way to just truncate the table. 

All I could find were scripts that went through the item collection and called the .Delete() function on each item.  This delete process takes roughly a quarter of a second per item, with 30K items to delete we were looking at 2 hours to iterate through.  Not too bad, but not great when you’re sitting on a deadline.  So with a little investigation I found the ProcessBatchData function, which allows us to process multiple requests to the server per transaction.  Using this method we can pass XML formatted Collaborative Application Markup Language (CAML) that contains the commands, which consists of a Batch element and any number of subordinate Method elements that each specify a SharePoint Foundation remote procedure call (RPC) method.

It worked so well that I wrote it up as my very first Gallery submission to MSDN.

Here’s the link, if you like it, rate me a 5 Smile

http://gallery.technet.microsoft.com/sharepoint/Truncate-all-Items-in-an-2841c740

And for posterity, here is the original text of the submission… 

Introduction

This script will demonstrate how to delete Items from a Microsoft SharePoint list using Windows PowerShell and Microsoft SharePoint PowerShell snapin utilizing the ProcessBatchData command and building an XML command structure.

Scenario

Occasionally I have received requests to delete large amounts of data consisting of over 30,000 items. Previous scripts I used would iterate through the Items in the SPList and delete each item on a per item basis. However this was taking considerable time, using this method we can quickly delete items in batches of 100 even 1000 and remove these items.

Script

This script leverages the capability of Windows PowerShell and the ProcessBatchData to pass an XML request to the parent web to delete the list items in a batch.

You can use this script by following steps:

  1. Download the script and copy it to a Microsoft SharePoint 2010 Server which will be used for testing.
  2. Run the .\Truncate-SPList command inside SharePoint Management Powershell.
  3. Enter the URL and Name of the list ( or pass in parameters for -SiteURL and -ListName
  4. Confirm that you want to remove all items from the list ( ‘y’ )

Copy Code

 

## Truncate-SPList 
## Remove all items in a SharePoint List, batched up for processing in large chunks for a quick delete process 
## NOTE: This is not a true "Truncate", as SharePoint will never reuse an Item ID so seed is not reset 
## 
## Usage: Truncate-SPList -SiteUrl http://Server/Site  -ListName List 
## 
## Author:  
##    ieDaddy  
##    web: http://iedaddy.com 
##    twitter: @ieDaddy 
##              
##          
 
Param( 
    [Parameter(Mandatory=$true)] [String] $SiteUrl, 
    [Parameter(Mandatory=$true)] [String] $ListName 
    ) 
     
Function TruncateSPList  
{ 
    ## Parameter validation 
    Try  
    {  
        ## Use Get-SPWeb get the website we want, on error don't go further 
        $spWeb = Get-SPWeb -Identity $SiteURL -ErrorAction Stop -Verbose:$false  
    }  
    Catch   
    {  
        #If Get-SPSite failed for any reason, this function will be terminated.  
        Write-Host $Error[0] 
        return $null  
    }  
    ## Get the specified list, $spList is a instance of Microsoft.SharePoint.SPList class  
    $spList = $spWeb.Lists[$ListName] 
 
     
    if ($spList -ne $null)  
    { 
        ## This looping goes through one by one, but maybe a better way? 
        #ForEach ($item in $spList.items) 
        #{ 
        #    $ItemToDelete=$splist.GetItemById($item.ID) 
        #    write-host 'Deleting : ' $ItemToDelete.ID 
        #    $ItemToDelete.Delete() 
        #} 
         
        ## Set up a do..until loop so we can batch the removals 100 records at a time     
        do  
        { 
            ## Set up our Items Collection for Batch Processing 
            $spQuery = new-object Microsoft.SharePoint.SPQuery  
            $spQuery.RowLimit = 100 
            $spQuery.Query = "" 
            ## Get collection of items to be deleted for the batch delete 
            $spListItemCollection = $spList.GetItems($spQuery) 
            $batchRemove = '<?xml version="1.0" encoding="UTF-8"?><Batch>';    
            ## The command is built out to iterate through the ItemCollection to build out batch command 
            $command = '<Method><SetList Scope="Request">' +   
                $spList.ID +'</SetList><SetVar Name="ID">{0}</SetVar>' +   
                '<SetVar Name="Cmd">Delete</SetVar></Method>';    
            foreach ($item in $spListItemCollection)   
            { 
                $batchRemove += $command -f $item.Id;   
            }   
            $batchRemove += "</Batch>";    
             
            ## Remove the list items using the batch command  
            $spList.ParentWeb.ProcessBatchData($batchRemove) | Out-Null 
 
        } until ( $spList.GetItems().Count -eq 0 ) 
    } 
    Else 
    { 
        Write-Host $Error[0] 
        return $null  
    } 
 
    ## Dispose SPWeb object, it's just good manners 
    $spWeb.Dispose()  
} 
 
$confirm = Read-Host "This script will delete all items from the list, Proceed [y/n]" 
if ($confirm -ne 'y') 
{ 
    Exit 
}     
TruncateSPList 
 
 
 
 

Prerequisite

Windows PowerShell 2.0

Microsoft SharePoint 2010 PowerShell Snapin