Quantcast
Channel: SharePoint Diary
Viewing all 1058 articles
Browse latest View live

How to Create and Deploy SSRS 2012 Reports to SharePoint 2013

$
0
0
Reporting Services integrated with SharePoint 2013 gives you Rich enterprise reporting features. We've our SQL Server 2012 Reporting services integrated with SharePoint 2013 already. So now we can create reports for SharePoint 2013 using both SQL Server Report Builder 3.0 and using Visual Studio.

Lets create a SQL Server Reporting Services Report using Visual studio and publish to SharePoint 2013 site:
  1. Open Visual Studio 2010 Shell which comes with SQL Server 2012 (formerly “BIDS”), Choose New Project >> "Report Server Project Wizard" type, Give it a name. create SSRS report for SharePoint 2013
  2. This opens Report Project Wizard. Click Next
  3. We've to create a Data source for our report. Choose "New data source", Give it a name and choose Type. In my case, data is in SQL Server. Click on "Edit" button to specify SQL Server database
  4. From the connection Properties dialog box, Specify the Server Name and Database in which our required data live
  5. Now, We get the connection string for our data source. Click on Next
  6. Click on "Add Table" icon from Query Designer, Choose the Tables query, Click on "Add"
  7. Pick the columns to use in the Report. Click on OK.
  8. Now we got the query to use in our reports. Click on Next.
  9. Move fields to relevant sections, such as on Page, Group, and on Report Details section.
  10. Choose the deployment location. In our case its our SharePoint site. Enter Report server as our SharePoint site URL and Deployment Folder as any existing document library URL in our SharePoint site.
  11. Finally, Give a Name to the report. Click on Finish.
  12. One last but not least step is: Go to Project Properties >> Set the Target Locations. Say we've a document library called "Reports" in our SharePoint site. Specify the document library’s full path here. (Set all attributes!)Deploy SSRS to SharePoint
Build and deploy the project, and we are done!

Report Output:
Here is the report we've deployed to SharePoint.
SQL Server Reporting Services 2012 Report Published to SharePoint 2013
We can also use "SQL Server Reporting Services Web Part" to display the report on any location.
SSRS 2012 integrated with SharePoint 2013


Get All SharePoint Site Collections in Content Databases

$
0
0
During audit/migrations, we had a requirement to generate reports on SharePoint content databases and list of sites collections lives in each content database.

PowerShell script to Get all content databases and Site collection:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Get all SharePoint content databases available
$ContentDatabases = Get-SPContentDatabase
#Loop through each content database
foreach($ContentDb in $ContentDatabases)
{
Write-Host "`nContent Database Name: $($ContentDb.Name) Size:$($ContentDb.DiskSizeRequired/1MB) MB " -ForegroundColor DarkGreen
#Get all site collections in the content database
Write-Host "Site Collections List:" -ForegroundColor Blue
foreach($site in $ContentDb.Sites)
{
write-host $site.url
}
}
This PowerShell script outputs all SharePoint content databases with their size, and for each of the content database, it gives the list of site collections within the content database.

Get all site collections in a specific content DB:
Lets change the script slightly to get all site collections lives in a particular content database:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Set the Content Database Name
$ContentDbName = "SP2010_SharePoint_ContentDB"
#Get the Content Database
$ContentDb = Get-SPContentDatabase -Identity $ContentDbName
#Iterate through each site collection in the Content database
foreach($site in $ContentDb.Sites)
{
write-host $site.url
}
How to Find in Which Content Database a particular Site collection Lives?
Simple! Just use: Get-SPContentDatabase -site http://Site-Collection-URL

Create SSRS Report from SharePoint 2013 List using Report Builder 3.0

$
0
0
Reporting Service integrated with SharePoint provides a rich reporting platform. Lets see how we can create SQL Server reporting services report from SharePoint list data:

Create a Library for Reports and add Report Content Type
To start with, Lets create a Document Library,  Add Report Builder Report content type to create a new report.
  1. Go to Library Setting >> Advance Settings >> Select Yes for “Allow management of content types” and click on Yes.
  2. This Navigates to library settings again. Scroll down and Click on “Add from existing site content types” under “Content Types”
  3. Add “Report Builder Report” content type, and click on “OK”.
Create Report using Report Builder Tool
Go to Files Tab >> Click on drop down on "New Document" Ribbon button >> Choose "Report Builder Report"
sharepoint reporting services
This launches “Report Builder Client 3.0” installation for the first time. Wait for the ClickOnce installation to complete. 
sharepoint reporting services configuration
Make sure your SharePoint site is in trusted sites list in IE, otherwise, it won’t launch client application installation when you click on "Report Builder Report" for the first time!
In the Report Builder, Click on "New Report", choose the Table or Matrix Wizard.
sharepoint reporting services tutorial
Choose "Create a Dataset" option and click on "Next" button
sharepoint reporting services integration
Click on New to create new data source for the report.
sharepoint list reporting services data source
Give a Name to Data source and choose connection type as "Microsoft SharePoint List" and enter the connection string as the URL of your SharePoint site. Click on Credentials Tab
sharepoint reporting services list
Specify the relevant credential settings.
Verify the connection properties by click on "Test Connection" button
Choose the SharePoint lists you want to present as a Report.
Pick the Fields to display.
sharepoint reporting services examples
Set Grouping, Sub-total, Grand Total options
Select the style for your report
 sharepoint 2010 reporting services list
 And finally, we will save our report in the document library we have created in the early step.
That's all. Add Reporting Services Web part to desired locations and point to the report we've created. Here is the SharePoint reporting services from list:
sharepoint reporting services list
Now these reports can be export to Excel, PDF, Word, etc. BTW, Its also possible to build the same report using Visual Studio. Refer: How to Create and Deploy SSRS 2012 Reports to SharePoint 2013

Here is an another related article: SQL Server 2012 Reporting Services and SharePoint 2013 integration configuration

The server was unable to save the form at this time. Please try again

$
0
0
Got this error message when trying to save a new list item. SharePoint didn't allow me save!
The server was unable to save the form at this time. Please try again.

It also repeated in few more situations like when trying to create new custom list, trying to add new folder, When performing a Search, etc.

Cause: Observed, This issue is closely related to server memory.

Solution:
Add more memory (RAM) to resolve this issue permanently!

As for temporary workaround, you can try these solutions:
  • Monitor your Server RAM usage. Try closing some programs running on the server.
  • Restart "Search Host Controller Service" service in Services console (services.msc)
  • Perform IISReset on SharePoint wFE(s)
  • Make sure anonymous authentication enabled for SharePont web application in IIS
  • Run IE with out any Add-ons. You can also try using browsers other than IE (Try with Firefox/Chrome)
  • If Security Token Service is in stopped state, Start it. Try recycling it, if its already started.

Find and Delete Orphaned Alerts in SharePoint

$
0
0
Problem Description: In Short - When users leave your organisation and removed from Active Directory (AD) they become orphans in SharePoint! Also their alerts!!

Why we care about them: To keep SharePoint clean, we've to remove em' from all SharePoint sites. So, I've written a PowerShell script to scan all site collections of the web application, find and remove orphaned users from SharePoint here: Find and Delete Orphaned Users in SharePoint with PowerShell

Well, that solves the problem? kind of, but we have one more orphan to clean-up: SharePoint alerts created for orphaned users! Alright, Not a difficult task, Lets make use of the existing script, modify it little, run it before deleting orphaned users!
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Function to Check if an User exists in AD
function CheckUserExistsInAD()
{
Param( [Parameter(Mandatory=$true)] [string]$UserLoginID )
#Search the User in AD
$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
foreach ($Domain in $forest.Domains)
{
$context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain", $Domain.Name)
$domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($context)
$root = $domain.GetDirectoryEntry()
$search = [System.DirectoryServices.DirectorySearcher]$root
$search.Filter = "(&(objectCategory=User)(samAccountName=$UserLoginID))"
$result = $search.FindOne()
if ($result -ne $null)
{
return $true
}
}
return $false
}

#Get All site collections of all web applications
$sites = Get-SPWebApplication | Get-SPSite -Limit All
#Iterate through each site collection
foreach($site in $sites)
{

Write-Host "Processing Site:"$site.Url -ForegroundColor Magenta
foreach($Web in $site.AllWebs)
{
#Arrays to Hold Orphaned Alerts & Users
$OrphanedAlerts = @()
$AlertUsers = @()
#Get all Alerts created on the web
$WebAlerts = $web.Alerts
#Get Unique Users from All Alerts
$AlertUsers = $web.Alerts | foreach { $_.User } | Select-Object -Unique

#Check if any user with alerts is :Orphan!
if($AlertUsers.length -gt 0)
{
foreach($AlertUser in $AlertUsers)
{
#Write-host "Checking User:"$AlertUser
#Check if the user is valid - Not Orphan
$UserName = $AlertUser.UserLogin.split("\") #Get User Name from : Domain\UserName
$AccountName = $UserName[1] #UserName
if ((CheckUserExistsInAD $AccountName) -eq $false)
{
$OrphanedAlerts+=$AlertUser.Alerts
}
}
if($OrphanedAlerts.Length -gt 0)
{
Write-Host "Total No. of Orphaned Alerts Found:" $OrphanedAlerts.Length -ForegroundColor Red
#Delete each orphaned alert
foreach ($OrphAlert in $OrphanedAlerts)
{
write-host "`nOrphaned Alert:" $OrphAlert.ID" on "$web.Url "List:" $OrphAlert.ListUrl "User:"$OrphAlert.User
Write-Host "Deleting Orphaned Alert..."
#$WebAlerts.Delete($OrphAlert.ID)
}
}
}
}
}

This PowerShell script scans and deletes all alerts created for Orphaned users. Please note, I've commented out the line:
#$WebAlerts.Delete($OrphAlert.ID)
Just run the script to see how many alerts on what lists & libraries, Un-comment the above line by removing the # to actually remove orphaned alerts in SharePoint.

jQuery Rotating Banner for SharePoint

$
0
0
In continuation to my earlier post Rotating Banner for SharePoint using jQuery, one enhancement requested by people is: The ability to dynamically fetch images from SharePoint library, so that new banner images can be easily added, existing banners can be modified with out touching the banner code.

So, I've made changes to fulfill these requirement. Now the new rotating banner code dynamically fetches banner images from a specified library using SharePoint web Services and renders the rotating banner on SharePoint. Also the target URL is now editable from SharePoint UI.

Steps to implement jQuery Rotating Banner for SharePoint
  • Step 1: Drop a mail to "SharePoint.Crescent@gmail.com" with subject "jQuery Rotating Banner for SharePoint" to get the complete source code jQuery-Rotating-Banner.zip instantly! This zip file contains all scripts, style sheets and sample images for the banner. Extract them to your local folder.
  • Step 2: Create a new picture library (or even document library can do!), name it as "banner", Open the library in explorer view and upload all files including "images" folder and its files extracted from the jQuery-Rotating-Banner.zipfile.
    jquery sharepoint image rotator
    Important: Make sure all of your SharePoint site users granted at least "Read" access to the banner library!
  • Step 3: Create a new Hyperlink column in your banner library, name it as "Target"
     image slider sharepoint 2013
  • Step 4: Go to "images" folder under your banner library, set the target URL for the banners, So that when users click on the rotating banner images, they'll be redirected to respective pages.
    sharepoint jquery banner rotator
  • Step 5: Edit banner.htm and style.css files: Find and replace the hard coded link: "http://sharepoint.crescent.com" with your SharePoint site's URL where you created "banner" library.
  • Step 6: Add a content editor web part, Edit web part properties, Specify the content link as the "banner.htm" file which is located in the "banner" library.
This zip file also contains a static version (banner images are hard-coded) which can be used in not just SharePoint sites but on any site. Here is the sample of the jQuery rotating banner in SharePoint 2010:
jQuery Rotating Banner for SharePoint 2010

Rotating banner/Image Slider for SharePoint 2013 using jQuery:
jQuery Rotating Banner for SharePoint 2013
Banner Code:
<!DOCTYPE HTML>
<html>
<head>
<title>jQuery Rotating Banner coded by http://www.SharePointDiary.com</title>

<link href="http://sharepoint.crescent.com/banner/style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="http://sharepoint.crescent.com/banner/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="http://sharepoint.crescent.com/banner/jquery.cycle.all.js"></script>
<script type="text/javascript" src="http://sharepoint.crescent.com/banner/jquery.easing.1.3.js"></script>
<script type="text/javascript" src="http://sharepoint.crescent.com/banner/jquery.backgroundpos.js"></script>

<script type="text/javascript">
$(window).bind("load", function() {
setTimeout(function() {
$('.slideshow').cycle({
fx: 'scrollHorz',
delay: 0,
speed: 500,
rev: 0,
next: '.nextArrow',
prev: '.prevArrow'
});
}, 2000);
});

$(document).ready(function() {
var soapEnv =
"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
<soapenv:Body> \
<GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
<listName>banner</listName> \
<viewFields> \
<ViewFields> \
<FieldRef Name='Title' /> \
<FieldRef Name='Target' /> \
</ViewFields> \
</viewFields> \
<queryOptions> \
<QueryOptions> \
<ViewAttributes Scope='RecursiveAll'/> \
<Folder>http://sharepoint.crescent.com/banner/images</Folder> \
</QueryOptions> \
</queryOptions> \
</GetListItems> \
</soapenv:Body> \
</soapenv:Envelope>";

$.ajax({
url: "http://sharepoint.crescent.com/_vti_bin/lists.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: processResult,
contentType: "text/xml; charset=\"utf-8\""
});
});

function processResult(xData, status) {
$(xData.responseXML).find("z\\:row").each(function() {
//Get Images from "Images" Folder
var Html=" <a href='" + $(this).attr("ows_Target").split(',')[0] +"'><img src='http://sharepoint.crescent.com/banner/images/" + $(this).attr("ows_FileLeafRef").substring($(this).attr("ows_FileLeafRef").indexOf('#')+1, $(this).attr("ows_FileLeafRef").length ) + "'></a>";

$("#slideimages").append(Html);

});
}

</script>
</head>
<body>
<div id="mainWrap">
<div class="banner">
<div class="innerWrap">
<div class="slideshow" id="slideimages">
</div>
<div class="prevArrow"></div>
<div class="nextArrow"></div>
</div>
</div>
</div>
</body>
</html>

Enable/Disable Custom Error by editing Web.Config using PowerShell

$
0
0
To reveal actual errors in SharePoint, we used to turn off custom error page by editing web.config file, located in the root of SharePoint virtual directory. sharepoint custom error page web.config
  • Open the web.config in Notepad
  • Search for "CallStack", Change it from "false" to "true"
  • Search for "CustomErrors mode", Change its value from "On" to "Off"
  • Save and Close.
Warning: Web.config file is highly sensitive! even a small typo may result your SharePoint site Crash!!

Typical SharePoint 2007 "Unknown Error"
sharepoint custom error web.config
 and SharePoint 2010's "An unexpected error has occurred"
 sharepoint 2010 web.config customerrors
Alright, Wouldn't it be a good idea to make these changes by PowerShell Scripts? Sure, Here is the PowerShell script to enable or disable SharePoint custom error page and reveal actual error by editing Web.Config file:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

Function ConfigureCustomError()
{
Param( [Parameter(Mandatory=$true)] [string]$WebAppURL, [parameter(Mandatory=$true)] $Option )
<#
.Description
This PowerShell function Enables / Disables SharePoint Custom Error by editing web.config file
.Example
ConfigureCustomError "http://sharepoint.crescent.com" "OFF"
This disables SharePoint's default custom error page and reveals actual error
.Link
http://www.sharepointdiary.com
http://twitter.com/SharePointdiary
.Inputs
$WebAppURL - Web Application URL in which the Custom Errors to be set
$Option - ON or OFF
.Outputs
Sets "CustomErrors mode" and "CallStack" values in web.config file
#>

#Get the web application
$WebApp = Get-SPWebApplication $WebAppURL
#Get the Web Application Zone
$Zone = $WebApp.AlternateUrls[0].UrlZone
# Get the IIS settings for the zone
$IISSettings = $WebApp.IISSettings[$zone]
# Get the path from the settings
$WebConfigPath = $IISSettings.Path.ToString() + "\web.config"

#Backup web.config file
$now = [datetime]::now.ToString('dd-MM-yyyy hh-mm-ss')
$BackupFile =$IISSettings.Path.ToString()+ "\web.config.$now"
copy-item $WebConfigPath -destination $BackupFile

#Get the Web.config File
$XMLDoc = new-object System.Xml.XmlDocument
$XMLDoc.Load($WebConfigPath)
switch($option)
{
"OFF" {
#Apply Change
$XMLDoc.get_DocumentElement()."sharepoint".safemode.callstack = "True"
$XMLDoc.get_DocumentElement()."system.web".customErrors.mode = "Off"
Write-Host "Custom Error Mode has been Disabled, Now you can get the actual errors!"
}
"ON" {
$XMLDoc.get_DocumentElement()."sharepoint".safemode.callstack = "False"
$XMLDoc.get_DocumentElement()."system.web".customErrors.mode = "ON"
Write-Host "Custom Error Mode has been Enabled, SharePoint displays default custom error Page!"
}
}
$XMLDoc.Save($WebConfigPath)
}
#Call the function to Turn OFF custom errors
ConfigureCustomError "http://sharepoint.crescent.com" "OFF"

SharePoint 2013 Maintenance Window Notifications

$
0
0
In continuation to my earlier post: Site Under Maintenance Page for SharePoint , While the solution serves the purpose perfectly by displaying a typical "Site under maintenance" page during occasions like SharePoint patching, upgrade, etc. wouldn't it be nice to intimate end-users about the planned maintenance window in advance?

Well, SharePoint 2013 brings a new class SPMaintenanceWindow to support planned maintenance windows. Here is how it works: Prior to planned maintenance window schedules, You set the maintenance window on SharePoint content databases to display a notification to end users about the Planned maintenance window.

Once user hit SharePoint sites they'll see a notification banner on SharePoint 2013 sites notification area (On Top).  Here is the PowerShell script to set maintenance window notification in SharePoint 2013:

Add-PSSnapin Microsoft.sharepoint.powershell -ErrorAction SilentlyContinue

$WebAppURL = "http://sharepoint.crescent.com"

#Get all content databases of the web application
$ContentDbs = Get-SPContentDatabase -WebApplication $WebAppURL

#Create maintenance Window Object
$MaintenanceWindow = New-Object Microsoft.SharePoint.Administration.SPMaintenanceWindow
$MaintenanceWindow.MaintenanceEndDate = "12/31/2013 11:59:00 PM"
$MaintenanceWindow.MaintenanceStartDate = "12/29/2013 12:00:00 AM"
$MaintenanceWindow.NotificationEndDate = "12/31/2013 11:59:00 AM"
$MaintenanceWindow.NotificationStartDate = "12/25/2013 08:00:00 AM"
$MaintenanceWindow.MaintenanceType = "MaintenancePlanned" #Another Option: MaintenanceWarning
$MaintenanceWindow.Duration = "03:00:00:00" #in "DD:HH:MM:SS" format
$MaintenanceWindow.MaintenanceLink = "http://support.crescent.com/faq/SPMaintenanceWindow"

#Add Maintenance window for each content database of the web application
$ContentDbs | ForEach-Object {
#Clear any existing maintenance window
$_.MaintenanceWindows.Clear()

#Add New Maintenance Window
$_.MaintenanceWindows.add($MaintenanceWindow)
$_.Update()
}

The above script gets all content databases associated with the provided web application and sets the maintenance window for site collections residing on them. Here is the script in action:
Maintenance Windows in SharePoint 2013
You can get all of the SharePoint content databases of all web applications by skipping parameter -WebApplication in Get-SPContentDatabase cmdlet.
$ContentDbs = Get-SPContentDatabase

Once the maintenance window is completed, don't forget to clear it!
Get-SPContentDatabase | foreach-object {
$_.MaintenanceWindows.Clear()
$_.Update()
}

BTW, even though the banner says: Sites will be in Read-only mode, actually the script it self doesn't set sites so. We've to make the site collections read-only explicitly, if needed.

SharePoint 2013 Import Spreadsheet Errors and Solutions

$
0
0
Error:The list cannot be imported because a Microsoft SharePoint foundation-compatible spreadsheet application is not not installed or is not compatible with your browser.
The list cannot be imported because a Microsoft SharePoint foundation-compatible spreadsheet application is not not installed or is not compatible with your browser.

Solution: Use Internet Explorer 32 bit version!

How to Open Internet Explorer 32 bit version? Go to start >> Type "Internet Explorer" and pick the "Internet Explorer" link as in this screenshot.

Error:The specified file is not a valid spreadsheet or contains no data to import.
I'm sure the data is valid and in right format. I know the data is in right format, What's wrong?
SharePoint 2013 Import Spreadsheet Error: The specified file is not a valid spreadsheet or contains no data to import.  I'm sure the data is valid and in right format.

Solution: Well, SharePoint 2013 expects your SharePoint 2013 site to be in Trusted Sites List! So, Add your SharePoint site to Trusted Sites zone.

Here is How to Add SharePoint Site to Trusted Sites Zone:
Go to Internet Explorer >> Click on "Tools" Menu >> Internet Options >> Security >> Trusted Sites >> click on "Sites" button and Enter the URL of your SharePoint Site >> Click on "Add".
Add SharePoint Site to Trusted Sites Zone

How to Add Promoted Search Results using Query Rules in SharePoint 2013

$
0
0
We can promote search results based on specific search phrase entered by end-users in SharePoint 2013. The promoted results will appear on the top of the search results. As best bets/visual best bets are replaced with "Query Rules" in SharePoint 2013, this is a powerful way to promote search results within SharePoint 2013 to brought forward specific results to the users.

Scenario: Say, We've a dedicated site for HR Policies with all Human Resources related content and want to bring this site on top of Search results when user types search query as "HR Policies" or "HR Policy".

How to Add Promoted Search Results in SharePoint 2013 (AKA - Best Bets):
Assuming Search Service Application is configured up and running, Navigate to SharePoint 2013 Central Administration Site:
  1. Central Administration >> Application Management >> Manage Service Applications
  2. Click on the "Search Service Application" link, Which takes you to Search Administration page.
  3. Click on "Query Rules" link from left navigation.
  4. SharePoint 2013 Query Rules section seems bit confusing at the first look.
  5. Select a Result Source as "Local SharePoint Results" and Click on "New Query Rule" link.
  6. Give a Rule Name. Say, "HR Policies". Under Query conditions select "Query Matches Keyword Exactly" and enter Phrases as "HR Policies; HR Policy". Under "Actions" section, click on "Add Promoted Results" Link.
  7. Provide promoted result specifications, such as Result Title, URL, Description. Click on Save" button once done. Promoted results also can point to any document, list/librariy item as well.How to Add Promoted Search Results in SharePoint 2013
  8. Optionally, You can enable Publishing based on dates (When should the rule be active?)
  9. Click the "Save" button in the promoted results page and in the Query Rules Page.
Lets see the result: See the Promoted Results in action. See that the "HR Policies" appears on Top!
How to Add Promoted Search Results using Query Rules in SharePoint 2013
Tips: Promoted results can be set as Site/Site collection level too!

Document Expiration Monitor - Automation with PowerShell Script

$
0
0
Requirement: There are bunch of document libraries with several documents loaded on various site collections. We've to monitor their expiry date based on a column and send e-mail notification to all members of  a  SharePoint Group. Also all E-mails sent should be logged in a tracking list.

Solution: Lets write a PowerShell script to scan required document libraries and send E-mail. BTW - Its for MOSS 2007 (But the script works on any SharePoint versions, of course!)

PowerShell Script:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

##################################################################################
## VARIABLES SECTION ##
##################################################################################

$LibraryURLs = @("https://intranet.Crescent.com/sites/IT/docs/", "https://intranet.Crescent.com/sites/operations/inventory/", "https://intranet.Crescent.com/sites/Sales/documents")

### Variables for Email setup
#URL of the Site where the SharePoint group exists
$EmailGroupSite = "https://intranet.Crescent.com/sites/IT/"
#Name of the SharePoint Group to which emails to be sent
$EmailGroupName= "Report Group"

#Internal Name of the Column which stores the expiration date of documents
$ExpiryDateColumnInternalName = "Expiration_x0020_Date0"
#How to get the Internal name of a SharePoint Column?
#Refer http://www.sharepointdiary.com/2011/06/sharepoint-field-display-name-vs-internal-name.html

#Site URL where the tracking list "Document Expiration Monitor - Tracking" to be maintained
$TrackingSiteURL = "https://intranet.Crescent.com/sites/IT/"

$ExpiryDays = 7

$SMTPServer = "smtp.Crescent.com"

$EmailFrom = "DocumentExpiryMonitor@YOURCOMPANY.com"
$EmailSubject = "Document Expiration Monitor Report as on $(Get-Date)"

#Region Functions
###############################################################################
## FUNCTIONS ##
###############################################################################

#Functions for Get-SPSite & Get-Web in MOSS 2007
function global:Get-SPSite($url) {
return new-Object Microsoft.SharePoint.SPSite($url)
}

function global:Get-SPWeb($url) {
$site= New-Object Microsoft.SharePoint.SPSite($url)
if($site -ne $null) {
$web=$site.OpenWeb();
}
return $web
}

#Validate the Web at given URL
function Validate-Web($WebURL)
{
try {
$web = Get-SPWeb $WebURL
return $web
}
catch {
$Message = "Error in Site URL:$WebURL. Please provide valid Site URL!"
Write-Host $Message -ForegroundColor red
Append-LogMessage $Message $error[0]

#Continue executing code
continue

return $null
}
}

#Validate the Web at given URL
function Validate-SPSite($SiteURL)
{
try {
$Site = Get-SPSite $SiteURL
return $Site
}
catch {
$Message = "Error in Site Collection URL:$SiteURL."
Write-Host $Message -ForegroundColor red
Append-LogMessage $Message $error[0]

#Continue executing code
continue

return $null
}

}
#Function to validate given List URL
function Validate-List($ListURL)
{
try {
$list = $web.GetList($ListURL)
return $list
}
catch {
$Message = "Error in List URL: $ListURL! Please provide valid List URL!"
Write-Host $Message -ForegroundColor red
Append-LogMessage $Message $error[0]

#Continue executing code
continue

return $null
}
}

function Send-Email ($EMailBody, $EmailTo) {
try {
#Send the Mail
$MailMessageParameters = @{
SmtpServer = $SMTPServer
Subject = $EmailSubject
Body = $EmailBody
From = $EmailFrom
To = $EmailTo
}
Send-MailMessage @MailMessageParameters -BodyAsHtml
Append-LogMessage "Email has been sent to :"$EmailTo
}
catch {
Write-Host "Error sending email, Please check log file!" -ForegroundColor Red
Append-LogMessage $error[0]
}
}

#Function to Get the Location where script is located
function GetScriptDir
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
return Split-Path $Invocation.MyCommand.Path
}

#Extract Emails from each user in a Group
function Get-GroupEmails()
{
try {
$Emails=@()
$Site = Validate-SPSite $EmailGroupSite
if($site -ne $null)
{
$Group = $site.RootWeb.sitegroups | Where {$_.Name -match $EmailGroupName}
#$Group= $web.SiteGroups[$GroupName]
if($Group -ne $null)
{
$Users = $Group.Users
foreach ($User in $Users)
{
if( ($user.Email -ne "") -and ($user.Email -ne $null) )
{
$Emails+=$user.Email
}
}
$Emails = $Emails -split ","
return $Emails
}
else
{
$Message = "E-mail Group Name:$EmailGroupName Not found!"
Write-Host $Message -ForegroundColor red
Append-LogMessage $Message $error[0]
return $null
}
}
}
catch {
$Message = "Error in Get-GroupEmails Function!"
Write-Host $Message -ForegroundColor red
Append-LogMessage $Message $error[0]

#Continue executing code
continue

return $null
}
}

#Function to Log details to Tracking List
function LogTo-TrackingList($EmailBody)
{
$web = Validate-Web $TrackingSiteURL
if($web -eq $null)
{
# Creating base file to append to, adding a new line for readability
$Message = "Tracking Site URL is not valid!"
Write-Host $Message -ForegroundColor Red
Append-LogMessage $Message
return
}

#Try to Get the "Tracking List"
$TrackingList = $web.Lists | Where { $_.Title -match "Document Expiration Monitor - Tracking"}

#If Tracking list doesnt exist, Create it
if($TrackingList -eq $null)
{
#Create New Tracking List
$TrackingListID = $Web.Lists.Add("DEMTracking","List to Track Document Expiration Monitor Mails",[Microsoft.SharePoint.SPListTemplateType]::GenericList)
#Set Name for the List
$TrackingList = $web.Lists[$TrackingListID]
$TrackingList.Title="Document Expiration Monitor - Tracking"
$TrackingList.update()

#Rename the "Title Field" to Tracking ID
$TitleField = $TrackingList.Fields.GetFieldByInternalName("Title")
#Set Field Display Name and Update
$TitleField.Title ="Tracking Date"
$TitleField.Update()

#Add Email Body Field
$EmailBodyField = $TrackingList.Fields.Add("Email Body","Note",$true)
$trackingList.Fields["Email Body"].RichText = $True
$trackingList.Fields["Email Body"].RichTextMode = "FullHtml"
$trackingList.Fields["Email Body"].update()

}
#Add New Item to Tracking List
$item = $TrackingList.Items.Add()
#Set the Tracking Date & Email Body field values
$item["Email Body"] = $EmailBody

#Set the Tracking Date field
$item["Tracking Date"] = $TodaysDate
$item.update()

#Log details to Tracking List
$web.dispose()

}

# Appends text to the log message
function Append-LogMessage($text)
{
Add-Content $LogTextFileName $text"`r" -Encoding UTF8
}

#EndRegion

#Variables for Internal processing
$ScriptPath = GetScriptdir

#Get the Template HTM File with CSS
$MailContent = Get-Content -Path "$ScriptPath\template.htm" -Encoding UTF7 | Out-String

$CAMLDateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
$DateFormat = "MM/dd/yyyy"

$TodaysDate = Get-date
$TodaysDateFormatted = (Get-date).ToString($CAMLDateFormat)
$ExpirationDate = (Get-Date).AddDays($ExpiryDays)
$ExpirationDateFormatted = (Get-Date).AddDays($ExpiryDays).ToString($CAMLDateFormat)
$LogTextFileName = "$ScriptPath\DEM_LOG.txt"
$Message =""

# Creating base file to append to, adding a new line for readability
$Message = "Script Execution Started at $TodaysDate." >> $LogTextFileName
Write-Host $Message -ForegroundColor DarkGreen
Append-LogMessage $Message

###############################################################################
## PROCESS EACH DOCUMENT LIBRARY AND SEND EMAIL ##
###############################################################################

########## Process "Expiring Documents" ###########
$MailContent+= "<h2> Document Expiry Monitor - Report as on : $(Get-Date) </h2>"
$ExpiringContentHeader = "<h3 style='color: #333399;'> List of Expiring Documents: </h3> <table class='altrowstable' cellpadding='5px' cellspacing='5'><tr><th>Document Name </th><th>Created By</th><th>Created on</th><th> Expiry Date </th><th> URL </th></tr>"
$MailContent += $ExpiringContentHeader
$ExpiringContent=""
$ExpiredContent=""

# Loop through items and Get all Expiring Documents
foreach ($ListURL in $LibraryURLs)
{
#Get the web
$web = Validate-Web $ListURL

if($web -eq $null) {
#Skip the current list and proceed with the next from array
continue
}

#Get the List
$list = Validate-List $ListURL
if($list -eq $null) {
#Skip the current list and proceed with the next from array
continue
}

#Check if the list has the "Expiration Date" Column
if ($list.Fields.GetFieldByInternalName($ExpiryDateColumnInternalName) -eq $false)
{
$Message = "$ListURL does not contains Expiration Date Field specified!"
Write-Host $Message -ForegroundColor red
Append-LogMessage $Message

#Skip the current list and proceed with the next from array
continue
}

# Write out the dates we're looking for
$Message = "Searching $ListURL for Expiring documents with Expiration Date between " + $TodaysDate + " - " + $ExpirationDate
Write-Host $Message -ForegroundColor DarkGreen
Append-LogMessage $Message

# Get all Expiring Documents
$ExpiringQuery = '<Where><And><Geq><FieldRef Name="' + $ExpiryDateColumnInternalName + '" /><Value Type="DateTime" IncludeTimeValue="True">' + $TodaysDateFormatted +

'</Value></Geq><Leq><FieldRef Name="' + $ExpiryDateColumnInternalName + '" /><Value Type="DateTime" IncludeTimeValue="True">' + $ExpirationDateFormatted + '</Value></Leq></And></Where>'
$SPExpiringQuery = new-object Microsoft.SharePoint.SPQuery
$SPExpiringQuery.ViewAttributes = "Scope='Recursive'"
$SPExpiringQuery.Query = $ExpiringQuery
$ExpiringListItems = $List.GetItems($SPExpiringQuery)
$Message = "Found " + $ExpiringListItems.Count + " Expired document(s)."
Write-Host $Message -ForegroundColor DarkGreen
Append-LogMessage $Message

#If There are some expiring documents found
if($ExpiringListItems.Count -gt 0)
{
foreach($Item in $ExpiringListItems)
{
$ExpiringContent+= "<tr> <td> $($item.Name) </td> <td> $($item.File.Author.Name) </td> <td> $($item.File.TimeCreated.ToString($DateFormat)) </td> <td> $($Item

[$ExpiryDateColumnInternalName].ToString($DateFormat)) </td> <td> <a href='$($web.URL)/$($item.URL)'>$($web.URL)/$($item.URL)</a> </td> </tr>"
}
}
}
if($ExpiringContent.Length -eq 0)
{
$ExpiringContent+= "<tr> <td colspan=5> No Expiring Documents Found! </td> </tr>"
}
$ExpiringContent+= "</table><br/>"

$MailContent += $ExpiringContent

########## Process "Expired Documents " ###########
$ExpiredContentHeader = "<h3 style='color: #660033;'> List of Expired Documents: </h3> <table class='altrowstable' cellpadding='5px' cellspacing='5'><tr><th>Document Name </th><th>Created

By</th><th>Created on</th><th> Expiry Date </th><th> URL </th></tr>"
$MailContent += $ExpiredContentHeader

$ExpiredContent=""
# Loop through items and Get all Expired Documents
foreach ($ListURL in $LibraryURLs)
{
if($web -eq $null) {
#Skip the current list and proceed with the next from array
continue
}

#Get the List
$list = Validate-List $ListURL
if($list -eq $null) {
#Skip the current list and proceed with the next from array
continue
}

#Check if the list has the "Expiration Date" Column
if ($list.Fields.GetFieldByInternalName($ExpiryDateColumnInternalName) -eq $false)
{
$Message = "$ListURL does not contains Expiration Date Field specified!"
Write-Host $Message -ForegroundColor red
Append-LogMessage $Message

#Skip the current list and proceed with the next from array
continue
}

# Write out the dates we're looking for
$Message = "Searching $ListURL for Expired documents with Expiration Date between " + $TodaysDate + " - " + $ExpirationDate
Write-Host $Message -ForegroundColor DarkGreen
Append-LogMessage $Message

# Get all Expired Documents
$ExpiredQuery = '<Where><Lt><FieldRef Name="' + $ExpiryDateColumnInternalName + '" /><Value Type="DateTime" IncludeTimeValue="True">' + $TodaysDateFormatted + '</Value></Lt></Where>'
$SPExpiredQuery = new-object Microsoft.SharePoint.SPQuery
$SPExpiredQuery.ViewAttributes = "Scope='Recursive'"
$SPExpiredQuery.Query = $ExpiredQuery
$ExpiredListItems = $List.GetItems($SPExpiredQuery)

$Message = "Found " + $ExpiredListItems.Count + " Expired document(s)."
Write-Host $Message -ForegroundColor DarkGreen
Append-LogMessage $Message

#If There are some expired documents found
if($ExpiredListItems.Count -gt 0)
{
foreach($Item in $ExpiredListItems)
{
$ExpiredContent+= "<tr> <td> $($item.Name) </td> <td> $($item.File.Author.Name) </td> <td> $($item.File.TimeCreated.ToString($DateFormat)) </td> <td> $($Item

[$ExpiryDateColumnInternalName].ToString($DateFormat)) </td> <td> <a href='$($web.URL)/$($item.URL)'>$($web.URL)/$($item.URL)</a> </td> </tr>"
}
}
}
if($ExpiredContent.Length -eq 0)
{
$ExpiredContent+= "<tr> <td colspan=5> No Expired Documents Found! </td> </tr>"
}
$ExpiredContent+= "</table><br/>"


$MailContent += $ExpiredContent
$MailContent += "</body></html>"

#Email the Body
$EmailAddresses = Get-GroupEmails
if($EmailAddresses -ne $null)
{
Send-Email $MailContent $EmailAddresses
}

#Log to Tracking table
LogTo-TrackingList $MailContent

###############################################################################
## CLEAN UP ##
###############################################################################

# Log end of processing
$Message = "Finished Processing Document Expiration Monitor Script by $(Get-Date)."
Write-Host $Message -ForegroundColor DarkGreen
Append-LogMessage $Message

# Dispose of the web object
$web.Dispose()

Template.htm File content:
<html>
<head>
<!-- CSS goes in the document HEAD or added to your external stylesheet -->
<style type="text/css">
body{
font-family: Calibri;
height: 12pt;
}
table.altrowstable {
border-collapse: collapse;
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #a9c6c9;
border: b1a0c7 0.5pt solid;
}
table.altrowstable th {
border-width: 1px;
padding: 5px;
background-color:#8064a2;
border: #b1a0c7 0.5pt solid;
font-family: Calibri;
height: 15pt;
color: white;
font-size: 11pt;
font-weight: 700;
text-decoration: none;
}
table.altrowstable td {
border: #b1a0c7 0.5pt solid; font-family: Calibri; height: 15pt; color: black; font-size: 11pt; font-weight: 400; text-decoration: none;
}
</style>
</head>
<body>

PowerShell Script in Action:
Tracking List:

Force Run SharePoint Health Analyzer Jobs on Demand

$
0
0
We may want to run SharePoint health analyzer on-demand to check if everything is alright in the farm, without waiting for them to run automatically. Well, as discussed in my another article, Run SharePoint 2010 Timer Jobs On-Demand with PowerShell , we can force run SharePoint Health Analyzer timer Jobs on Demand with PowerShell!

How to run SharePoint 2010/2013 health analyzer with PowerShell:
Lets use PowerShell to force run health analyzer jobs.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Display name of the Timer Job to Run on-demand
$TimerJobName = "Health Analysis Job"

#Get the Timer Job
$TimerJobs = Get-SPTimerJob | where { $_.DisplayName -match $TimerJobName}

foreach($TimerJob in $TimerJobs)
{
Write-Host "Running:" $TimerJob.DisplayName
$TimerJob.RunNow()
}
This script executes all timer jobs with "Health Analysis Job" in its display name which performs health check immediately!
Run SharePoint 2013 Health Analyzer Jobs on Demand

One Liner to SharePoint 2010/2013 run all health analyzer:
Get-SPTimerJob | where { $_.DisplayName -match "Health Analysis Job"} | % { Start-SPTimerJob $_ ; Write-Host "Runing Job:" $_.displayName } # 

Find Top 10 Site Collections based on its Usage during Last Month

$
0
0
PowerShell Script to find top 10 SharePoint 2007 site collections based on its usage hits:

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

#Functions to Imitate SharePoint 2010 Cmdlets in MOSS 2007
function global:Get-SPWebApplication($WebAppURL)
{
return [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($WebAppURL)
}

function global:Get-SPSite($url) {
return new-Object Microsoft.SharePoint.SPSite($url)
}

function global:Get-SPWeb($url) {
$site= New-Object Microsoft.SharePoint.SPSite($url)
if($site -ne $null) {
$web=$site.OpenWeb();
}
return $web
}

#Get all site collections of the provided web application
$WebApp = Get-SPWebApplication "https://intranet.crescent.com"
$SitesCollection = $WebApp.Sites

$UsageDataCollection = @()
#Iterate through each site collection
ForEach($site in $SitesCollection)
{
$web = Get-SPWeb $site.URL
$LastMonthUsage = ($web.GetUsageData("url", "lastMonth") | sort 'Total Hits')
If($LastMonthUsage -ne $null)
{

$totalHits = ($LastMonthUsage | Measure-Object 'Total Hits' -Sum | Select -expand Sum)

$UsageDataResult = New-Object PSObject
$UsageDataResult | Add-Member -type NoteProperty -name "Site Collection URL" -value $site.URL
$UsageDataResult | Add-Member -type NoteProperty -name "Site Title" -value $web.title
$UsageDataResult | Add-Member -type NoteProperty -name "Total Hits" -value $totalHits

$UsageDataCollection += $UsageDataResult

#Clear variables
$LastMonthUsage = $null
$tHits = $null
}
}

$UsageDataCollection | sort-object "Total Hits" -descending | select-object -first 10 | Export-csv "Top10Sites.csv" -notypeinformation
For SharePoint 2010 and above, Use Web Analytics Web Part!

SharePoint 2010/2013 Search Query Suggestions

$
0
0
Search suggestions are one of the great new feature introduced in SharePoint 2010, enhanced in SharePoint 2013. Search query suggestions are words that appear under the search box as users type a Search query. (also known as: Pre-query suggestions).

SharePoint Search suggestions are automatically generated:
When users have clicked any of the search results for that query at least six times, then that query will be automatically added to search suggestions. Technically, on a daily basis, the SharePoint timer job titled "Prepare Query Suggestions" handles compiling them. So the automatic query suggestions can be different for different result sources and site collections.

Although Search query suggestions are auto populated based on user searches, It would be helpful to manually add search query suggestions to promote specific areas of your SharePoint. Isn't it?

How to Add SharePoint 2010 Search Suggestions using PowerShell:
Lets add SharePoint 2010 search suggestions with PowerShellscript.

Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue

#Set the Terms to add in Search Suggestions
$SearchSuggestions = @("Crescent", "Crescent Policies", "Crescent News", "Crescent Tech", "Crescent Employee Of the Month", "Crescent Travel Request")

#Get the Search Service Application "Search Service Application" - Your's may be in different name
$ssa = Get-SPEnterpriseSearchServiceapplication -Identity "Search Service Application"

#Process Each Search Term
foreach ($Suggestion in $SearchSuggestions)
{
New-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $ssa -Language en-US -Type QuerySuggestionAlwaysSuggest -Name $Suggestion
}

#Trigger the Timerjob
$timerJob = Get-SPTimerJob "Prepare query suggestions"
$timerJob.RunNow()
Instead of having them in a hard-coded array, Its also possible to have them in a CSV file and import them:
$csvfile = "D:\SearchSuggestions.csv" #with header "Suggestion"
$KeyWordsData = Import-Csv $csvfile
...

foreach ($Row in $KeywordsData)
{
New-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $ssa -Language en-US -Type QuerySuggestionAlwaysSuggest -Name $Row.Suggestion
}
...
You can get the Search service application name by navigating to central admin and manage service applications page.

SharePoint 2010 search query suggestions not working? Run the timer job: "Prepare Query Suggestions". Also, make sure SharePoint 2010 Show Query Suggestions option is enabled in search box web part properties!
sharepoint 2010 search query suggestions not working

 Result: As a user types keywords in the Search box, the Search Center provides suggestions to help complete the query
sharepoint 2010 search query suggestions

To Get all SharePoint 2013 search query suggestions:
#Get the Search Service Application "Search Service Application" by its name
$ssa = Get-SPEnterpriseSearchServiceapplication -Identity "Search Service Application"
#Get all Search Query suggestion
Get-SPEnterpriseSearchQuerySuggestionCandidates -SearchApplication $ssa

Remove a Search Suggestion using PowerShell:
Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue

#Get the Search Service Application "Search Service Application" by its name
$ssa = Get-SPEnterpriseSearchServiceapplication -Identity "Search Service Application"

#Remove Search Query Suggestion "Crescent Employee Of the Month"
Remove-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $ssa -Language En-Us -Type QuerySuggestionAlwaysSuggest -Identity "Crescent Employee Of the Month"

#Trigger the Timerjob for the changes to take effect
$timerJob = Get-SPTimerJob "Prepare query suggestions"
$timerJob.RunNow()


How to Add SharePoint 2013 search query suggestions manually:
Go to Central Administration>> Manage service applications>> Search Service Application>> Click on Query Suggestions link from left navigation. From here, you can enable/disable, Import/Export your custom search query suggestions.
sharepoint 2013 query suggestions

BTW, importing query suggestions overwrites any existing manual query suggestions created already! So, Export them first, modify and then import again!!


Whats new in SharePoint 2013 search query suggestions:
Things are slightly different in SharePoint 2013, as it allows customizing Search parameters at SSA/Site collection/Site level. So, We've an additional parameter "Owner" to specify the scope. Also, query suggestions have improved in SharePoint 2013 with result sources. The query suggestions are generated daily for each result source - each site collection.

Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue

#Set the Terms to add in Search Suggestions
$SearchSuggestions = @("Crescent", "Crescent Policies", "Crescent News", "Crescent Tech", "Crescent Employee Of the Month", "Crescent Travel Request")

#Get the default search service application
$ssa = Get-SPEnterpriseSearchServiceApplication
#You can also use: Get-SPEnterpriseSearchServiceapplication -Identity "Search Service Application"

$owner = Get-SPEnterpriseSearchOwner -level SSA

#Process Each Search Term
foreach ($Suggestion in $SearchSuggestions)
{
New-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $ssa -Language En-Us -Type QuerySuggestionAlwaysSuggest -Name $Suggestion -Owner $owner
}
#Trigger the SharePoint 2013 query suggestions timer job
Start-SPTimerJob -Identity "Prepare query suggestions"
Don't forget to Run the SharePoint 2013 query suggestions timer job!

Remove Search Suggestions at SSA level in SharePoint 2013:
Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue

#Get the default search service application
$ssa = Get-SPEnterpriseSearchServiceApplication

#Set the Query Suggestion Level
$owner = Get-SPEnterpriseSearchOwner -level SSA

#Get All Existing phrases
$SuggestionList = Get-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $ssa -Owner $Owner -Language En-Us -Type QuerySuggestionAlwaysSuggest #-SourceId $ResultSource.Id

#Remove Them All
$SuggestionList | Remove-SPEnterpriseSearchLanguageResourcePhrase -Type QuerySuggestionAlwaysSuggest -Language "en-us" -Owner $Owner

#Trigger the SharePoint 2013 query suggestions timer job
Start-SPTimerJob -Identity "Prepare query suggestions"

Add Query Suggestions at Site Level in SharePoint 2013:
Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue

#Set the Terms to add in Search Suggestions
$SearchSuggestions = @("Crescent", "Crescent Policies", "Crescent News", "Crescent Tech", "Crescent Employee Of the Month", "Crescent Travel Request")

#Get the default search service application
$ssa = Get-SPEnterpriseSearchServiceApplication

$Web = Get-SPweb -Identity "http://sharepoint.crescent.com/sites/operations/"

$owner = Get-SPEnterpriseSearchOwner -Level SPWeb -SPWeb $web

$FederationManager = New-Object Microsoft.Office.Server.Search.Administration.Query.FederationManager –ArgumentList $ssa

$ResultSource = $FederationManager.GetSourceByName("Local SharePoint Results", $owner)

#Process Each Search Term
foreach ($Suggestion in $SearchSuggestions)
{
New-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $ssa -Language En-Us -Type QuerySuggestionAlwaysSuggest -Name $Suggestion -Owner $owner -SourceId $ResultSource.Id
}

#Its also possible to use PowerShell to Import Search Suggestions from text file using PowerShell
#$ssap = Get-SPEnterpriseSearchServiceApplicationProxy
#Import-SPEnterpriseSearchPopularQueries -SearchApplicationProxy $ssap -Filename "D:\querySuggestions.txt" -ResultSource $source -Web $web

#Trigger the timer job
Start-SPTimerJob -Identity "Prepare query suggestions"
That is it you have added a query suggestion to your SharePoint searh box. Now you start typing SharePoint it will will bring SharePoint suggestion.
sharepoint search box query suggestions

SharePoint Rich Text Editor Toolbar Missing - Solution

$
0
0
User reported an issue: SharePoint rich text editor toolbar is missing on list columns!
SharePoint Rich Text Editor Toolbar Missing
I verified that the SharePoint list columns are enabled with "Rich Text" capabilities, but still rich text editor toolbars are missing!

Solution: Open SharePoint site in Internet Explorer 32 bit mode! Here is how: Type "Internet explorer" in Start menu, Choose "Internet Explorer" link as in the screen.


Here is the Rich text editor/multi-line column with rich text editing toolbar:

SharePoint Number Column without Commas

$
0
0
Problem: SharePoint Number columns shows , (comma) in View/Display Forms. There are specific numeric columns, User wanted to display without commas.

There is no direct way to remove comma/avoid thousand separator in SharePoint Number fields, But the below tricks help to get SharePoint 2007/2010/2013 number column values without commas.

Solutions:
Here are some solutions to show number fields without comma:
  1. Use "Single Line of Text" instead of "Number" column type, if possible. (But this will not stop users from entering alpha characters!)
  2. Use an another Calculated column with formula: = TEXT( Number_Column_Name, "0") . If you need sorting, you can use: =FIXED(Number_Column_Name,0,TRUE) 
  3. Add Integer field programmatically (As there is no interface to do this!)
    #Get all site collections of the provided web application
    $Web = Get-SPWeb "http://projects.crescent.com/sites/Corp"

    $ListName = "ProjectBudget"

    $list = $web.lists[$ListName]

    $list.Fields.Add("TotalValue", [Microsoft.SharePoint.SPFieldType]::Integer, $false)
  4. If its for a view, You can use Dataview/XSLT web part with "format-number" formula as: <xsl:value-of select='format-number(TotalValue,"#.00") '/>
 sharepoint 2010 format number column without comma

Get All SharePoint Site Collection Owners - Report

$
0
0
Requirement is to find out owners of each SharePoint site collection in the environment.We needed this data to get approvals on critical changes and to inform site owners prior to maintenance windows.

Simple! Use STSADM command:
On SharePoint 2007 and above, STSADM command can be used to get primary owner details of site collections:
Syntax:
stsadm -0 enumsites -url <web-app-url>
E.g.
stsadm -0 enumsites -url "http://sharePoint.crescent.com" > SitesRpt.xml

This command enumerates all site collections and pulls site owner information. It also retrieves secondary owner, content database in which site collection exist and storage details of the site collection. Just open the generated XML file with Microsoft Excel.

Find Site Owner for All site collections using PowerShell:
For SharePoint 2007 Sites, The PowerShell script to get site Owners for all Site collections would be:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

$WebAppUrl = "http://sharepoint.crescent.com" #Read-Host "Enter Web Application URL:"
$rootSite = New-Object Microsoft.SharePoint.SPSite($WebAppUrl)

#Get the Web Application from Site Collection
$WebApp = $rootSite.WebApplication

foreach($site in $WebApp.Sites)
{
Write-Host "$($Site.Url) - $($Site.Owner) : $($Site.Owner.Email)"
$site.Dispose()
}

Get All Site Owners in SharePoint 2010/2013:
On SharePoint 2010 and above, we can retrieve owner information with a single line of code:
Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue

Get-SPWebApplication "http://sharepoint.crescent.com" | Get-SPSite | foreach-object { Write-host $_.Url - $_.Owner.Email}

Get me all Site collections I own:
This time, I had to find out all site collections a particular user owns. No worries, PowerShell is so powerful!

Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue

Get-SPSite -Filter {$_.Owner -EQ "Global\Salaudeen"} -limit 100

For SharePoint Site Collection Administrators report, Refer: Site Collection Administrators Report for All SharePoint Sites

SharePoint Features Usage Report using PowerShell

$
0
0
Task: Generate a report for All Installed/Activated Features for the entire SharePoint Environment. Here are some nifty PowerShell scripts to find features installed on the farm as well as specific features activated on a particular scope.

Get-SPFeature cmdlet:
Get-SPFeature cmdlet retrieves all features installed on the environment, when "Scope" parameter's value is not supplied. It gets all activated features on the particular scope, when you provide scope parameter: (Such as : -site "http://sharepointsite.com". But Get-SPFeature -site Gets all site scoped features installed!)

Get a list of all installed SharePoint features, Grouped by feature scope:
Get-SPFeature | Sort-Object Scope | Format-Table -GroupBy scope
SharePoint Features Usage Report using PowerShell

Lets export to a text file:
Get-SPFeature | Sort -Property Scope, DisplayName | Ft -Autosize -GroupBy Scope DisplayName, Id > D:\FeaturesReport.txt

To get all features activated at a particular web application scope, Use:
Get-SPFeature -WebApplication "web-app-url"
#Similarly:
#Get-SPFeature -Farm
#Get-SPFeature -Site $Site.URL
#Get-SPFeature -Web $web.URL

Get All Features along with their title:
Get-SPFeature | Format-Table @{Label='ID';Expression={$_.Id}}, 
@{Label='DisplayName';Expression={$_.DisplayName}},
@{Label='Title';Expression={$_.GetTitle(1033)}},
@{Label='Scope';Expression={$_.Scope}} -AutoSize | Out-File -Width 250
D:\AllFeatures.txt

Get All Feature Tiles and Description, Activated on a Particular Site collection:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

$siteurl = "http://sharepoint.crescent.com"

Get-SPFeature -Limit ALL -Site $siteurl | ForEach-Object {
$data = @{
Feature = $_.GetTitle(1033)
Description = $_.GetDescription(1033)
}
New-Object PSObject -Property $data;
} | Select-Object Feature, Description

Find all/specific Feature in SharePoint 2013 / SharePoint 2010:
Lets find and list where a feature is activated.
Add-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue

$FeatureName = "TemplateDiscovery"
#We can also use "FeatureID" instead of Feature DisplayName

# Get all Farm scoped features
#write-host "Farm scoped features:"
#Get-SPFeature -Farm

# To Search for a specific Farm scoped feature:
Get-SPFeature -Farm | where { $_.DisplayName -eq $FeatureName } #Eg SpellChecking

#Process All Web Applications
ForEach ($WebApp in Get-SPWebApplication)
{
write-host "`nProcessing Web Application:" $webapp.url
#Get All Web Application Scoped features
#Get-SPFeature -WebApplication $WebApp.url

# To Search for a specific WebApplication scoped feature:
Get-SPFeature -WebApplication $WebApp.url | where { $_.DisplayName -eq $FeatureName }

#Process each site collection
foreach ($site in $WebApp.sites)
{
write-host "`tProcessing Site Collection: " $site.url
#Get All Site collection Scoped features
#Get-SPFeature -Site $site.url

# To Search for a specific Site Collection scoped feature:
Get-SPFeature -Site $site.url | where { $_.DisplayName -eq $FeatureName }

#Process each site
foreach ($web in $site.AllWebs)
{
write-host "`t`tProcessing Web: " $web.url
# Get All Web scoped features
#Get-SPFeature -Web $web

# To Search for a specific Site Collection scoped feature:
Get-SPFeature -Web $web | where { $_.DisplayName -eq $FeatureName }
}
}
}

Feature inventory for SharePoint 2007 using STSADM:
Stsadm -o enumallwebs -includefeature

Using PowerShell to find all features in MOSS 2007:
This script gets all activated features scoped at web application, Site Collection, Site scopes:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

Function global:Get-SPWebApplication($WebAppURL)
{
return [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($WebAppURL)
}

#Get the SharePoint Farm. Equallent to : Get-SPFarm commandlet
$Farm = [Microsoft.SharePoint.Administration.SPFarm]::Local

#Get All feature of the farm. Equallent to: Get-SPFeature commandlet
$FarmFeatures= $Farm.FeatureDefinitions

$WebAppURL = "http://SharePoint.Crescent.com"
$WebApp = Get-SPWebApplication $WebAppURL

#Scan Web Application Features
Write-Host "Features Activated at Web Application Level:" -ForegroundColor DarkGreen

foreach($feature in $WebApp.Features)
{
#Write-Host $feature.DefinitionId;
Write-Host $farmfeatures[$feature.DefinitionId].DisplayName
}

#Get All site collections of the Web Application
$SitesColl = $webApp.Sites

#Iterate through each site collection/sub-site
foreach($Site in $SitesColl)
{
Write-Host "`nFeatures Activated at SITE:" $site.Url -ForegroundColor DarkGreen

#Iterate through each feature activated at Site collection level
foreach($feature in $site.Features)
{
#Write-Host $feature.DefinitionId;
Write-Output $farmfeatures[$feature.DefinitionId].DisplayName;
}
foreach($web in $site.AllWebs)
{
Write-Host "`nFeatures Activated at WEB:" $web.Url -ForegroundColor DarkGreen
#Iterate through each feature activated at web level
foreach($Feature in $web.Features)
{
Write-Output $FarmFeatures[$Feature.DefinitionId].DisplayName;
#Write-Output $FarmFeatures[$Feature.DefinitionId].GetTitle(1033);
}
}
}

Get-SPFeature Cmdlet for SharePoint 2007:
Powershell script to report all SharePoint Farm Feature 
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

#Get the SharePoint Farm. Equallent to : Get-SPFarm commandlet
$Farm = [Microsoft.SharePoint.Administration.SPFarm]::Local

#Get All feature of the farm. Equallent to: Get-SPFeature commandlet
$FarmFeatures= $Farm.FeatureDefinitions
$FarmFeatures | Select ID,DisplayName, Scope | Sort-Object Scope | Format-Table -GroupBy Scope
Tip: To find out all SharePoint enterprise feature usage, use: PremiumWebApplication, PremiumSite, PremiumWeb accordingly on Feature Display Names.

Find a Particular Feature's usage in SharePoint 2007:
#Get-SPWebApplication Cmdlet for MOSS 2007
Function global:Get-SPWebApplication($WebAppURL)
{
if($WebAppURL -eq $null) #Get All Web Applications
{
$Farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
$websvcs = $farm.Services | where -FilterScript {$_.GetType() -eq [Microsoft.SharePoint.Administration.SPWebService]}
$WebApps = @()
foreach ($websvc in $websvcs)
{
foreach ($WebApp in $websvc.WebApplications)
{
$WebApps += $WebApp
}
}
return $WebApps
}
else #Get Web Application for given URL
{
return [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($WebAppURL)
}
}

#Get the SharePoint Farm. Equallent to : Get-SPFarm commandlet
$Farm = [Microsoft.SharePoint.Administration.SPFarm]::Local

#Get All feature of the farm. Equallent to: Get-SPFeature commandlet
$FarmFeatures= $Farm.FeatureDefinitions

#Feature to Search
$FeatureDisplayName = "IPFSWebFeatures" #Infopath Form Services Feature

#Scan Farm Level Features
$FarmLevelFeatures = $farm.FeatureDefinitions | Where-Object { ($_.Scope -eq "Farm") -and ($_.DisplayName -eq $FeatureDisplayName) }
if($FarmLevelFeatures -ne $null)
{
"$($FeatureDisplayName) Installed at Farm Level!"
}

#Get all web applications and scan through
$WebApplications = Get-SPWebApplication "http://sharepoint.crescent.com"
#To process all web applications, simply use: $WebApplications = Get-SPWebApplication
foreach($WebApp in $WebApplications)
{
Write-Host "Processing web Application : $($WebApp.url)"
$WebAppLevelFeature = $webApp.Features | Where-Object { $_.Definition.DisplayName -eq $FeatureDisplayName }
#If Feature found
if($WebAppLevelFeature -ne $null)
{
"$($FeatureDisplayName) Activated at Web Application $($webApp.URL)"
}

#Get All site collections of the Web Application
$SitesColl = $webApp.Sites

#Iterate through each site collection
foreach($Site in $SitesColl)
{
#Write-host "Processing Site: $($Site.Url)"
$SiteLevelFeature = $Site.Features | Where-Object { $_.Definition.DisplayName -eq $FeatureDisplayName }
#If Feature found
if($SiteLevelFeature -ne $null)
{
"$($FeatureDisplayName) Activated at Site Collection $($Site.URL)"
}

#Enumerate each sub-site
foreach($web in $site.AllWebs)
{
#Write-host "Processing Web: $($Web.Url)"
$WebLevelFeature = $web.Features | Where-Object { $_.Definition.DisplayName -eq $FeatureDisplayName }
#If Feature found
if($WebLevelFeature -ne $null)
{
"$($FeatureDisplayName) Activated at Web Level $($web.URL)"
}
$web.Dispose()
}
$site.Dispose()
}
}

How do I find all custom features?
We can run Get-SPFeature on a fresh sharepoint machine, take that inventory in a csv file.
Run it again in your targt machine which has custom features and compare!

Lately, Found this script on Technet Forums:
Add-PSSnapin "Microsoft.SharePoint.Powershell" -ErrorAction SilentlyContinue

$siteurl = "http://sharepoint.crescent.com"
$Site = Get-SPSite $siteURL

#send all features to output file features.txt
$site.WebApplication.Farm.FeatureDefinitions `
| where-object {$_.solutionid -ne '00000000-0000-0000-0000-000000000000'} `
| Sort-Object solutionid,displayname `
| ft -property displayname,scope -auto -groupBy solutionid > "d:\features.txt"

#replace solutionId in features.txt with solution name
foreach($solution in $site.WebApplication.Farm.Solutions)
{
(Get-Content "d:\features.txt") `
| Foreach-Object {$_ -replace $solution.solutionid.ToString(), $solution.Name} `
| Set-Content "D:\features.txt"
}

$site.Dispose()

"This field can have no more than 255 characters." Error in Multiline Text Columns

$
0
0
Getting  "This field can have no more than 255 characters." error on SharePoint Multiple lines of text  columns?

Well, the fix is simple, we've the property  "Allow Unlimited length in document libraries" on Multiple lines of text fields. Once enabled, technically it can hold content up to 2 GB.
This field can have no more than 255 characters

We can also set this property programmatically either with C# or PowerShell:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

#Get-SPSite cmdlet for MOSS 2007
function global:Get-SPSite($url)
{
return new-Object Microsoft.SharePoint.SPSite($url)
}

#Get-SPWeb cmdlet for MOSS 2007
Function global:Get-SPWeb($url)
{
$site= New-Object Microsoft.SharePoint.SPSite($url)
if($site -ne $null)
{
$web=$site.OpenWeb();

}
return $web
}

#Parameters
$web = Get-SPweb "http://sharepoint.crescent.com/regions/emea/se/"
$ListName = "Employee of the Month"
$FieldName = "Desciption"

#Get the List
$list = $web.lists[$ListName]

#Set the "Allow unlimited length in document libraries" option to true programmatically
$list.Fields[$FieldName].UnlimitedLengthInDocumentLibrary= $false

#Update the Field
$list.Fields[$FieldName].update()

C# code:

static void Main(string[] args)
{
SPSite mySite = new SPSite("http://sharepoint.crescent.com/regions/emea/se/");
SPWeb myWeb = mySite.OpenWeb();

SPList myList = myWeb.Lists["Employee of the Month"];
SPField myField = myList.Fields["Description"];

((SPFieldMultiLineText)myField).UnlimitedLengthInDocumentLibrary = true;
myField.Update();
}

Unfortunately, in some of the OOTB list fields, "Allow Unlimited length in document libraries" property is not included in the field definition. E.g. "Description" field in SharePoint picture libraries! What's the workaround? Create a New multiline column and copy values from the existing OOTB column!

Copy SharePoint List Column Values from One to Another

$
0
0
In some situations, we may have to copy SharePoint list column values from one column to another. Say, for E.g.
  • OOTB column doesn't provide a way to enter more than 255 characters in Multiple Lines of Text field. As user already entered values in it and wants to make it allow more than 255 chars.
  • When a SharePoint field's internal name needs to be changed.
  • There is requirement to add a new column, whose values are partially based on an existing column
While the Data Sheet view is one solution, Its not available for all lists. And even in datasheet view, some columns like people picker values can't be copy/pasted. So, the solution is: PowerShell

Here is the PowerShell script to copy SharePoint list / library field data from one column to another column:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

#Using Get-SPSite in MOSS 2007
function global:Get-SPSite($url)
{
return new-Object Microsoft.SharePoint.SPSite($url)
}

Function global:Get-SPWeb($url)
{
$site= New-Object Microsoft.SharePoint.SPSite($url)
if($site -ne $null)
{
$web=$site.OpenWeb();

}
return $web
}

#Parameters
$web = Get-SPweb "http://sharepoint.crescent.com/"
$listName = "Pictures"

#Use the Display Names
$CopyFromColumnName = "Description" #column copy source
$CopyToColumnName = "Desc" #destination column

#Get the List
$list = $web.lists[$ListName]

#Get all Items
$Items = $list.Items

foreach ($Item in $items)
{
#copy data from one column to another
$item[$copyToColumnName] = $item[$copyFromColumnName]

#Do a system update to avoid Version and to Keep same metadata
$item.SystemUpdate($false)
}

Viewing all 1058 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>