Monday, March 31, 2014

Restart SharePoint Timer Service Remotely using PowerShell

SharePoint Timer service must be restarted for certain configuration changes in SharePoint administration activities. Well, without logging into each and every SharePoint server and restarting timer service, we can utilize PowerShell to do it remotely!

To Restart SharePoint Timer service using PowerShell, use:
Restart-Service sptimerv4

PowerShell Script to Restart SharePoint Timer Service Remotely:
 #Service to Restart
 $ServiceName = "SPTimerV4"

 #Array to Hold server Names. Update this Array accordingly
 $ServerNames = @("SPServer01", "SPServer02", "SPServer03")
 
 #Get All SharePoint Servers and restart their SharePoint Timer service
 foreach($Server in $ServerNames) 
 {
     Restart-Service -InputObject $(Get-Service -Computer $Server -Name $ServiceName)
 }

You can also use the classic WMI method to restart any service on remove server:
 
    #Server Name
    $ServerName = "SPServer01"
 
    #Service to Restart
    $ServiceName = "SPTimerV4"
 
    #Get Timer Service
    $Service = Get-WmiObject -computer $ServerName Win32_Service -Filter "Name='$ServiceName'"
    $Service.InvokeMethod('StopService',$Null)
    start-sleep -s 5
    $Service.InvokeMethod('StartService',$Null)
    start-sleep -s 5
Restart Timer Service on all Servers:
#Get the Farm
$Farm = Get-SPFarm

#Get all Timer Job instances and restart
$Farm.TimerService.Instances | foreach { $_.Stop(); $_.Start(); }

Restart Timer Service from command line:
net stop SPTimerV4
net start SPTimerV4


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Sunday, March 30, 2014

Get SharePoint Site Collection, Web, List Objects from GUID

Requirement: On Nintex workflow databases, Ran a query to fetch workflow usage statistics, and the query gave GUIDs of SPSite, SPWeb and SPList objects!

SELECT TOP 100 
I.WorkflowName, 
I.WorkflowInstanceID, 
I.SiteID, 
I.WebID, 
I.ListID, 
I.ItemID, 
I.WorkflowInitiator, 
I.WorkflowID,
I.State, COUNT(P.WorkflowProgressID) as WorkflowProgressRecords
FROM WorkflowInstance I inner join WorkflowProgress P WITH (NOLOCK)
ON I.InstanceID = P.InstanceID
--WHERE i.State=2 
GROUP BY I.WorkflowName, I.WorkflowInstanceID, I.SiteID, I.WebID, I.ListID, I.ItemID, I.WorkflowInitiator, I.WorkflowID, I.State 
ORDER BY COUNT(P.WorkflowProgressID) DESC
Get SharePoint Site Collection, Web, List Objects from GUID
Well, from SQL query we got GUIDs of SharePoint site collection, web and list objects, but how do we get the actual site collection/site/list locations? PowerShell comes to rescue. Here is the PowerShell script to get SharePoint site collection, web, list objects from GUID.
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")  
 
#Get-SPWeb cmdlet for MOSS 2007
 Function global:Get-SPWeb($SiteGUID, $WebGUID)
{
  $site = New-Object Microsoft.SharePoint.SPSite($SiteGUID)
        if($site -ne $null)
            {
               $web=$site.OpenWeb($WebGUID);      
            }
    return $web
}
 #GUIDs for Site, Web and List 
 $SiteGUID = [GUID]("294D0050-19BE-439E-BF87-246F07828DAE")
 $WebGUID = [GUID]("AEDA6502-83C5-4967-A4C6-DF26B6F1ABDA")
 $ListGUID =[GUID]("1A54DCCD-251A-4B05-A7EC-BF10877C8B90")
 
 #Get the Web   
 $web = Get-SPweb $SiteGUID $WebGUID
 #Get the List
 $list = $web.Lists[$ListGUID]
 
 #Get the List title
 $list.title 
 $ListURL = $Web.URL+"/"+$list.RootFolder.URL
 write-host $ListURL 


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Friday, March 28, 2014

Open PDF Documents in New Window in SharePoint

By default, PDF documents are opened in the same browser window in SharePoint. Here is the trick to open PDF files in new window:

Option 1: Open PDF in new window with jQuery
Use this jQuery to script to open SharePoint 2010 PDF documents in a new window:
<script src="https://code.jquery.com/jquery-1.7.2.min.js" type="text/javascript"></script>

<script>
$(document).ready(function() {
$("a[href$='.pdf']").removeAttr('onclick').attr("target","_blank");
   });
</script> 

This script can be placed in Master Page, in Script editor/Content editor web parts or as part of SharePoint 2013/2010 delegate controls!

Option 2: Configure Client Settings to Open PDF in Client Application instead of Browser
If Office Web Apps isn't integrated with your SharePoint 2013, you can configure these options at client side:
  • Go to Adobe Reader >> Edit >> Preferences
  • Under Internet tab >> Uncheck : Display PDF in browser.
open pdf in new window sharepoint 2013
This will change the open in browser behavior to open in Adobe reader client application.

If that option isn't available/doesn't work for you, then configure IE to open PDF in Adobe reader instead of same window in Internet explorer. Here is how:
  • Go to Internet Explorer >> Tools >> Internet Options 
  • Under Programs tab >> Manage Add-Ons. >> Show : All Addons >> Then Disable the Adobe PDF plug-in.
open pdf in new window sharepoint

Option 3: Instruct Office Web Apps WordApp to Not to open PDF documents:
Don't want your Office web apps to handle PDF documents? Want to open PDF documents in Adobe reader instead of Word web app? Well, you can Remove the PDF handler from word by running:
Get-SPWOPIBinding –Application "WordPDF" | Remove-SPWOPIBinding -Confirm:$false

To revert it back:
New-SPWOPIBinding –ServerName "was.crescent.com" –Application "WordPDF" -AllowHTTP 


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Thursday, March 27, 2014

Download Attachments from SharePoint List Programmatically

This code is a C# version of my earlier post: Download All Attachments from SharePoint List Items using PowerShell

Download attachments from SharePoint list using C# Object model:
  
            //Variables
            String SiteURL;
            String ListName;
            String downloadLocation;
            
            //Get all inputs
            Console.WriteLine("Enter the Site URL:");
            SiteURL = Console.ReadLine();
            Console.WriteLine("Enter the List Name:");
            ListName = Console.ReadLine();
            Console.WriteLine("Enter the Download Location:");
            downloadLocation = Console.ReadLine();


            using (SPSite oSPsite = new SPSite(SiteURL))
            {
                using (SPWeb oSPWeb = oSPsite.OpenWeb())
                {
                    oSPWeb.AllowUnsafeUpdates = true;

                    //Get the List
                    SPList list = oSPWeb.Lists[ListName];
                    
                    //Get all list items
                    SPListItemCollection itemCollection = list.Items;

                    //Loop through each list item
                    foreach (SPListItem item in itemCollection)
                    {
                        string destinationFolder = downloadLocation + "\\" + item.ID;
                        if (!Directory.Exists(destinationFolder))
                        {
                            Directory.CreateDirectory(destinationFolder);
                        }

                        //Get all attachments
                        SPAttachmentCollection attachmentsColl = item.Attachments;
                        
                        //Loop through each attachment
                        foreach (string attachment in attachmentsColl)
                        {
                            SPFile file = oSPWeb.GetFile(attachmentsColl.UrlPrefix + attachment);
                            string filePath = destinationFolder + "\\" + attachment;

                            byte[] binFile = file.OpenBinary();
                            System.IO.FileStream fs = System.IO.File.Create(filePath);
                            fs.Write(binFile, 0, binFile.Length);
                            fs.Close();
                        }

                    }

                }
            }
            Console.WriteLine("Downloaded all attachments!");
            //Pause
            Console.ReadLine();
This code downloads all attachments from SharePoint list items.

You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Tuesday, March 25, 2014

SharePoint 2010 Search Scope Drop Down Missing?

SharePoint 2010 search drop downs such as "All Sites", "People" missing in site collections? Shows only "Search This site..." in search box? Well, That's the default setup in SharePoint 2010.
sharepoint 2010 search scope drop down missing
Enable SharePoint 2010 add search scope drop down:
How to enable search scope drop down in SharePoint 2010? simple, follow these steps:
Make sure you have a Search Center site created already, before proceeding to these steps.
  1. Go to Site Actions >> Site Settings 
  2. Click on "Search Settings" link under Site Collection Administration group. sharepoint 2010 search scope drop down missing
  3. Under "Site Collection Search Center" section, Choose "Enable Search Scopes" and enter the URL of your search center.
  4. On "Site Collection Search Dropdown Mode", choose "Show Search Dropdown"
  5. Click "Ok" to save your changes.

Now the searh box should show you a drop down with "All Sites", "People" Scopes in SharePoint 2010 sites along with "This Site" scope.
sharepoint 2010 search scope drop down

You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Sunday, March 23, 2014

Export SharePoint List Items to XML using PowerShell

Sometime back, I wrote a PowerShell script to import from a XML file to SharePoint list, Import XML File Data into SharePoint List using PowerShell. Now the requirement is in reverse: Export SharePoint List data to XML file!

PowerShell script to Export SharePoint List Items to XML:
How to export SharePoint list to XML? Here in the PowerShell script!
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Set these three variables accordingly
$WebURL  = "http://projects.crescent.com/"
$ListName = "External Projects"
$XMLFilePath = "E:\data\ExternalProjects.xml"

#Get the Web
$web = Get-SPWeb $WebURL
#Get the List
$ProjectList = $web.Lists[$ListName]

#Create a XML File
$XMLFile = New-Object System.Xml.XmlDocument
#Add XML Declaration
[System.Xml.XmlDeclaration] $xmlDeclaration = $XMLFile.CreateXmlDeclaration("1.0", "UTF-16", $null);
$XMLFile.AppendChild($xmlDeclaration) | Out-Null
   
 #Create Root Elemment "Projects"
$ProjectsElement = $XMLFile.CreateElement("Projects")
 
 #Iterate through each list item and send Rows to XML file
foreach ($Item in $ProjectList.Items)
 {
  #Add "Project" node under "Projects" Root node
  $ProjectElement = $XMLFile.CreateElement("Project")
  #Add "ID" attribute to "Project" element
  $ProjectElement.SetAttribute("id", $Item["ID"])
  $ProjectsElement.AppendChild($ProjectElement)  | Out-Null
  
  #Populate Each Columns
  #Add "Description" node under "Project" node
  $DescriptionElement = $XMLFile.CreateElement("description"); 
  $DescriptionElement.InnerText = $Item["Description"]
  #Append it to "Project" node
  $ProjectElement.AppendChild($DescriptionElement) | Out-Null
  
  #Add "Project Manager" element under "Project" node
  $managerElement = $XMLFile.CreateElement("manager"); 
  $managerElement.InnerText = $Item["Project Manager"]
  #Append it to "Project" node
  $ProjectElement.AppendChild($managerElement) | Out-Null
  
  #Add "Cost" element under "Project" node
  $CostElement = $XMLFile.CreateElement("cost"); 
  $CostElement.InnerText = $Item["Cost"]
  #Append it to "Project" node
  $ProjectElement.AppendChild($CostElement) | Out-Null
 }
  #Close the Root Element
  $XMLFile.AppendChild($ProjectsElement) | Out-Null
  #Save all changes
  $XMLFile.Save($XMLFilePath) 
XML file generated:
export sharepoint list to xml powershell
Another nifty trick would be: Export SharePoint list to Ms-Access, and then from there, export tables to XML!
export sharepoint 2010 list to xml file
You can also export/view SharePoint List items to XML format using RPC call, refer: Retrieve SharePoint List data in XML format


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Change Master Page in SharePoint using PowerShell

Requirement: Change Master page for SharePoint Site collections.

After a branding redesign project, Got a requirement to change master pages on existing sites. branding on new sites going to be created. But for existing sites, We got to change master pages manually.

SharePoint 2013 set master page using PowerShell:
Lets change master page in SharePoint 2010 using PowerShell.
Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue

#Get the Web
$web = Get-SPWeb "https://intranet.crescent.com/branding"

#Prepare the Custom Master page URL
$WebURL = $web.ServerRelativeUrl.TrimEnd("/")
$MasterPageURL = $WebURL+"/_catalogs/masterpage/crescentv1.master"

#Set Default and Custom Master pages
$web.MasterUrl = $MasterPageURL
$web.CustomMasterUrl = $MasterPageURL

#Apply Changes
$web.Update() 

How about All sites in a site collection?Here is the PowerShell script in SharePoint 2013 to change master page.
#Variable for Site collection
$SiteURL ="http://intranet.crescent.com"

#Get the Site object
$site = Get-SPSite $SiteURL

#Iterate through each web
foreach ($web in $site.AllWebs)
{
 #Prepare the Custom Master page URL
 $WebURL = $web.ServerRelativeUrl.TrimEnd("/")
 $MasterPageURL = $WebURL+"/_catalogs/masterpage/crescentv1.master"

 $web.MasterUrl = $MasterPageURL;
 $web.CustomMasterUrl = $MasterPageURL;
 
 $web.Update();

    Write-Host "Master page set for: $web.Url
}
We can modify the above code to apply master page for entire web application, even entire SharePoint farm!

Tags: sharepoint 2013 apply master page powershell, sharepoint powershell apply master page sharepoint 2010, powershell apply master page sharepoint, change master page powershell, sharepoint 2013 change master page powershell, set master page powershell sharepoint 2013, change master page sharepoint 2013 using powershell

You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Activate-Deactivate Feature on All Sites,Site Collections in SharePoint using PowerShell

We use "Enable-SPFeature" and " Disable-SPFeature" PowerShell cmdlets in SharePoint 2010 / SharePoint 2013 sites to activate or deactivate features as in my another article: How to Activate-Deactivate Features in SharePoint. At times, we may have to activate feature for all site collections or deactivate feature on all sites. Here is my PowerShell scripts to do that.

Enable a feature for all site collections in SharePoint:
In my case, I had to enable "Open Documents in Client Applications" feature in every site collection under a web application to force opening documents in Office clients such as Microsoft Word instead of Office web apps due the licensing limitation.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#variables
#$WebAppURL = "http://intranet.crescent.com"
$FeatureName ="OpenInClient"

#Get the Web Application
$webApp = Get-SPWebApplication -Identity $WebAppURL

#Get all site collections with in the web app
$SitesCollection = $WebApp | Get-SPSite -limit all 

#Iterate through each site 
foreach ($site in $SitesCollection)
{
    #Check if feature is already activated
    $feature = Get-SPFeature -site $site.Url  | Where-object {$_.DisplayName -eq $FeatureName}
    if($feature -eq $null)
    {    
        #Enable the feature 
        Enable-SPFeature -Identity $FeatureName -url $site.url -Confirm:$False
  
        Write-host "Feature Activated on $($site.URL)" -ForegroundColor Green    
    }
    else
    {
        Write-host "Feature is already Active on $($site.URL)" -ForegroundColor Red
    }
}

PowerShell to Deactivate Feature on All Sites:
Requirement: Deactivate "Mobile Redirect" feature on all sites in a SharePoint 2010 web application.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
 
#Variables
$WebAppURL = "http://intranet.crescent.com" 
$FeatureName = "MobilityRedirect"
 
#Disable Mobile View feature on all sites in the web application
$WebsCollection = Get-SPWebApplication $WebAppURL | Get-SPSite -Limit ALL | Get-SPWeb -Limit ALL
 
#Itereate through each web
ForEach($Web in $WebsCollection)
{
    #Check if feature is already activated
    $feature = Get-SPFeature -web $Web.Url  | Where-object {$_.DisplayName -eq $FeatureName}
 
    if($feature -ne $null)
    {
        #Disable the Mobile browser view feature
        Disable-SPFeature -identity $FeatureName -URL $Web.URL -Force -Confirm:$false
        write-host "Mobile Redirect feature deactivated at site: $($Web.Url)"
    }
 }


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Friday, March 21, 2014

Add Remove Content Types to SharePoint List or Library using PowerShell

SharePoint content types enables user to organize related data together. Everything is built around the content types in SharePoint to provide consistency and re-usability. Say for instance, All list templates such as Announcements, Tasks are built with content types "Announcement" and "Task" respectively! Typically a content type consists of template and metadata columns.  E.g. Lets consider "Sales Proposal document" content type which may be created at site collection with a template for sales proposal and columns to capture its related meta data, and can be associated with any number of document libraries.

By default content types are scoped at site collection level. When you add a content type to a SharePoint list, its copied from site content type gallery to the list, which means when you customize content type at list level, it doesn't affect the parent content type which lives at site collection level.
In OOPS terminology, you can consider "Content Type" as the class and items created from that content type as "Objects"

How to Associate a Content Types to SharePoint Library or List:
 To add content type to list or Library in SharePoint, do the following:
  • Go to the List / Library settings 
  • Click on Advanced Settings under General Settings group
  • On content types option set it to "Yes" for allow management of content types.
  • Now, in list settings page, you'll find a new section "Content types" with all associated content types with the list.
  • You can Click on "Add from existing site content types" link to add any existing content type to the list.
sharepoint powershell add content type to list
SharePoint 2013 PowerShell add content type to library
  •  On the "Add Content Types" page, in the "Available Site Content Types" section, select the content types you want to add to the list or library  click the Add and then OK. Now the new content type appears in the settings page.
    sharepoint 20130 powershell add content type to list
Remove content type from list
To remove any unused content types that you aren't using, do the following:
  • Browse to the List Settings or Library Settings page.
  • Under the "Content Types" section, click the content type you want to remove.
  • Click the "Delete This Content Type" link and then click OK at the confirmation prompt.
Content types and site columns are hierarchically inherited! So, if you create a content type, it will be available to all of its subsites underneath it!

Task: Add content type to SharePoint list using PowerShell:
If you want to associate a content type to multiple lists in multiple sites, you can use below PowerShell scripts to do it programmatically! In my case, I've a site with 50+ subsites. Requirement is to add a content type to a particular library on all sites. So, I wrote this PowerShell custom function to add remove content type in SharePoint library.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Custom PowerShell Function to Add Content type to SharePoint list
Function Add-ContentTypeToList([Microsoft.SharePoint.SPList]$List, $ContentTypeName)
{
    #Check if Content Type Management is enabled
    if($List.ContentTypesEnabled -ne $true)
    {
        Write-Host "Enabling Content type management on list: $($list.Title)"
        $List.ContentTypesEnabled = $true
        $List.Update()
    }

    #Get the content type
    $ContentType = $List.ParentWeb.Site.RootWeb.ContentTypes[$ContentTypeName]

    #If content type found in the site
    if ($ContentType)
    {
        #Check If list doesn't has the specific content type already
        if (-not $list.ContentTypes[$ContentTypeName])
        {
            #Add content type to the list
            $list.ContentTypes.Add($ContentType) | Out-Null
           
            $list.Update()
            Write-Host "Content Type Added to the list: $($List.Title)"
        }
        else
        {
            Write-Host  "Content Type '$($ContentTypeName)' already exists on the list '$($list.Title)'"
        }
    }
    else
    {
        Write-Host  "Cannot find the Content Type '$($ContentTypeName)' to add to list '$($list.Title)'"
    }
}

#Custom PowerShell Function to Remove Content type from SharePoint list
Function Remove-ContentTypeFromList([Microsoft.SharePoint.SPList]$List, $ContentTypeName)
{
    #Check if Content Type Management is enabled
    if($List.ContentTypesEnabled -ne $true)
    {
        Write-Host "Enabling Content type management on list: $($list.Title)"
        $List.ContentTypesEnabled = $true
        $List.Update()
    }

    #Get the content to remove from list
    $ContentType = $List.ContentTypes[$ContentTypeName]

    #If content type found in the site
    if ($ContentType)
    {
        #Check If list doesn't has the specific content type already
        if ($list.ContentTypes[$ContentTypeName])
        {
            #Remove content type from the list
            $list.ContentTypes.Delete($ContentType.Id)
            $list.Update()
            Write-Host "Content Type has been removed from the list: $($List.Title)"
        }
        else
        {
            Write-Host  "Content Type '$($ContentTypeName)' doesn't exists on the list '$($list.Title)'"
        }
    }
    else
    {
        Write-Host  "Cannot find the Content Type '$($ContentTypeName)' to add to list '$($list.Title)'"
    }
}

#Variables for processing
$WebURL ="http://sales.crescent.com"
$ListName ="Q1 Sales Proposal"
$ContentTypeName ="Sales Proposal"

#Get the Web and List
$Web = Get-SPWeb $WebURL
$List = $Web.lists.TryGetList($ListName)

if($list -ne $null)
{
    #Call the function to add content type
    #Add-ContentTypeToList $list $ContentTypeName

    #To remove content type from list, call: 
    Remove-ContentTypeFromList $list $ContentTypeName
}
You can't remove a content type if items are already created based on the content type! If you try to delete a content type in use, you'll end up with "Content Type is still in use" error!

You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Wednesday, March 12, 2014

SharePoint Web Part Usage Report - Find All Locations where a Particular web part is being Used

During Migration, I had to get the URLs where a particular web part is being used. So, Used this PowerShell script to generate SharePoint web part usage report.

This script made compatible with SharePoint 2007, So it can be used in SharePoint 2010 and in SharePoint 2013 as well. Just change the Web Application URL from "http://sharepoint.crescent.com" to yours.

SharePoint Web Part Usage Report using PowerShell:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
 
Function global:Get-SPWebApplication($WebAppURL)
{
 return [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($WebAppURL)
}

#Get-SPSite cmdlet for 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
}
 
#Write Header to CSV File
"Page URL,  Web Part Name" | out-file "D:\Data\ExcelServicesWPs.csv"
 
#Get all Webs
$WebApp = Get-SPWebApplication "http://sharepoint.crescent.com" 
foreach($site in $WebApp.Sites)
{
#Iterate through webs
foreach ($web in $site.AllWebs)
{
#Get All Pages from site's Root into $AllPages Array
$AllPages = @($web.Files | Where-Object {$_.Name -match ".aspx"})
 
#Search All Folders for Pages
foreach ($folder in $web.Folders)
    {
       #Add the pages to $AllPages Array
       $AllPages += @($folder.Files | Where-Object {$_.Name -match ".aspx"})
    }
  
 #Iterate through all pages
 foreach($Page in $AllPages)
  {
     $webPartManager = $web.GetLimitedWebPartManager($Page.ServerRelativeUrl, [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
    
     # Array to Hold Closed Web Parts
                foreach ($webPart in $webPartManager.WebParts | Where-Object {$_ -like "*Excel*"})
                {
                 $result = "$($web.site.Url)$($Page.ServerRelativeUrl), $($webpart.Title)"
                 Write-Host "Web Part Found at: "$result
                 $result | Out-File "D:\Data\ExcelServicesWPs.csv" -Append
                } 
         }
    }
 } 
The above script scans all libraries (not just "Site Pages" or "Pages" library! What if a web part page stored in a "documents" library?) from all sites where a particular webpart is being used and generates report in CSV format.

But if you want to scan only publishing pages, Here is how the script goes:
 $PublishingWeb =  [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
        $PagesLib = $PublishingWeb.GetPublishingPages()
        foreach($Page in $PagesLib)
        {
          #
        }


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Tuesday, March 11, 2014

Create a SharePoint Subsite from Custom Site Template using PowerShell

Requirement: We've a PMO site template created for managing projects in SharePoint. Had a new requirement to create some 20+ new PMO subsites based on the custom site template.

PowerShell script to create subsite from custom site template:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Custom function to create a site from site template
Function Create-SubsiteFromTemplate($SiteTitle, $ParentSiteUrl, $TemplateTitle)
{
    #Get the custom site template
    $ParentWeb = Get-SPWeb $ParentSiteUrl
    $SiteTemplates = $ParentWeb.GetAvailableWebTemplates($ParentWeb.Language)

    $CustomSiteTemplate = $SiteTemplates | Where-Object {$_.Title -eq $CustomSiteTemplateTitle}

    #URL for you new subsite
    $SiteUrl = $ParentSiteUrl + $SubsiteURL

    #create subsite without template
    $web  = New-SPWeb -Name $SiteTitle -Url $SiteUrl 

    #Apply the custom site template
    $Web.ApplyWebTemplate($CustomSiteTemplate.Name)

    Write-host "Subsite $($web.Url) has been created from template!"
}

#Call the function to create subsite
Create-SubsiteFromTemplate "Airbus 365 Project" "http://teamsites.crescent.com/projects/"  "PMO Site Template"
This creates s subsite "Airbus 365 Project" with URL "airbus365project" at the parent site: http://teamsites.crescent.com/projects/ with template "PMO Site Template".

How to create subsite in bulk from custom site template?
#List of sites to be created
$ProjectList = @("Data Tools", "Knowledge Village", "Service Center", "Business Reporting", "JDT Core", "EFI", "Ecore Tools")
$ParentSiteURL ="http://teamsites.crescent.com/projects/"
$SiteTemplateTitle = "PMO Site Template"

#loop through each object in the array and create subsite
foreach($Project in $ProjectList)
 {
    #Call the function to create subsite
    Create-SubsiteFromTemplate $project $ParentSiteURL $SiteTemplateTitle    
 }


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Friday, March 7, 2014

Download All Attachments from SharePoint List Items using PowerShell

Requirement is to Download all attachments from a SharePoint list to local folder. Lets use PowerShell to download attachments in SharePoint list items using PowerShell.

PowerShell script to download all attachments from a SharePoint list:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
#For MOSS 2007 compatibility
Function global:Get-SPWeb($url)
{
  $site= New-Object Microsoft.SharePoint.SPSite($url)
        if($site -ne $null)
            {
               $web=$site.OpenWeb()        
            }
    return $web
}

#Site URL and List Name variables
$WebURL = "http://intranet.crescent.com/sites/purchase"    
$LibraryName = "Invoinces"   

#Local folder to which attachments to be downloaded
$DownloadPath = "C:\Docs"     

#Get the web
$Web = Get-SPWeb $WebURL
#Get the Library
$List = $Web.Lists[$LibraryName]    

    #Loop through each List item
    foreach ($ListItem in $List.Items)
     {   
       #Set path to save attachment
       $DestinationFolder = $DownloadPath + "\" + $ListItem.ID          

       #Check if folder exists already. If not, create the folder
         if (!(Test-Path -path $DestinationFolder))        
            {            
                New-Item $DestinationFolder -type directory          
            }
      
          #Get all attachments
          $AttachmentsColl = $ListItem.Attachments
          
          #Loop through each attachment
          foreach ($Attachment in $AttachmentsColl)    
               { 
                 #Get the attachment File       
                 $file = $web.GetFile($listItem.Attachments.UrlPrefix + $Attachment)        
                 $bytes = $file.OpenBinary()                
                
                 #Save the attachment as a file  
                 $FilePath = $DestinationFolder + " \" + $Attachment
                 $fs = new-object System.IO.FileStream($FilePath, "OpenOrCreate")
                 $fs.Write($bytes, 0 , $bytes.Length)    
                 $fs.Close()    
                }
    }
For C# version of the above code, Go to: Download Attachments from SharePoint List Programmatically

You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Wednesday, March 5, 2014

Find All Users who Accessed the SharePoint Sites in the Past One Year

Requirement: Get the E-mail ids of all users who accessed SharePoint sites during the past one year!

Solution: Lets use Log Parser and PowerShell to fulfill this requirement. Here is how:
  1. Locate your SharePoint web application's log folders from all web front servers (usually: C:\WINDOWS\system32\LogFiles\W3SVCxxxxxxxxx\") using IIS. Make a note of them.
  2. Execute this log parser query by substituting LOG folders path, from any one of the Web Front end
  3. Use the data we received from log parser, pass it to PowerShell to query e-mails from active directory.
Log parser query to get all users:
@path=C:\Program Files\Log Parser 2.2\

LogParser -i:W3C "SELECT TO_LOWERCASE(cs-username)  As UserName, count(*) as [Total Hits] INTO PortalUsersFeb.csv FROM E:\MOSS2007\LogFiles\W3SVC1297965057\*, \\MOSS07-WFE02\E$\MOSS2007\LogFiles\W3SVC1297965057\*, \\MOSS07-WFE03\E$\MOSS2007\LogFiles\W3SVC1297965057\* WHERE date > '2013-03-01' AND cs-username Is Not Null group by TO_LOWERCASE(cs-username)" -o:CSV

pause
Place the above code in a batch file(.bat) and execute from any SharePoint web front end. This should give a CSV file with list of users. Alright, we got the list of user names. And now, we needed their E-mail IDs. Lets query active directory to get the E-mail ids of the users.

Query AD to Get user E-mail from user ID:
#Function to Check if an User exists in AD
function Get-Email()
   {
   Param( [Parameter(Mandatory=$true)] [string]$UserLoginID )
 
  #Search the User in AD
  $forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
  #To Search on other forests use these three lines:
  #$ForestName ="corporate.crescent.org"
  #$adCtx = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("forest", $ForestName)    
  #$forest = ([System.DirectoryServices.ActiveDirectory.Forest]::GetForest($adCtx))    
  
  #Search in all domains
  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 user found
         if ($result -ne $null)
         {
           $result.Properties["mail"]
         }
   }  
 }

##Read the CSV file - Map the Columns to Named Header
$CSVData = Import-CSV -path "E:\Users.csv" -Header("UserAccount")
#Iterate through each Row in the CSV
foreach ($row in $CSVData)
 {
    $mail = Get-Email $row.UserAccount
 $row.UserAccount +","+ $mail >>"E:\data\Mails.csv"
  }
This script outputs a CSV file by searching AD. Please note, the $UserLoginID parameter is simply user's login name without domain. (E.g. if Global\Salaudeen is the user name, we'll have to pass only "Salaudeen" to Get-Email function).

You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Tuesday, March 4, 2014

SharePoint 2013 deployment - Project Plan Template with Milestones

Assuming Hardware, Public IP, SSL Certificates, Domain Names are ready - Here is my SharePoint 2013 deployment project plan template with milestones outlined:

Deployment Tasks
0. Project Kick-off, Team-setup, Identifying key stake-holders and Responsibilities
1.Pre-Deployment Activities
1.1 Planning Logical Architecture, Topology, Service Accounts, Domain URLs, Naming Standards, etc.
1.2 Provision Service Accounts, DNS Entries & Delegations for SharePoint.
1.3 Prepare machines for SharePoint deployment (Adding Server Roles, Permissions, windows updates, etc.)
1.4 SQL Server Installation, Clustering / Mirroring / Always-ON.
2. SharePoint Installation
2.1.1 Install SharePoint binaries to Web and App Servers
2.1.2 Install Language Packs, Patch to recent build
2.2. Configure SharePoint Farm
2.2.1 Run SharePoint Configuration Wizard and Create SharePoint Farm
2.2.2 Configure Farm, Web Application Settings (SMTP, Upload Size, Recycle Bin, Quota Templates,
Antivirus settings, etc.)
2.3 Create and Configure Service Applications
2.3.1 Create Search Service Application.
2.3.2 Configure Search Service Content Source, Crawl Schedules, Verticals
2.3.3 Configure User Profile Service  Application (My Sites, User Profile Sync)
2.3.4 Create and configure BDC, Excel Services, Managed Metadata Service, Secure Store, Web Analytics
2.4 Branding
2.5 Configure SSL certificates, Configure Scheduled Tasks for Backup, Archival, Etc.
2.6 Load Balance, Publish SharePoint Farm
3. Deploy Office Web App Farm
3.1 Install necessary server roles to OWS Servers
3.2 Install and configure Office Web Apps Server Farm
3.3 Establish bindings between SharePoint and OWS Farm
4. Testing
4.1 Execute Load Testing on provisioned SharePoint Farm
4.2 Perform UI, Functional Testing on SharePoint features
4.3 Test My Sites, User Profile Sync, Incoming-Outgoing Emails, Search, etc.
5. Post deployment Tasks
5.1 Plan and Implement Application/Hardware/Security Monitoring (SCOM), High Availability, Backup, Disaster Recovery
5.2 Run SharePoint Health analyser, Best Practices checker and fix any possible issues.
5.3 Environment Build Guide Documentation
5.4 Handover, Knowledge Transfer, Trainings

This is only high-level tasks list! You may have to add/remove milestones based on your requirements!!


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Monday, March 3, 2014

SharePoint Products Configuration Wizard Failed to Connect to the Database Server.

Symptoms:
SharePoint sites crashed suddenly! Found event id 5586 "The target principal name is incorrect. Cannot generate SSPI context." logged in SharePoint servers.

Tried running SharePoint 2013 Products configuration wizard. Received error message:
"Failed to connect to the database server. Ensure the database server exists, is a Sql server, and that your have the appropriate permissions to access the server."
Failed to connect to the database server. Ensure the database server exists, is a Sql server, and that your have the appropriate permissions to access the server.
Troubleshooting tried:
  • Verified the Network connectivity, Port open in database server (Netstat -a -n -o)
  • Made sure Firewall is disabled. TCP/IP, Named Pipe protocols are enabled in SQL Server.
  • Verified the SQL Server service is up and running
  • Verified all required permissions to connect with SQL Server. Made sure no service account is locked. Tried restarting the services and server.
  • But when tried establishing a connection to SQL Server as in How to Check SQL Server Connectivity from SharePoint, it failed!
The Final solution Worked for me:
  • Go to your Active Directory >> Under Computer node, select your SQL Server >> Right Click >> Properties
  • Click on "Attribute Editor" tab, Edit "ServicePrincipalName" attribute
  • Remove these two highlighted entries which starts with "MSSQLSvc" 
  • Restart your database server.


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Sunday, March 2, 2014

Enable Item Level Permissions on Document Library in SharePoint using PowerShell

SharePoint Lists provide item level security options such as "Read items that were created by the user" or "Create items and edit items that were created by the user" under "Advanced Settings" page in SharePoint list settings.

But you don't get these options to set Item level security in SharePoint document libraries! Say your requirement is to restrict users to view and edit other's documents and allow only their own documents in a document library! If you need these options, you can utilize PowerShell to enable Item level permissions on SharePoint document libraries as there is no UI available!
These settings configures ReadSecurity and WriteSecurity properties of SPList object.

Change Read Security with PowerShell:
$web = Get-SPWeb "http://Your-SharePoint-Site"
$list = $web.Lists["Your Document Library Name"]
$list.ReadSecurity = 2
$list.Update()
$web.Dispose()
Where:
  • Read all items: 1
  • Read items that were created by the user: 2
Change Write Security permissions programmatically:
$web = Get-SPWeb "http://Your-SharePoint-Site"
$list = $web.Lists[“Your Document Library Name”]
$list.WriteSecurity = 2
$list.Update()
$web.Dispose()
Where:
  • Create and edit All items: 1
  • Create items and edit items that were created by the user: 2
  • None: 4
Please note, These settings will not have any effect for Site owners and administrators!

You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Fix for Powershell Script cannot be loaded because running scripts is disabled on this system error

Problem:
On trying to run a PowerShell script from PowerShell console, received this error message: "File C:\temp\GenerateRpt.ps1 cannot be loaded because running scripts is disabled on this
system. For more information, see about_Execution_Policies at http://go.microsoft.com/fwlink/?LinkID=135170."
This is due to the PowerShell's policy to prevent untrusted scripts which can affect your Server environment.

Solution: 
  • Open PowerShell Console by selecting "Run as Administrator" and set the execution Policy with the command: Set-ExecutionPolicy RemoteSigned 
  • Type "Y" when prompted to proceed 
This in fact sets the registry key: HKLM\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell
Policy parameter takes below values:
  1. Restricted - No scripting allowed
  2. Unrestricted - You can any scripting
    • No signing required
  3. Remote signed – good for Test, Dev environments
    • Only files from internet need to be signed
    • This is the default setting
  4. All signed  - local, remote script, it should be signed.
    • user must agree to run script


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Update List Item Metadata Fields (Created By, Last Modified) using PowerShell

Ever wanted to update SharePoint list or library item's metadata fields such as: "Created By" "Modified By" "Created" "Last Modified"? These column values must be updated while copying items from one list to another, programmatically.

Today, Had an another requirement to update metadata fields in a document stored in SharePoint document library. Lets update these metadata fields such as "Created By" "Modified By" "Created" "Last Modified" using PowerShell.

PowerShell Script to Update Metadata Fields in SharePoint:

Add-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue

#Define the Parameters
$WebURL = "http://sharepoint.crescent.com/projects/1033/"
$LibraryName = "Project Documents"
$DocumentName = "Project Schedules.xlsx"
$UserName = "Global\EricCo"
$DateValue = "2013-01-01 10:05" # Should be in "yyyy-mm-dd HH:mm" format

#Get the Web 
$web= Get-SPWeb $WebURL
#Get the Library
$list= $web.Lists[$LibraryName]
#Get the User
$Author =$web.EnsureUser($UserName)
#Get the document
$Document = $list.Items | where {$_.Name -eq $DocumentName}

#update created by column sharepoint programmatically
$Document["Author"] = $Author
#set modified by programmatically
$Document["Editor"] = $Author

#Set Created Date value
$Document["Created"] =  $DateValue
#Set Last Modified Date 
$Document["Modified"] = $DateValue

$Document.UpdateOverwriteVersion() #Can use $Document.SystemUpdate() as well..


You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Saturday, March 1, 2014

Add New Field to Customized List Forms in SharePoint 2013

Requirement: You have customized a SharePoint list form heavily. Now you got a new requirement to add a new field to the List, of course on List form as well. Unfortunately, when you add a new column to SharePoint list, custom forms have no effect - meaning new column will not appear on custom forms in SharePoint!

So, This leads to create a new list form and do all customizations in the list form again from the scratch, isn't it? Well, Here is a trick to avoid rebuilding custom list forms when new fields are added to the list.
 
Step 1: Refresh the data source
  • Open your custom form (Say, New.aspx) in SharePoint designer
  • Click on "Refresh data source" link in "Data Source Details" pane. 
    • Not finding "Data Source Details" pane?
      Place the cursor under <SharePoint:DataFormWebPart> node, You'll find the "Data View Tools" Ribbon Group. Click on "Options" Tab and then click on "Data Source Details" button. This should bring the data source details pane.  
Add New column to Custom List Form in SharePoint 2013
This updates the <DataFields> node in the source code!

Step 2: Copy Paste the similar field and update Field ID and Name 
The next step is to copy paste the existing similar field (In my case its single line of text) and change the Field name and ID  field's number which start with "FF"
  • Locate a field of similar type. Copy between <TR> to <TR>. Here is my code
<tr>
 <td width="190px" valign="top" class="ms-formlabel">
  <H3 class="ms-standardheader">
   <nobr>Change Request Number</nobr>
  </H3>
 </td>
 <td width="400px" valign="top" class="ms-formbody">
  <SharePoint:FormField runat="server" id="ff50{$Pos}" ControlMode="New" FieldName="ChangeNumber" __designer:bind="{ddwrt:DataBind('i',concat('ff50',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@ChangeNumber')}"/>
  <SharePoint:FieldDescription runat="server" id="ff50description{$Pos}" FieldName="ChangeNumber" ControlMode="New"/>
 </td>
</tr>
  • Paste the copied code into the relevant place. Change the Title text of the field. Change "FieldName" to new field. (Internal name of the field!). 
  • Change the ID field: Each field ID in SharePoint list form is named with the prefix "ff<Number>" such as "ff1","ff2", "ff3"and so on. Search for text "FF" in your source code. Get the highest FF number from the form. Change your pasted code's FF to existing higest FF +1. E.g. In my case, I found a field with ID: FF49. So, I changed my code to FF50.
These steps must be repeated for all custom forms such as Edit Form, Display form separately!

You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


You might also like:

Related Posts Plugin for WordPress, Blogger...