Wednesday, December 14, 2016

Best Practices: Common Coding Issues When Using the SharePoint Object Model

WSS 3.0 : https://msdn.microsoft.com/en-us/library/bb687949.aspx
SharePoint Add-in: https://msdn.microsoft.com/EN-US/library/fp179922.aspx

Wednesday, August 3, 2016

Export and Import SharePoint List with content using PowerShell

We had SharePoint farms in many variation SharePoint 2007, SharePoint 2010 and SharePoint 2013. Recently I had worked on a assignment that migrating single list data from SharePoint 2007 to SharePoint 2010.  Initially I thought that it bit easy task but when get in to it, it had given many issue because I was told that there should not be any change in the data including modified date, modified by, created data, created by finally all versions as it is.

I was in trouble because the source list is 100% customized(custom fields, custom content types, list definition, event receivers and New, Edit & display forms as well)

I had upgraded the custom functionality to SharePoint 2010 excluding custom input forms. But export import command, failed all the time.

Ends with lot off issue like, fields are duplicated, content type is not matching, field ids are not matching, destination web, list are are not available and so many.

Thought of implementing some data correcting before importing the SharePoint 2007 list content.

1. I had trimmed the custom source code only with Custom fields and Custom Content Types
2. Deployed the latest build on SharePoint 2010 farm
3. Created a new list and added custom content type, Enabled versioning and removed default content type "Item".
4. Created a test item using new custom content type
5. Exported the SharePoint 2010 list as.DAT file
6. Renamed .DAT to .CAB and extracted all files in to new folder
7. Exported SharePoint 2007 list as .DAT file
8. Renamed .DAT to .CAB and Extracted all files in to new folder
9. Opened the manifest.xml file from SharePoint 2007 extracted folder and copied SPListItem elements
10. Opened the manifest.xml file from SharePoint 2010 extracted folder and pasted Copied SPListItem elements.
11. Replaced the below ids on newly pasted element
      ParentId, ParentWebId, FileUrl,URL,ContentTypeId,
12.Created .CAB files form extracted SharePoint 2010 files.(used makecab.exe)
13. Imported the cab to SharePoint 2010
14. Verified the list
15. All worked fine.

Blow are the PowerShell scripts I used for migration.

Export SharePoint List

# For Export a specified SharePoint List
Export-List "http://kmsnet:15006/Lists/sklist/"

function Export-List([string]$ListURL)
{
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Deployment") > $null

$versions = [Microsoft.SharePoint.Deployment.SPIncludeVersions]::All

$exportObject = New-Object Microsoft.SharePoint.Deployment.SPExportObject
$exportObject.Type = [Microsoft.SharePoint.Deployment.SPDeploymentObjectType]::List
$exportObject.IncludeDescendants = [Microsoft.SharePoint.Deployment.SPIncludeDescendants]::All

$settings = New-Object Microsoft.SharePoint.Deployment.SPExportSettings

$settings.ExportMethod = [Microsoft.SharePoint.Deployment.SPExportMethodType]::ExportAll
$settings.IncludeVersions = $versions
$settings.IncludeSecurity = [Microsoft.SharePoint.Deployment.SPIncludeSecurity]::All
$settings.OverwriteExistingDataFile = 1
$settings.ExcludeDependencies = $true

$site = new-object Microsoft.SharePoint.SPSite($ListURL)
Write-Host "ListURL", $ListURL

$web = $site.OpenWeb()
$list = $web.GetList($ListURL)

$settings.SiteUrl = $web.Url
$exportObject.Id = $list.ID
$settings.FileLocation = "C:\Temp\BackupRestoreTemp\"
$settings.BaseFileName = "ExportList-"+ $list.ID.ToString() +".DAT"
$settings.FileCompression = 1

Write-Host "FileLocation", $settings.FileLocation

$settings.ExportObjects.Add($exportObject)

$export = New-Object Microsoft.SharePoint.Deployment.SPExport($settings)
$export.Run()

$web.Dispose()
$site.Dispose()
}

Import SharePoint List

# For Import the list you export in previous command
Import-List "http://kmsnet:15006" "C:\SK_DEV\sklist.cab" "C:\SK_DEV\OUT\ImportLog.txt"

function Import-List([string]$DestWebURL, [string]$FileName, [string]$LogFilePath)
{
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Deployment") > $null

$settings = New-Object Microsoft.SharePoint.Deployment.SPImportSettings

$settings.IncludeSecurity = [Microsoft.SharePoint.Deployment.SPIncludeSecurity]::All
$settings.UpdateVersions = [Microsoft.SharePoint.Deployment.SPUpdateVersions]::Overwrite
$settings.UserInfoDateTime = [Microsoft.SharePoint.Deployment.SPImportUserInfoDateTimeOption]::ImportAll

$site = new-object Microsoft.SharePoint.SPSite($DestWebURL)
Write-Host "DestWebURL", $DestWebURL

$web = $site.OpenWeb()

Write-Host "SPWeb", $web.Url

$settings.SiteUrl = $web.Url
$settings.WebUrl = $web.Url
$settings.FileLocation = "C:\SK_DEV\OUT\"
$settings.BaseFileName = $FileName
$settings.LogFilePath = $LogFilePath
$settings.FileCompression = 1

Write-Host "FileLocation", $settings.FileLocation

$import = New-Object Microsoft.SharePoint.Deployment.SPImport($settings)
$import.Run()

$web.Dispose()
$site.Dispose()
}



Monday, July 25, 2016

SharePoint 2013 Service Application comparison of each editions




Service Application Foundation Standard Enterprise Online
Access Services No No Yes Yes
Access Services 2010 No No Yes No
Apps Management Service Yes Yes Yes Yes
Business Data Connectivity Service Yes Yes Yes Yes
Excel Services application No No Yes Yes
Machine Translation Service No No Yes Yes
PerformancePoint Service Application No No Yes No
PowerPoint Automation Service No Yes Yes Yes
Managed Metadata Service Application Yes Yes Yes Yes
Secure Store Service Application No Yes Yes Yes
Search Service Application Yes* Yes Yes Yes
State Service Application Yes Yes Yes Yes
UserProfile Service Application No Yes Yes Yes
Visio Graphics Service No No Yes Yes
Word Automation Services No Yes Yes Yes
Workflow Management Service Application Yes Yes Yes Yes
Work Management Service Application No Yes Yes Yes
Site Subscription Settings Services Yes Yes Yes Yes
UserAndHealth Data Services Yes Yes Yes Yes

SharePoint 2013 Insights comparison of each editions





Insights features Foundation Standard CAL Enterprise CAL Online
Business Intelligence Center No No Yes TBA
Calculated Measures and Members No No Yes TBA
Data Connection Library No No Yes TBA
Decoupled PivotTables and PivotCharts No No Yes TBA
Excel Services No No Yes Yes
Field list and Field Support No No Yes TBA
Filter Enhancements No No Yes TBA
Filter Search No No Yes TBA
PerformancePoint Services No No Yes TBA
PerformancePoint Services (PPS) Dashboard Migration No No Yes TBA
Power View for Excel in SharePoint No No Yes TBA
Power Pivot for Excel in SharePoint No No Yes TBA
Quick Explore No No Yes TBA
Scorecards & Dashboards No No Yes TBA
SQL Server Reporting Services (SSRS) Integrated Mode Yes Yes Yes TBA
Timeline Slicer No No Yes TBA
Visio Service No No Yes TBA

Sunday, June 12, 2016

Model-View-Presenter (MVP) Pattern


MVP: Model - View - Presenter
I thought of writing something about MVP design pattern which is one of the major pattern used in SharePoint and many .Net applications.


Most of the time reader(s) feels that it is easy when reading article but during implementation there will be lot of confusion and forget how it works internally. I had created a easy example with a day to day life which will give a very clear understating and implementation knowledge.

Before I proceed to the example, we should know some basic definition used for MVP.
MVP design pattern is evaluation of MVC. MVP pattern providing a clear separation between view, model and controller. As well as improves the the testability of enterprise solution. 

MVP pattern is adding more benefit to decoupling architecture. The model can be used by more than one applications/operations.

Model: It is a domain level or business object. Model accommodates application data and behaviours to systematically access it. Model should be independent and it should not be communicated directly from either View or Presenter. All the time model will be treated as stand alone build business object which can be interacted through an interface.

View: View is nothing but UI where all data/result will be bound. But view should be updated by presenter. View will know the model but not wise versa.

Presenter: Presenter will address all input from view and use them to manipulate the result through Model and update the result back to view.





Below is the example that I created with Restaurant operation with MVP. 

Actions: Customer going to an restaurant for having some food. Waiter will get the order from customer and pass it to kitchen department. Cook will get all input and prepare the food for the order and deliver the food.


Find below the mapping how this action and characters are associated with MVP architecture/elements.


Customer -->  End user

Ingredients--> Model: Place of providing data/manipulating result with help of business logic. Here in this context the kitchen is source for supplying ingredients for preparing food.

Waiter --> View: Read out the menu items and get order from customer

Cook --> Presenter: The one who collect input from waiter and prepare food based on the order and deliver the food back to waiter who will serve to customer.

Menu card --> View Interface : Waiter should know all available items and way of serving the food which is nothing but implementing the interface in view.
Kitchen --> Model Interface:

Kitchen Interface --> Model Interface: Kitchen is the place which provide a facility to prepare food by accessing all ingredients and cooking equipments by cook. 


Logical diagram of MVP pattern association with Restaurant operation.

  • As stated in above diagrams, waiter(view) should knows all available food by implementing the food menu which is nothing but and View interface
  • Waiter can communicate the customer order to cook for preparing food but cannot go to kitchen and prepare food himself.
  • Cook will completely read the order details and access kitchen to get all ingredients and equipments for preparing food
  • Kitchen is an model interface because it is the place providing facility for preparing food.
  • Ingredients is our mode as it is similar to information data. This model can be accessed by PO department, Stack department and many more.
  • Cook will prepare food and deliver it on a plate or cup based on order. This action is nothing but presenter updating the view with result which will be deliver to end user(customer)
Transforming the logic in below diagram

  1. Waiter reading all items available in menu card
  2. Customer ordering one black tea and cup of coffee to waiter
  3. Waiter sending order details to cook for preparing black tea and coffee
  4. Cook access kitchen and collect coffee seed, Tea powder and milk for preparing food.
  5. Cook complete the preparation and pouring it in two different cups. One for black tea another one for coffee.
  6. Waiter serve the black team and coffee to respective customer.

Find below completely transformed class diagram 

Sample C# solution explorer

Sample code:
Model:


namespace Restaurant
{
    public class Ingredients_Model : IKitchen_Interface
    {
        public string VegetableRice(int qty)
        {
            return "Ready :- "+qty + " --> Vegetable Rice."; 
        }
        public string CurdRice(int qty)
        {
            return "Ready :- " + qty + " --> Curd Rice "; 
        }
        public string Tea(string density, bool withMilk)
        {
            if (withMilk)
            {
                return "Ready :- " + density + " --> Tea with Milk ";
            }
            else
            {
                return "Ready :- " + density + " --> tea without Milk ";
            }
            
        }
        public string Coffee(string density, bool withMilk)
        {
            if (withMilk)
            {
                return "Ready :- " + density + " --> coffee with Milk ";
            }
            else
            {
                return "Ready :- " + density + " --> coffee without Milk ";
            }
        }
        public string FishFry(string fishName, int qty)
        {
            return "Ready :- " + qty + " --> Fried " + fishName + " fish ";
        }
        public string ChickenFry(int qty)
        {
            return "Ready :- " + qty + " --> Fried chicken ";
        }
    }
}

Model Interface:


namespace Restaurant
{
    public interface IKitchen_Interface
    {
        string VegetableRice(int qty);
        string CurdRice(int qty);
        string Tea(string density,bool withMilk);
        string Coffee(string density, bool withMilk);
        string FishFry(string fishName,int qty);
        string ChickenFry(int qty);
    }
}

Presenter:


namespace Restaurant
{
    public class Cook_Presenter
    {
        IMenuCard_Interface iMenu;
        IKitchen_Interface iKit;
        public Cook_Presenter(IMenuCard_Interface pImenu)
        {
            iMenu = pImenu;
            iKit = new Ingredients_Model();
        }
        public void  FishFry(string fishName,int qty)
        {
           iMenu.PreparedFood=iKit.FishFry(fishName,qty);
        }
        public void ChichenFry(int qty)
        {
            iMenu.PreparedFood = iKit.ChickenFry( qty);
        }
        public void CurdRice(int qty)
        {
            iMenu.PreparedFood = iKit.CurdRice( qty);
        }
        public void VegerableRice(int qty)
        {
            iMenu.PreparedFood = iKit.VegetableRice( qty);
        }
        public void Tea(string dencity, bool withMilk)
        {
            iMenu.PreparedFood = iKit.Tea(dencity, withMilk);
        }
        public void Coffee(string dencity, bool withMilk)
        {
            iMenu.PreparedFood = iKit.Coffee(dencity, withMilk);
        }
    }
}

View Interface;


namespace Restaurant
{
    public interface IMenuCard_Interface
    {
        void FishFry(string fishName,int qty);
        void ChickenFry(int qty);
        void Coffee(string dencity, bool withMilk);
        void Tea(string dencity, bool withMilk);
        void CurdRice(int qty);
        void VegetableRice(int qty);
        string PreparedFood { get; set; }
    }
}

View:


namespace Restaurant
{
    public class Waiter_View:IMenuCard_Interface
    {
        Cook_Presenter cook;
        public void FishFry(string fishName, int qty)
        {
            cook=new Cook_Presenter(this);
            cook.FishFry(fishName, qty);
        }
        
        public string PreparedFood
        {
            get;
            set;
        }

        public void ChickenFry(int qty)
        {
            cook = new Cook_Presenter(this);
            cook.ChichenFry(qty);
        }

        public void Coffee(string dencity, bool withMilk)
        {
            cook = new Cook_Presenter(this);
            cook.Coffee(dencity, withMilk);
        }

        public void Tea(string dencity, bool withMilk)
        {
            cook = new Cook_Presenter(this);
            cook.Tea(dencity, withMilk);
        }

        public void CurdRice(int qty)
        {
            cook = new Cook_Presenter(this);
            cook.CurdRice( qty);
        }

        public void VegetableRice(int qty)
        {
            cook = new Cook_Presenter(this);
            cook.VegerableRice( qty);
        }
    }
}


Customer:


using System;

namespace Restaurant
{
    class Customer
    {
        static void Main(string[] args)
        {
            Waiter_View order = new Waiter_View();
            
            order.Tea("Black", false);
            Console.WriteLine(order.PreparedFood);

            order.Coffee("Strong", true);
            Console.WriteLine(order.PreparedFood);

            Console.ReadKey(true);
        }
    }
}

RESULT:







Tuesday, May 31, 2016

Creating A Service With $http using AngularJS

AngularJS is providing lot of extraordinary build in feature. One among many feature is creating a custom service.
We can have an custom service which can be reused in many controllers.

In below sample I had created a common service for $http and displaying responses from different controllers.

URL is passed as dynamic input parameter to the service and the service will send response back to the controller. The code is mode easy and self explanatory.


HTML Example:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
   
    <script src="Scripts/angular.js"></script>
    <script src="Scripts/httpFactory.js"></script>
</head>
<body ng-app="skMain">
    <div ng-controller="skCtrl1">
       VALID  HTML RESPONSE DATA : {{mydata}}
    </div>
    <br/>
    <div ng-controller="skCtrl2">
        INVALID  HTML RESPONSE DATA : {{getResponse}}
    </div>
</body>
</html>

Saved above html name " httpFactory.html"


AngularJS Example 

///

//Angulare module
var skMain = angular.module("skMain", []);

//Declaring controller
skMain.controller("skCtrl1", skCtrl1);
skMain.controller("skCtrl2", skCtrl2);

//declaring service/factory
skMain.factory("httpFact",httpFact);


//Controller has farctoy injected
function skCtrl1($scope, httpFact) {
    //Get http response from factory for valid HTML page
    httpFact.getData("httpFactory.html")
        .then(
        function (response) {
            //getting success response
            $scope.mydata = "Success --> httpFactory.html : status"
                + response.status + "  " + response.statusText;
            console.log(response);
        },
        function (response) {
            //getting failure response
            $scope.mydata = "Failed --> httpFactory.html : status"
                + response.status + "  " + response.statusText;
        });

}

//Controller has farctoy injected
function skCtrl2($scope, httpFact) {
    //Get http response from factory for valid HTML page
    httpFact.getData("httpFactory1.html")
        .then(
        function (response) {
            //getting success response
            $scope.getResponse = "Success --> httpFactory.html : status"
                + response.status + "  " + response.statusText;
        },
        function (response) {
            //getting failure response
            $scope.getResponse = "Failed --> httpFactory.html : status"
                + response.status + "  " + response.statusText;
            console.log(response);
        });

}

//Defining factory method. getDate will be returned as http response
function httpFact($http) {
        return {
            getData: function(myUrl) {
                return $http({
                    method: "GET",
                    url: myUrl
                });
            }
        }
    }


Result:
VALID HTML RESPONSE DATA : Success --> httpFactory.html : status 200 OK

INVALID HTML RESPONSE DATA : Failed --> httpFactory.html : status 404 Not Found

Saturday, May 21, 2016

Get App Web and Host Web URL using jQuery

Find below the code sample of jQuery to get App Web and Host web URL.

$(document).ready(function(){
var spHostWebUrl=decodeURIComponent(getQueryStringValue("SPHostUrl"));
var spAppWebUrl=decodeURIComponent(getQueryStringValue("SPAppWebUrl"));
console.log("Host web URL  :"+spHostWebUrl);
console.log("App web URL  :"+spAppWebUrl);
});

function getQueryStringValue(paramName){
var params=document.URL.split("?")[1].split("&");
for(var intx=0;intx<params.length;intx++){
var urlParam=params[intx].split("=");
if(urlParam[0]==paramName){
return urlParam[1];
}
}
}

Friday, April 29, 2016

Create app catalog site in SharePoint online


SharePoint online will accept only one app catalog per tenant. Once the app catalog is created then all sites and site collection will use the same for apps management.

Find below the steps to create app catalog in existing SharePoint online site.

  1. Login http://portal.office.com
  2. Go to SharePoint Admin Center
  3. Click on Apps available in quick launch
  4. Click on app catalog present at right hand side(work space)

   5. Selection create new app catalog site option

6. Click on OK button
7. Enter new app catalog site details(similar to new site collection creations process)

8. Click on OK button
9. SharePoint online will take few minutes to process and provision app catalog site

10.  New app catalog site is available in site collection list
11. Click app catalog site url to see the properties


12. Click on web address to see newly create app catalog site

13. New app catalog site loaded 
14. Find different type options to import apps to your tenant








Thursday, April 28, 2016

Create New Site Collection in SharePoint Online

Create new site collection in SharePoint online


Microsoft gives a sophisticated environment for maintaining all content at one place and make it available online all the time. SharePoint online is part of Office 365 suite. If you have SharePoint subscriptions enabled then you are allowed to create new site collections.


Find below the steps to create new site collection SharePoint online.


1. Login to http://portal.office.com
2. Once landed in Office 365, go to Admin Center and click on SharePoint



3. Once landed in SharePoint Admin center, click on New Private site collection




4. SharePoint begins with creating site collection input form


5. Enter the new site collection details as required


6. Enter the site collection administrator's name/id
7.Click on OK Button
8. SharePoint process the new site collection and it takes few minutes


9. New site collection creation process will complete and back to SharePoint Admin Center
10. New site collection will be available in the list of site collection
11.Click on newly created site collection URL to see all properties

12. Click on the web site address to see newly created SharePoint site


13. Newly created site loaded in new window.









Wednesday, February 10, 2016

Get all sites where a feature is activated or deactivated

Get list of webs where either feature activated or deactivated in SharePoint at different scopes like web, site collection, web application and farm.

Below PowerShell script will provide list of webs(sub site including top level site) where specified feature is installed and not activated in particular site collection

Get-SPSite "http://kmsnet:5050"| Get-SPWeb -Limit All | Where-Object { (Get-SPFeature "12f73b57-1db8-4272-3d45-d8c1cc9f3d41" -ErrorAction SilentlyContinue -Web $_.Url) -eq $null} | Select Url


Below script will provide list of webs(sub sites including toplevel site) where specified feature is installed and activated.

Get-SPSite "http://kmsnet:5050"| Get-SPWeb -Limit All | Where-Object { (Get-SPFeature "12f73b57-1db8-4272-3d45-d8c1cc9f3d41" -ErrorAction SilentlyContinue -Web $_.Url) -ne $null} | Select Url

Note: If the feature object is null then those web(s) considered that feature is installed and not activated. If it is not-null then feature is installed and activated on the web.

Below PowerShell script will provide list of webs(sub sites including top level site) where specified feature is installed and not activated in all site collections from current SharePoint Farm

Get-SPSite –Limit All | Get-SPWeb -Limit All | Where-Object { (Get-SPFeature "12f73b57-1db8-4272-3d45-d8c1cc9f3d41" -ErrorAction SilentlyContinue -Web $_.Url) -eq $null} | Select Url


Below script will provide list of webs(sub sites including toplevel site) where specified feature is installed and activated in all site collections from current SharePoint Farm.

Get-SPSite –Limit All | Get-SPWeb -Limit All | Where-Object { (Get-SPFeature "12f73b57-1db8-4272-3d45-d8c1cc9f3d41" -ErrorAction SilentlyContinue -Web $_.Url) -ne $null} | Select Url

Below PowerShell script will provide list of webs(sub sites including top level site) where specified feature is installed and not activated in all site collections from specified web application

Get-SPWebApplication “http://kmsnet:5050” |Get-SPSite –Limit All | Get-SPWeb -Limit All | Where-Object { (Get-SPFeature "12f73b57-1db8-4272-3d45-d8c1cc9f3d41" -ErrorAction SilentlyContinue -Web $_.Url) -eq $null} | Select Url

Below script will provide list of webs(sub sites including toplevel site) where specified feature is installed and activated in all site collections from specified web application.

Get-SPWebApplication “http://kmsnet:5050” |Get-SPSite –Limit All | Get-SPWeb -Limit All | Where-Object { (Get-SPFeature "12f73b57-1db8-4272-3d45-d8c1cc9f3d41" -ErrorAction SilentlyContinue -Web $_.Url) -ne $null} | Select Url

Monday, January 25, 2016

Find Process Identifier (PID) for Application Pool

Developers and system administrators must know to find out the correct PID associated with application pool if multiple web sites are running different app pools on the same server. PID is more important when Administrator troubleshoots an issue/worker process or developers debug the code by attaching the correct W3WP process with visual studio.

There are four common methods available to find out the Process Identifier for application pool.
1. Using IIS user interface
2. Using Command prompt
3. Using Task manager
4. Using Process Viewer


Method 1: Using IIS User Interface


1. Open IIS
2. Select Server from Connection Tree
3. Select Features Tab
4. Double click on Worker Process available under IIS section
5. Find the application pool name and Process identifiers in tabular view


Method 2: Using Command Prompt

iisapp.vbs script needs to be used to retrieve the correct PID from IIS6 and Windows 2003 server. Find the details in below snapshot.

C:\Windows\System32>script iisapp.vbs

Command “appcmd” need to be used on IIS7 or above and Windows 2008 server or above to retrieve the correct PID details from server. The “appcmd” command had to be executed by passing additional parameters “list” and “wps”. Find the details in below snapshot.


Go to c:\Windows\system32\inetsrv>appcmd list wps

Method 3: Using Command Prompt
1. Open Task Manager
2. Go to Process Tab
3. Go to View menu and client on Select columns
4. Add PID(Process Identifier) and Command line
5. Click OK
6. Find the PID and application pool details in the updated view




Thursday, January 14, 2016

Activate Web (subsite) scoped feature in all existing sites and subsites using PowerShell


We ware asked to enable a new rule that site/sub site cannot be deleted if any document declared as record. Of course I have added  new web deleting event receiver and used a web scoped feature to register the event on web.

But we have more than 100000 sub sites in our SharePoint farm. And enabling web scoped feature for all existing sites became a risk and performance hit.

I had created two scripts to resolve this issue. 1. PS script to collect all site collection from a web application and store it in a XML file. 2. PS script will read the XML file and process the site collection one by one as we got a provision to pass number site to be processed at one time. It reduced the performance hit and trace issue if any feature failed to activate

PowerShell script to Fetch All Site Collection:

# This script to generate XML file which contains all site collections in web application

# .\1_GetsiteCollections.ps1 -url "http://kmsnet:5500/" 



param
(
[string]$url   # Web application URL

)

If ((Get-PSSnapIn -Name Microsoft.SharePoint.PowerShell -ErrorAction Stop) -eq $null )  
{ Add-PSSnapIn -Name Microsoft.SharePoint.PowerShell } 

#Start-Transcript
if($url)
{

[string]$filepath = $(get-location).Path;
# XML file generation code 
$ErrorActionPreference = "SilentlyContinue"
#$ErrorActionPreference = "Stop"

# Create a new XML File with config root node
[System.XML.XMLDocument]$oXMLDocument=New-Object System.XML.XMLDocument

# New Node
[System.XML.XMLElement]$oXMLRoot=$oXMLDocument.CreateElement("SiteCollection")
# Append as child to an existing node
$oXMLDocument.appendChild($oXMLRoot)
    $site = get-spsite $url
    $WebApp = $site.webapplication 
    $Count =0;
    try
    {
   foreach ($spsite in $WebApp.sites) 
   {
            [System.XML.XMLElement]$oXMLSystem=$oXMLRoot.appendChild($oXMLDocument.CreateElement("site"))
            $Count +=1;
       $oXMLSystem.SetAttribute("Count",$($Count))
       $oXMLSystem.SetAttribute("URL",$($spsite.Url))
            $oXMLSystem.SetAttribute("GUID",$($spsite.ID))
            $oXMLSystem.SetAttribute("Status","New")
                        
        }
        
        $xmlPath=$filepath + "\SiteCollXML";
        New-Item -force -ItemType directory -Path $xmlPath;
        $Filename = $filepath + "\SiteCollXML\SiteURL.xml"
        $oXMLDocument.Save($Filename )
        Write-host " Site collection file is generated : " $Filename
        
    }
     catch
    {
       # $Error; 
        $ErrorMessage = $_.Exception.Message
        write-host $ErrorMessage 


        $FailedItem = $_.Exception.ItemName
        write-host $FailedItem 
        
    }

}
else
{
Write-host "Please provide the Web Application Url...!!!" -foregroundcolor "Yellow"
}

PowerShell Script to process each site collection.

# .\2_EnableWebScopedFeature.ps1 -count 5 -Enable Y -FeatureId "12f73b57-1db8-4272-9d95-d8c1cc9f3d41"

param
(
    
    [int]$count =$(throw "Count is mandatory, please provide a value."), # No. of site collections to be processed
    [string]$Enable =$(throw "Pass y/Y to Activate the feature else pass n/N to deactivate the deature"),
    [string]$FeatureId =$(throw "Pass feature Id")
    
 )



Start-Transcript

If ((Get-PSSnapIn -Name Microsoft.SharePoint.PowerShell -ErrorAction Stop) -eq $null )  
{ Add-PSSnapIn -Name Microsoft.SharePoint.PowerShell } 

write-host "Successfully added SharePoint PowerShell snapins"

#$ErrorActionPreference = "Stop"
$ErrorActionPreference = "SilentlyContinue"
$curDir=$(get-location).Path;
$LogTime = Get-Date -Format yyyy-MM-dd_h-mm  
$LogFile = $curDir + "\Logs1-$LogTime.txt"  
$DocIDFile = $curDir + "\Log2-$LogTime.txt"  
write-host "Log file Location : " $LogFile


$filePath = $curDir + "\SiteCollXML\SiteURL.xml"

#write-host "source XMl file Path is $filePath "
write-host " Doc Id file " $DocIDFile 


$SiteCollectionsXML = [xml](gc $filePath)
try
{
    write-host "$count number of site collection requested to process";
    $currentcount = 0
    $DocIDcount = 0

$SiteCollectionsXML = [xml](gc $filePath)
$newItems=$SiteCollectionsXML.SiteCollection.site | where { $_.Status -eq "New"} 
    $node="";
    foreach ($sColl in $newItems)
  {
      if ([int]$currentcount -lt $count)
            {
        write-host "Start: Site Collection ";
        
        try
        {
        $currentcount = $currentcount + 1
         $node = $SiteCollectionsXML.SiteCollection.site | where {$_.GUID -eq $sColl.GUID}   
        $node.Status = "New"
        $objsite = Get-SPSite $sColl.URL;
        if($Enable -eq "Y" -and $Enable -eq "y")
        {
        $objsite | Get-SPWeb -limit all | ForEach-Object {Enable-SPFeature -Identity $FeatureId -Url $_.Url -Confirm:$false -ErrorAction:SilentlyContinue -Force}
        $node.Status = "Feature Activated"
        }
        
        if($Enable -eq "N" -and $Enable -eq "n")
        {
        $objsite | Get-SPWeb -limit all | ForEach-Object {Disable-SPFeature -Identity $FeatureId -Url $_.Url -Force -Confirm:$false -ErrorAction:SilentlyContinue}
        $node.Status = "Feature Dectivated"
        }
        
        $objsite.Dispose();
        
              
        
         
        }
        catch
        {
        $ex = $_.Exception 
        $node.Status = "Failed to Activate: $ex.Message" 
        Write-Error "Error on $siteURL details: $ex.Message" 
continue 
        
        }
        finally
        {
        $objsite.Dispose();
        $SiteCollectionsXML.Save($filePath);
        }
        
          }
    }
        $SiteCollectionsXML.Save($filePath)
}
catch
{
       
    $ErrorMessage = $_.Exception.Message
    write-host $ErrorMessage 

    $FailedItem = $_.Exception.ItemName
    write-host $FailedItem 
       
    $node = $SiteCollectionsXML.SiteCollection.site | where {$_.GUID -eq $Guid}
    $node.Status = "Error"

    Add-Content -path $LogFile -value ("`n" + "Site URL : " + ($SiteCollectionUrl)  + ' Site GUID : ' + ($Guid) + ' Error: ' + ($ErrorMessage) )

    $SiteCollections.Save($filePath)

}

Stop-Transcript

XML Output

<SiteCollection>
  <site Count="1" URL="http://kmsnet:5500" GUID="870c5dbb-c1b8-417a-89b3-c428369b7e45" Status="Feature Activated" />
  <site Count="2" URL="http://kmsnet:5500/SC1/" GUID="888b3fd3-48a1-41c5-b1c9-bd5b9102b29f" Status="Feature Activated" />
  <site Count="3" URL="http://kmsnet:5500/SC2" GUID="9f6f0d3b-1e02-42e0-8fbd-070b298576dc" Status="Feature Activated" />

</SiteCollection>