Tag Archive for: Powershell

Powershell: Efficiently empty large SharePoint lists

03 May
May 3, 2013

Previously I had a little console app to efficiently empty large SharePoint lists. Today I converted it to powershell.

Compared to the simple item by item delete with item.Delete() its 30 times faster; on my dev machine it deletes ~30 items per second. It works for SharePoint 2010 and should  for 2013 (not tested, yet).

Script

param($weburl,$listname)
 
if ($weburl -eq $null -or $listname -eq $null)
{
	write-host -foregroundcolor red "-weburl or -listname are null."
	return
}
 
Add-PSSnapin Microsoft.SharePoint.Powershell -EA 0
$web = get-spweb $weburl
$list = $web.lists[$listname]
 
$stringbuilder = new-object System.Text.StringBuilder
 
 #TODO: fetch items with spquery 
 
try
{
    $stringbuilder.Append("<!--?xml version=`"1.0`" encoding=`"UTF-8`"?-->") > $null
 
	$i=0
 
	$spQuery = New-Object Microsoft.SharePoint.SPQuery
	$spQuery.ViewFieldsOnly = $true
 
	$items = $list.GetItems($spQuery);
	$count = $items.Count
 
	while ($i -le $count)
	{
		write-host $i
		$item = $items[$i]
 
        $stringbuilder.Append("") > $null
        $stringbuilder.Append("" + $list.ID + "") > $null
        $stringbuilder.Append("" +$item.Id + "") > $null
        $stringbuilder.Append("Delete") > $null
        $stringbuilder.Append("") > $null
 
		$i++
    }
    $stringbuilder.Append("") > $null
 
    $web.ProcessBatchData($stringbuilder.ToString()) > $null
}
catch
{
	Write-Host $_.Exception.ToString()
}
 
write-host "done."

Usage

Delete-Items.ps1 -weburl [url of web] -listname [name of list]

Further improvements

I think if the list is really huge (100k items or greater) the items should be deleted in batches.

I have not tried it with a document library, maybe there are issues. If there are issues, please leave a comment!

Disclaimer

There is no way back – if you start the script there is no “ARE YOU SURE?” – all data is gone in a very short time.

Cache cluster is down, restart the cache cluster and Retry

05 Feb
February 5, 2013

Had a small issue with my SharePoint 2013 MySite today, I could not update a User Profile in Central Admin – this is what I got from the ULS Log:

sp2013_cachecluster

ULSViewer: The exception is pointing us in the right direction.

The Execute method of job definition Microsoft.Office.Server.UserProfiles.LMTRepopulationJob (ID 104963a2-b53c-4476-bc23-fa7d6453e42f) threw an exception. More information is included below.  Unexpected exception in FeedCacheService.IsRepopulationNeeded: Cache cluster is down, restart the cache cluster and Retry.

At least the error message pointed me to the right direction, the Cache Cluster is new in SharePoint 2013 and I associated it with the app fabric distributed cache. As I first read it it sounded like “The King is dead – long live the King!” – but maybe I watch to many movies…

Solution

Restart the app fabric service and wait a couple of second with a line of powershell:

Restart-Service AppFabricCachingService

SharePoint 2013: Replace the PDF icon

18 Sep
September 18, 2012

Icon madness

Playing arround with SharePoint 2013 and uploading some content for a cool search driven application I noticed that the PDF icon is not the correct one:

MS_PDF_ICON

OOTB PDF icon from SharePoint 2013

Is it a document with a belt or what ? Nevermind I don’t like it and I am very certain that most of the users out there do not recognize the icon – and that is the main purpose of the icon right?

Search_WithMSPDF

Search result with out-of-the-box SharePoint 2013 PDF icon

With SharePoint 2010 there was no PDF support out of the box – afaik there was no icon at all. I should be happy and quite right? Nope, created a small powershell that replaced the icon (either you place it next to the script or the script downloads it from the Adobe page).

The result will look like this – way better if you ask me.

Search_WithOriginalPDF

Original PDF icon – as expected!

PDF_Doclib

Same icon in a document library

 

Powershell to the rescue – once again!

And here comes the small script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#########################################################################################
# by Max Melcher, http://melcher.it, @maxmelcher
# Feel free to change and reuse as you wish - use on your own risk
 
# Script that replaces the OOTB SharePoint 2013 PDF icon with the orignal Adobe PDF icon.
# Execute on each webfrontend
#########################################################################################
 
#settings
$destination = "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\TEMPLATE\IMAGES\icpdf.png"
 
#Check if the icon exists otherwise download it
$item = Get-ChildItem  pdficon_small.png -ErrorAction SilentlyContinue
 
if ($item)
{ 
    Write-Host -ForegroundColor Yellow "Supplied icon found - overwriting"
    Copy-Item $item -Destination $destination -Force
}
else
{
    Write-Host -ForegroundColor Yellow "Downloading icon from Adobe"
    Download "http://1.2.3.10/bmi/www.adobe.com/images/pdficon_small.png" $destination
}
 
Write-Host -ForegroundColor Green "Icon replaced"
 
#Icon will only be changed after iisreset or reboot
RestartIIS
 
#Helper
function download{&nbsp;&nbsp;&nbsp;&nbsp; # usage: download http://url c:\temp
    param([string]$URL, [string]$destination)&nbsp;&nbsp;&nbsp;&nbsp; Write-Host "Downloading $URL ..."&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $clnt = new-object System.Net.WebClient -ErrorVariable err -ErrorAction "SilentlyContinue"&nbsp;&nbsp;&nbsp;&nbsp; $clnt.DownloadFile($url,$destination)&nbsp;&nbsp;&nbsp;&nbsp; if ([String]::IsNullOrEmpty($err) -eq $true) { Write-Output " - Download completed."}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else { Write-Error "Download ERROR - Check URL: $err" }
 
}
 
function RestartIIS(){
$title = "Restart IIS"
$message = "Do you want to restart the local IIS?"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&amp;Yes","Restarts IIS."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&amp;No","Silently continues..."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0) 
    if ($result -eq 0){
        Write-Host -ForegroundColor Yellow "Restarting IIS"
        iisreset /noforce
    }
}
 
Write-Host -ForegroundColor Green "done!"

 

Thats it – go try it!

As always, would love to hear your feedback.

#SharePoint 2013 – Create a Search Service Application and Search Topology with Powershell

23 Jul
July 23, 2012

Writing SharePoint 2013 feels very new to me, but I created my first Demo environment and tried to set up search.

What needs to be done?

14 steps for a simple Search Topology – 1 powershell can do them all.

  1. Create a Service Application Pool for the Search Service Application (15-22)
  2. Create a Search Service Application (22-28)
  3. Create a Search Service Application Proxy (30-36)
  4. Get the current Search Instance (38)
  5. Save the current Search Topology for later use (39)
  6. Create a new Search Topology (40)
  7. Create all the Search Components (Analytics- , Content Processing, Query Processing, Crawler-, Admin Component) (42-46)
  8. Remove the Index-Folder and recreate it (50-51)
  9. Create a new Index Component (53)
  10. Activate the new Topology (56)
  11. Call the method synchronize on the old topology – this errors but forces an update on the old topology object (59)
  12. The "forced updated" Topology object becomes inactive and can be deleted. (62)
  13. Everything  done – start a full crawl oder set it to the new shiny continuous crawling. Enjoy!

The numbers in the braces are the line numbers in the powershell script following now.

 

Powershell to the rescue!

Here is my powershell script for creating the whole service application and creating a basic topology.

Please keep in mind that the $IndexLocation folder will be deleted and recreated.

Adjust the settings in the lines 4-11 to your needs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
 
#Settings
$IndexLocation = "C:\Search"  #Location must be empty, will be deleted during the process!
$SearchAppPoolName = "Search App Pool"
$SearchAppPoolAccountName = "demo\SPSearchAppPool"
$SearchServiceName = "Search SA"
$SearchServiceProxyName = "Search SA Proxy"
 
$DatabaseServer = "sp2013\sharepoint"
$DatabaseName = "SP2013 Search"
 
Write-Host -ForegroundColor Yellow "Checking if Search Application Pool exists"
$spAppPool = Get-SPServiceApplicationPool -Identity $SearchAppPoolName -ErrorAction SilentlyContinue
 
if (!$spAppPool)
{
    Write-Host -ForegroundColor Green "Creating Search Application Pool"
    $spAppPool = New-SPServiceApplicationPool -Name $SearchAppPoolName -Account $SearchAppPoolAccountName -Verbose
}
 
Write-Host -ForegroundColor Yellow "Checking if Search Service Application exists"
$ServiceApplication = Get-SPEnterpriseSearchServiceApplication -Identity $SearchServiceName -ErrorAction SilentlyContinue
if (!$ServiceApplication)
{
    Write-Host -ForegroundColor Green "Creating Search Service Application"
    $ServiceApplication = New-SPEnterpriseSearchServiceApplication -Name $SearchServiceName -ApplicationPool $spAppPool.Name -DatabaseServer  $DatabaseServer -DatabaseName $DatabaseName
}
 
Write-Host -ForegroundColor Yellow "Checking if Search Service Application Proxy exists"
$Proxy = Get-SPEnterpriseSearchServiceApplicationProxy -Identity $SearchServiceProxyName -ErrorAction SilentlyContinue
if (!$Proxy)
{
    Write-Host -ForegroundColor Green "Creating Search Service Application Proxy"
    New-SPEnterpriseSearchServiceApplicationProxy -Name $SearchServiceProxyName -SearchApplication $SearchServiceName
}
 
$searchInstance = Get-SPEnterpriseSearchServiceInstance -local 
$InitialSearchTopology = $ServiceApplication | Get-SPEnterpriseSearchTopology -Active 
$SearchTopology = $ServiceApplication | New-SPEnterpriseSearchTopology
 
New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchTopology $SearchTopology -SearchServiceInstance $searchInstance
New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $SearchTopology -SearchServiceInstance $searchInstance
New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $SearchTopology -SearchServiceInstance $searchInstance
New-SPEnterpriseSearchCrawlComponent -SearchTopology $SearchTopology -SearchServiceInstance $searchInstance 
New-SPEnterpriseSearchAdminComponent -SearchTopology $SearchTopology -SearchServiceInstance $searchInstance
 
set-SPEnterpriseSearchAdministrationComponent -SearchApplication $ServiceApplication -SearchServiceInstance  $searchInstance
 
Remove-Item -Recurse -Force -LiteralPath $IndexLocation -ErrorAction SilentlyContinue
mkdir -Path $IndexLocation -Force 
 
New-SPEnterpriseSearchIndexComponent -SearchTopology $SearchTopology -SearchServiceInstance $searchInstance -RootDirectory $IndexLocation 
 
Write-Host -ForegroundColor Green "Activating new topology"
$SearchTopology.Activate()
 
Write-Host -ForegroundColor Yellow "Next call will provoke an error but after that the old topology can be deleted - just ignore it!"
$InitialSearchTopology.Synchronize()
 
Write-Host -ForegroundColor Yellow "Deleting old topology"
Remove-SPEnterpriseSearchTopology -Identity $InitialSearchTopology -Confirm:$false
Write-Host -ForegroundColor Green "Old topology deleted"
Write-Host -ForegroundColor Green "Done - start a full crawl and you are good to go (search)."

The whole script took about 3 minutes on my machine.

image

 

References

I took some parts from here, but received some errors, some paramaters were missing so I adjusted the script for my needs.

The MSDN documentation is missing that there is a timer job responsible for topology changes – ULSViewer helped me to figure that one out.

Update 1, 24.07.2012 17:11

I exchanged some emails with Alpesh Nakar (funnily he created a script for the same thing) and he helped me reducing my script a lot. Thanks for that.

 

Did it work for you?

Missing FAST Search Center Template

26 Apr
April 26, 2012

Ever wondered where the FAST Search Center Template is and why the hack its not there when you create a new site?

Start this little powershell and you can create it:

$site = Get-SPSite -Identity <a title="Demo Link" href="http://melcher.it">http://sp2010.demo.com/sites/demo</a>
$site.Features.Add("5EAC763D-FBF5-4d6f-A76B-EDED7DD7B0A5")