Friday, June 29, 2012

Change SharePoint 2010 Authentication from Windows to Forms

While creating a web application, by mistake selected "Windows" authentication, and felt we need "Forms" authentication (Claims Based Authentication) because of a business requirement.

Went to Central Administration >> Application Management >> Manage Web Applications >> Selected the desired web application >> Authentication Providers.
Change SharePoint 2010 Authentication from Windows to Forms

Oops, "Forms" option is disabled! Couldn't find any way to enable "Forms" Authentication from user interface. Solution? PowerShell!

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

$WebApp=get-spwebapplication "http://sharepoint.crescent.com"
$WebApp.useclaimsauthentication="True"
$WebApp.Update()


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


Tuesday, June 26, 2012

Hide Contextual Search Scope from Search Dropdown

Requirement: Hide the contextual "This Site: Site Name" search scope from Search drop down.

Solution:
1. Copy the folder OSearchEnhancedFeature from "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\OSearchEnhancedFeature" as "OSearchNoContextScope"

2. Delete the SearchAdminLinks.xml file inside OSearchNoContextScope and remove the reference <ElementManifest Location="searchadminlinks.xml"/>  from Feature.xml

3. Edit the Feature.xml file, Change the Feature GUID, Feature Title, description.

4. Add <Property Name="DropDownMode">ShowDD_NoContextual</Property> in SearchArea.xml. Move the <Property Name="UseSiteDefaults">true</Property> next to it.

4. Build and Create a WSP. Deploy & activate the feature "Hide Contextual Search Scope Dropdown items" to see it in action!
Project structure
 
Before:

After:


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


Saturday, June 23, 2012

Report for SharePoint Access Request Email Configurations

Requirement:
People are moving to different roles, Few left the company from time to time. Access requests are sent to those in that kind. Its a problem! We had to monitor the access request configurations to make sure its sent to the relevant person. So, Wrote this PowerShell code to generate the report for SharePoint access request email address configurations.

PowerShell code to Generate Report on Access Requests Configuration:

#Set-ExecutionPolicy RemoteSigned
$OutputFN = "AccessRequestConfigs.csv"
#delete the file, If already exist!
if (Test-Path $OutputFN)
 { 
    Remove-Item $OutputFN 
 }
#Write the CSV Headers
"Site Collection Name, Site Name ,URL ,Access Requst E-Mail" > $OutputFN

# Get All Web Applications 
$WebAppServices=Get-SPWebApplication

foreach($webApp in $WebAppServices)
{

   # Get All Site collections
    foreach ($SPsite in $webApp.Sites)
    {
       # get All Sites 
       foreach($SPweb in $SPsite.AllWebs)
        {
          if($SPweb.RequestAccessEnabled -eq $True)
          {
           $SPsite.Rootweb.title + "," + $SPweb.title.replace(","," ") + "," + $SPweb.URL + "," + $SPweb.RequestAccessEmail >>$OutputFN
         
          }
          $SPweb.dispose()
        }
      $SPsite.dispose()
    }
  }

and the Output:
sharepoint 2010 access request email address

Here is the MOSS 2007 Version to get access request Emails:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null

#For SharePoint 2007 compatibility
function global:Get-SPSite($url){
    return new-Object Microsoft.SharePoint.SPSite($url)
}
 
#Get the web application
Write-Host "Enter the Web Application URL:"
$WebAppURL= Read-Host
$SiteColletion = Get-SPSite($WebAppURL)
$WebApp = $SiteColletion.WebApplication

$OutputFN = "AccessRequestConfigs.csv"
#delete the file, If already exist!
if (Test-Path $OutputFN)
 {
    Remove-Item $OutputFN
 }

#Write the CSV Headers
"Site Collection Name, Site Name ,URL ,Access Requst E-Mail" > $OutputFN
 
   # Get All Site collections
    foreach ($SPsite in $webApp.Sites)
    {
       # get All Sites
       foreach($SPweb in $SPsite.AllWebs)
        {
          if($SPweb.RequestAccessEnabled -eq $True)
          {
           $SPsite.Rootweb.title + "`t" + $SPweb.title + "`t" + $SPweb.URL + "`t" + $SPweb.RequestAccessEmail >>$OutputFN
          
          }
          $SPweb.dispose()
        }
      $SPsite.dispose()
    }

Related Posts:


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


Friday, June 22, 2012

How to Install PowerShell ISE in Windows Server 2008 R2

PowerShell ISE is a wonderful tool for creating, Debugging and executing PowerShell scripts. But it doesn't get installed automatically. Here is how to install PowerShell ISE in windows 2008 R2.

You don't have to download anything to get PowerShell ISE in Windows 2008 R2, Its a Instinct feature but not installed by default.

1. Go to Server Manager >> Features >> Add Features

powershell ise windows 2008 r2
2. From the features list choose "Windows PowerShell Integrated Scripting Environment"
powershell ise windows 2008 r2 install
3. Click Next and Install
enable powershell ise windows 2008 r2
Once installed, You can choose "Edit" from PowerShell Script files to launch PowerShell ISE.
powershell ise on windows 2008 r2
you can access the PowerShell ISE by typing "PowerShell_ISE" in Run box even!
install powershell ise on windows 2008 r2
Tail:
All these actions can be simply achieved by running these two lines of PowerShell:
Import-Module ServerManager
Add-Windowsfeature PowerShell-ISE


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


Trim audit log to Improve Performance in SharePoint

Found SharePoint content databases are growing even when no content was added from user side. I was analyzing SharePoint Database growth, went ahead and generated disk space report from SQL Server Management studio (Right click the database, choose Reports >> Standard Reports >> Disk Usage by Table) which gave me the clear picture: AuditData table was growing rapidly and occupying more disk space.
trim audit log sharepoint 2007
This is because of the auditing feature is turned ON for several Months and Audit logs are stored in the AuditData table of the content database. Auditing feature is great, but it can take so much disk space in a long run and we definitely want to put some cap to preserve system resources, especially database disk space.

SharePoint 2010 provides the interface to specify the number of days to retain audit logs and also provides an option to export the audit logs before truncate.
sharepoint 2010 trim audit logSo, we can adjust the settings to export and clear the audit logs in a interval.
trim audit log sharepoint 2010
trim audit log SharePoint 2010

Delete All Audit Logs Till Yesterday?
So, You noticed the logs are filling the disk space and want to delete all the audit logs, isn't it? No issues, Lets call PowerShell to rescue.
$site = Get-SPSite -Identity http://sharepoint.company.com
#To Get Yesterday
$date = Get-Date
$date = $date.AddDays(-1)
#Delete Audit logs
$site.Audit.DeleteEntries($date)

More info: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spaudit.deleteentries

How to trim audit log in SharePoint 2007?
In MOSS 2007 (after sp2), We have to manually do this trimming with: STSADM -o trimaudtilog.
After executing the above stsadm command, Shrink the database manually to regain the disk space.

stsadm -o trimauditlog –enddate 20120101 –databasename WSS_Content_Func_Finance

These trimming operations could cause blocks in database, which can prevent SharePoint sites from loading.
STSADM -o TrimAuditLog Reference
http://technet.microsoft.com/en-us/library/cc706879%28v=office.12%29

The above method of trimming audit log doesn't provide any way to export the audit log. So here is the workaround, Object model code which exports the audit logs programmatically and deletes.
http://blogs.msdn.com/b/sowmyancs/archive/2008/05/29/create-a-tool-or-interface-to-delete-the-audit-log-from-content-db-of-an-auditing-enabled-sharepoint-site.aspx

Codeplex tool to Trim audit logs for MOSS 2007 : http://sharepointauditlog.codeplex.com/


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


Wednesday, June 20, 2012

Find in Which Content Database Site Collection Lives

Requirement: Get which site collections resides in which content database.

Solution: Simplest method is: Navigate to Central Admin >> Application Management >> View All Site Collections .  This will display the content database name of a particular site collection.
site collection's content database sharepoint 2010
Site collection's content database in SharePoint 2010

PowerShell Script to get site collection's content database:
This code outputs the content database name of given site collection.
$site=Get-SPSite "http://sharepoint.crescent.com
write-host $site.ContentDatabase.Name

One-Liner to Find Content Databases of Site collections in SharePoint 2013:
Get-SPWebApplication | Get-SPSite | Select URL, @{Name="Database"; Expression={$_.ContentDatabase.Name}} 

Using STSADM to get Content Database of All site collections: Execute the STSADM as
STSADM -o enumSites -url http://SharePoint.Company.com > SitesList.xml

This will generate the SitesList.xml file with following information:
  1.  URL of site collections
  2.  Primary Owner
  3.  Secondary Owner
  4.  Content Database
  5.  Storage Used
  6.  Storage Warning
  7.  Storage Max
get site collection database
Report for site collection content database in SharePoint:
On a regular basis, Had to generate report with site collection databases information. PowerShell comes to rescue again!
function SitesInDB([string]$url)
{

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration") > $null

$rootSite = new-object Microsoft.SharePoint.SPSite($url)
$webApplication = $rootSite.WebApplication

$ContentDBCollection = $WebApplication.ContentDatabases

$DBName = [Microsoft.SharePoint.Administration.SPContentDatabase].GetProperty("Name")


#If Data directory already exists remove it
if (Test-Path "D:\Reports\SitesInDB\Data")
{
    Remove-Item "D:\Reports\SitesInDB\Data" -Recurse
}

# create a folder
mkdir D:\Reports\SitesInDB\Data

# Traverse through all the content databases and run the stsadm command
foreach($ContentDB in $ContentDBCollection){  
 $CurrentDBName = $DBName.GetValue($ContentDB, $null)
 stsadm -o enumsites -url $url -databasename $CurrentDBName > D:\Reports\SitesInDB\Data\$CurrentDBName.txt
 }

# check the folder "Data-YEAR-MM-DD exists already if so delete it
$newName = get-date -uformat "%Y-%m-%d"
if (Test-Path "D:\Reports\SitesInDB\Data-$newName")
{
    Remove-Item "D:\Reports\SitesInDB\Data-$newName" -Recurse
}

#rename the folder "Data" to "Data-YEAR-MM-DD"
ren D:\Reports\SitesInDB\Data D:\Reports\SitesInDB\Data-$newName
}

#Call the function
sitesInDB 'http://SharePoint.crescent.com'


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


Friday, June 15, 2012

How to Set Welcome Page Programmatically in SharePoint

By default, SharePoint uses "default.aspx" page as the welcome page (or Home page) in SharePoint 2007 and "SitePages/Home.aspx" in SharePoint 2010. It uses Pages/Home.aspx when publishing feature is enabled under MOSS 2007.

If you want to change Home Page, SharePoint provides users interface to set the welcome page once Publishing feature is enabled. (By going to Site actions >> Site Settings >> Welcome Page)
change sharepoint welcome page
and specify the welcome page
change sharepoint 2010 welcome page

What if You don't want to enable the publishing feature, but want to change the Welcome page? Just hit this URL in browser:

http://Sharepoint-site-URL/_layouts/AreaWelcomePage.aspx  ,change the Sharepoint-site-URL accordingly.

Want to do it Programmatically? Yes, We can set welcome page in SharePoint 2010 programmatically with Object Model. Here is how:

Change welcome page programmatically Using C# Object Model:
using (SPSite site = new SPSite("http://sharepoint.com")) 
   {
    using (SPWeb web = site.RootWeb) 
       {
        SPFolder rootFolder = web.RootFolder;
        rootFolder.WelcomePage = "Pages/HomePage.aspx";
        rootFolder.Update();
      }
   }

Set Welcome Page in SharePoint Using PowerShell:
$SiteUrl = "http://sharepoint.com"
$Site = Get-SPWeb -identity $SiteUrl
$RootFolder = $Site.RootFolder;
$RootFolder.WelcomePage = "SitePages/HomePage.aspx";
$RootFolder.Update();
$Site.Dispose()


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


Change All SharePoint Site's Access Request Emails with PowerShell

Some time back, I posted an article on Configuring Access Requests from SharePoint .Now, To take the control, Business decided to give the access control requests to SharePoint help desk, instead of site owners.

So, the requirement is: Update All SharePoint Site's Access request Emails to: SharePoint Help Desk's Mail id (SharePointSupport@Crescent.com). Lets change SharePoint access request email with PowerShell.

PowerShell Script to Change All SharePoint Site's access request Email addresses:
# Get All Web Application
$webApp=Get-SPWebApplication
   # Get All site collections
    foreach ($SPsite in $webApp.Sites)
    {
       # get the collection of webs
       foreach($SPweb in $SPsite.AllWebs)
        {
              # if a site inherits permissions, then the Access request mail setting also will be inherited
             if (!$SPweb.HasUniquePerm)
               {
                  Write-Host "Inheriting from Parent site"
               }
             elseif($SPweb.RequestAccessEnabled)
           {
              $SPweb.RequestAccessEmail ="SharePointSupport@crescent.com"
              $SPweb.Update()
           }
        }
    }

BTW, the RequestAccessEnabled is a Read-only property. But if you set the RequestAccessEmail, it will be enabled automatically! so the "elseif($SPweb.RequestAccessEnabled)" may not necessary! just an else will do!!

Here is the MOSS 2007 version of PowerShell to set access request Email Settings:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null

#For SharePoint 2007 compatibility
function global:Get-SPSite($url){
    return new-Object Microsoft.SharePoint.SPSite($url)
}
 
#Get the web application
Write-Host "Enter the Web Application URL:"
$WebAppURL= Read-Host
$SiteColletion = Get-SPSite($WebAppURL)
$WebApp = $SiteColletion.WebApplication

   # Get All site collections
    foreach ($SPsite in $webApp.Sites)
    {
       # get the collection of webs
       foreach($SPweb in $SPsite.AllWebs)
        {
              # if a site inherits permissions, then the Access request mail setting also will be inherited
             if (!$SPweb.HasUniquePerm)
               {
                  Write-Host "Inheriting from Parent site"
               }
             else
           {
              #$SPweb.RequestAccessEnabled=$true
              $SPweb.RequestAccessEmail ="support@crescent.com"
              $SPweb.Update()
           }
        }
    }


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


Tuesday, June 12, 2012

Iterate through All SharePoint Web Applications, Site Collections, Sub-sites, Lists and List Items Programmatically

Often in development, we may have to iterate through all web applications, Site collections, sites, Lists and List Items to get some job done or generate reports. Here are the code snippets to help.

Iterate Through all web applications, Site collections, Sites, Lists and List Items Using C#:

  
      static void Main(string[] args)
        {
                    SPFarm farm = SPFarm.Local;
                   //Get all SharePoint Web services
                    SPWebService service = farm.Services.GetValue<SPWebService>("");

                    foreach (SPWebApplication webapp in service.WebApplications)
                    {
                         Console.WriteLine(webapp.Name);
                        //Enumerate through each site collection
                        foreach (SPSite site in webapp.Sites)
                        {  
                            //Console.WriteLine(site.Url);
                            
                            //Enumerate through each sub-site
                            foreach (SPWeb web in site.AllWebs)
                            {  
                                //Console.WriteLine(web.Title);

                                //Enumerate through each List
                                foreach (SPList list in web.Lists)
                                {
                                    //Console.WriteLine(list.Title);
                                   //Enumerate through each list item
                                     foreach(SPListItem Item in list.Items)
                                     {
                                        //do something
                                     }

                                 }
                               
                            }
                          
                        }
                    }
                     //To pause: 
                    Console.ReadLine();
                }

Starting the Loop from Web Application:
                
                string site;
                Console.WriteLine("Enter the Web Application URL:");
                site = Console.ReadLine();
         
                SPSite tmpRoot = new SPSite(site);
                SPSiteCollection tmpRootColl = tmpRoot.WebApplication.Sites;

                //Enumerate through each site collection
                foreach (SPSite tmpSite in tmpRootColl)
                {
                   //Enumerate through each sub-site
                    foreach (SPWeb tmpWeb in tmpSite.AllWebs)
                    {
                        //Enumerate through each List
                        foreach (SPList tmpList in tmpWeb.Lists)
                        {
                            //Do something
                        }
                     }                 
                 }

You can directly start from Web Application URL also: Lets say, you want to find the content database of all site collection in a web application:

static void Main(string[] args)
        {
            SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://sharepoint.crescent.com"));

            foreach (SPContentDatabase cdb in webApp.ContentDatabases)
            {
                foreach (SPSite oSPSite in cdb.Sites)
                {
                    Console.WriteLine("Site:" +oSPSite.RootWeb.Title +" at "+oSPSite.RootWeb.Url + " lives in the database:" + cdb.Name);
                }
            }
            Console.ReadLine();
        }

Iterate Through all Web applications, Site collections, Sites, Lists and List Items With PowerShell:

# Get All Web Applications 
$WebApps=Get-SPWebApplication
foreach($webApp in $WebApps)
{ 
    foreach ($SPsite in $webApp.Sites)
    {
       # get the collection of webs
       foreach($SPweb in $SPsite.AllWebs)
        {
            write-host $SPweb.title ":" $spweb.URL
               foreach($list in $web.lists)
               {
                  foreach($item in $list.items)
                      {
                         Write-Host $item.Title
                      }
                 
               }
        }
    }
  } 

Another Shortcut Method: 
Get-SPWebApplication | Get-SPSite | Get-SPWeb -Limit All | ForEach-Object{ write-host Site Name: $_.Title, URL: $_.URL}

E.g. If you want to get all subsites to CSV File:
  
Get-SPSite "http://sharepoint.company.com/sales/" | Get-SPWeb -Limit All | Select Title, Url | Export-Csv -NoTypeInformation -Path "c:\sites.csv"

Iterate Through all Content Databases to get site collections in the DB:
#Get all SharePoint content Databases
$ContentDatabases=  Get-SPContentDatabase 

#Iterate through each Database
Foreach($Database in $ContentDatabases)
{
    Write-host "`nContent Database: "$Database.Name 
    #Get all site collections of the Database
    $Sites = $Database.Sites
    foreach($site in $Sites)
     {
     Write-host $Site.URL
     }
}
     

Similar reading: http://gallery.technet.microsoft.com/Maxer-for-SharePoint-2010-8cd0f26f


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


Alert Management Web Part - Released in CodePlex

Received lot of mails from People who read my post Alert Management Web part Mock-up on Alert Management Web Part Solution. So, I created a CodePlex Project to Share!

Business Problem:
In a Project management site, When new project sites created, Project Manager creates alerts for all team members in multiple Lists/Libraries.  Pain point is: He need to manually create alerts by going to each and every list/library >> Alert Me >> and then adding users to keep them informed. Yes, Its a pain for them to add users one by one in all of the lists and libraries,

Solution: we started creating Custom Alert Management web part which will solve this problem.

Key Features:
  • Create Alert for Multiple Lists/Libraries at one stretch
  • Edit/Delete Multiple alerts at one stretch based on Site/Sub-Site/User
Screens:
SharePoint 2010 Alert Management Web Part
sharepoint alert web part
Deployment Instructions:
Download the WSP from below CodePlex location, Add & Deploy the solution. Go to Site collection Features and activate the "Alert Management Web Part" Feature and then Add the "Alert Management Web Part" to any page.Works both in SharePoint 2007 and SharePoint 2010.

Released in Codeplex
I've published this project in Codeplex at: https://alertmanagement.codeplex.com/ , Enjoy!

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


Monday, June 11, 2012

SharePoint Web Services Exposed to Anonymous Access Users

Accidentally found my SharePoint Test environment's web services URLs are exposed in Google as anonymous access!
sharepoint web services anonymous access
 and I was able to access the web services anonymously!
sharepoint web services anonymous

Even though SharePoint web services exposed by anonymous access, SharePoint will not allow anyone to do beyond their access rights. Say for e.g. In order to call Add List Item method via web service, End user must have contributor permission at least.

But the problem is, It disposes lot of content via web services E.g. SiteData.asmx which exposes every page of our SharePoint site. We don't want to expose data to anyone, We don't want anonymous people to access our web-services, isn't it?

What is the Fix for SharePoint 2007 web services anonymous access?
Most of the Web services resides at "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI", which is mapped as a virtual folder "/_vti_bin".  So, Lets Instruct SharePoint to require authentication to /_vti_bin directory by editing the web.config file for the web application Under <configuration> Node:

sharepoint 2010 web service anonymous access
<!-- Disable anonymous access to _vti_bin -->
<location path="_vti_bin">
    <system.web>                  
        <authorization>
            <deny users="?" />
        </authorization>
    </system.web>
</location>

In the above web.config we've denied all the anonymous users and enabled only "_vti_bin/ReportServer/ReportServiceAuthentication.asmx" (Note: order is important!). Don't forget to do this change in All SharePoint servers! This will stop SharePoint web service anonymous access.

Output after the fix implemented:
sharepoint 2007 web services anonymous access

Technet Reference: http://technet.microsoft.com/en-us/library/ee191479%28v=office.12%29.aspx

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


Thursday, June 7, 2012

Programmatically Check whether a Particular List/Library Exists or Not

How to check if list exists in SharePoint programmatically?
SharePoint 2010 offers TryGetList Method to determine the existence of a List programmatically. TryGetList returns null, if the specified list doesn't exist.

SharePoint 2010 check if list exists:
using (SPSite site = new SPSite("http://sharepoint.company.com/sites/sales/"))
            {
                using (SPWeb web = site.RootWeb)
                 {
                       SPList ProjectList = Web.Lists.TryGetList("Project Documents");
                       if (ProjectList != null)
                         {
                             ProjectList.Delete();
                          }
                 }
         }


MOSS 2007: In SharePoint 2007, we have to write our own method to check if a particular list exists or not.
SharePoint 2007 check if list exists in C#:
     //Method to Get whether the particular list exists or Not
        public static bool ListExists(SPWeb web, string listName)
        {
            var lists = web.Lists;
            foreach (SPList list in lists)
            {
                if (list.Title.Equals(listName))
                    return true;
            }
            return false;
        } 


Before Deleting/creating a List, we can call the above function as:

 using (SPSite site = new SPSite("http://sharepoint.company.com/sites/sales/"))
              {
                using (SPWeb web = site.RootWeb)
                   {

                 if (ListExists(web, "Project Documents"))
                  {
                      web.Lists["Project Documents"].Delete();
 
                   }
  
                }

              }


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


Monday, June 4, 2012

Read From Excel & Import to Sharepoint List - Using Web Services

Another code snippet using SharePoint-Web Services. Requirement is: End-User wants to read data from Microsoft Excel (it will be placed at c:\contracts.xls) and append to SharePoint List (List Name: Contracts) on-demand from his desktop.

So the idea is: Lets build a console application, Add a web service reference to SharePoint List web service http://<Site>/_vti_bin/Lists.asmx and give it to the end user. Let him run the console application from his desktop on-demand.

using System;
using System.Collections;
using System.Data;
using System.Xml;
using System.IO;
using System.Data.OleDb;
using System.Data.Common;

namespace ReadFromExcelImportToSharePoint
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dt;
            string dt1;
   //initialize Web Service Reference
   Site1.Lists.Lists list = new ListWebservice.Site1.Lists.Lists();
   list.Credentials = System.Net.CredentialCache.DefaultCredentials;

            XmlNode contacts = list.GetList("Contracts");  

   XmlDocument doc = new XmlDocument();

   string listName = contacts.Attributes["ID"].Value;

            string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\contracts.xls;Extended Properties=""Excel 8.0;HDR=YES;""";
            DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OleDb");
            using (DbConnection connection = factory.CreateConnection())
            {
                connection.ConnectionString = connectionString;
                using (DbCommand command = connection.CreateCommand())
                {
                    command.CommandText = "SELECT * FROM [Sheet1$]";
                    connection.Open();
                    using (DbDataReader dr = command.ExecuteReader())
                    {
                        int i = 0;
                        while (dr.Read())
                        {
                            lblRecordNo.Text = i.ToString();

                            XmlElement elBatch = doc.CreateElement("Batch");
                            elBatch.SetAttribute("OnError", "Continue");
                            elBatch.SetAttribute("ListVersion", "1");

                            XmlElement el1 = doc.CreateElement("Method");
                            el1.SetAttribute("ID", "1");
                            el1.SetAttribute("Cmd", "New");

                            XmlElement field1 = doc.CreateElement("Field");
                            field1.SetAttribute("Name", "ID");
                            field1.InnerText = "New";

                            //From Here List Fields starts.
                            XmlElement field2 = doc.CreateElement("Field");
                            field2.SetAttribute("Name", "Title");
                            field2.InnerText = dr["i-Many number"].ToString();

                            XmlElement field3 = doc.CreateElement("Field");
                            field3.SetAttribute("Name", "Executing_x0020_Site");
                            field3.InnerText = dr["Executing Site"].ToString();

                            XmlElement field4 = doc.CreateElement("Field");
                            field4.SetAttribute("Name", "SAP_x002f_Legacy_x0020_Pricing_x");
                            field4.InnerText = dr["SAP/Legacy Pricing System"].ToString();

                            XmlElement field5 = doc.CreateElement("Field");
                            field5.SetAttribute("Name", "Customer_x0020_Name");
                            field5.InnerText = dr["Customer Name"].ToString();

                            XmlElement field6 = doc.CreateElement("Field");
                            field6.SetAttribute("Name", "Type_x0020_of_x0020_Contract");
                            field6.InnerText = dr["Type of Contract"].ToString();

                            XmlElement field7 = doc.CreateElement("Field");
                            field7.SetAttribute("Name", "Contract_x0020_Description");
                            field7.InnerText = dr["Contract Description"].ToString();

                            XmlElement field8 = doc.CreateElement("Field");
                            field8.SetAttribute("Name", "Effective_x0020_Date");
                            dt = Convert.ToDateTime(dr["Effective Date"].ToString()) ;
                            dt1=dt.ToString("u");
                            field8.InnerText = dt1;
                        
                            XmlElement field9 = doc.CreateElement("Field");
                            field9.SetAttribute("Name", "SBU");
                            field9.InnerText = dr["SBU"].ToString();

                            XmlElement field10 = doc.CreateElement("Field");
                            field10.SetAttribute("Name", "Customer_x0020_Type");
                            field10.InnerText = dr["Customer Type"].ToString();

                            elBatch.AppendChild(el1);

                            el1.AppendChild(field1);
                            el1.AppendChild(field2);
                            el1.AppendChild(field3);
                            el1.AppendChild(field4);
                            el1.AppendChild(field5);
                            el1.AppendChild(field6);
                            el1.AppendChild(field7);
                            el1.AppendChild(field8);
                            el1.AppendChild(field9);
                            el1.AppendChild(field10);
                            XmlNode rNode = list.UpdateListItems(listName, elBatch);

                            // 0x00000000 returned means that the list item was inserted correctly...
                           //   Console.WriteLine(rNode.InnerText);

                            i = i + 1;
                        }
                    }
                }
            }
       Console.WriteLine("No.of Records Imported:" +i);
          }
       } 
   }


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


Saturday, June 2, 2012

Setting up Scopes in SharePoint Search Results

Requirement is: When user search from a particular site collection, either the default search result or advanced search result, should get content ONLY from a list of sites.

Solution? Search Scopes! Search scopes in SharePoint allows users to narrow down the search results based on content sources, web addresses, and metadata. So, I created a scope "Search All Marketing Sites" to include all marketing websites URLs. Now, I'm jumping to setting up scope on Search results directly.

For Default Search Results:
I created a separate search center site, edited the search results page (/SearchCenter/Pages/Results.aspx) Search core results web part properties, Expand the Miscellaneous section and entered the scope.
sharepoint search scope result page
SharePoint search scope result page
Pretty straight forward, isn't it?

How about Advanced Search?
For advanced search, scopes are not configured in web part properties as in default search results. But, Its on Site collection's scope settings. Navigate to top level site collection's Site settings >> Search Scopes and then click on "Advanced Search"
sharepoint search core results scope
This will show all available scopes. Choose the desired scope from the list and click OK.
sharepoint 2007 search results scope Once done, All the advanced search results page will be restricted to the specified scope.


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


Site Traffic Hits Report on Every Item on a SharePoint Site

Requirement: Get the site traffic hits count for the past 30 days on each and every File/List/Page/etc stored on a MOSS 2007 site.

C# Object Model code to Generate SharePoint hits report:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Data;
using System.Diagnostics;
using System.IO;

namespace SharePoint.AdminReport
{
    class GetSiteUsageReport
    {
        //Method to Convert Data Table to CSV
        public static string ToCSV(DataTable table, string webURL)//, string listURL) 
        { 
            var result = new StringBuilder();

              foreach (DataRow dr in table.Rows)
              {
                  result.Append(webURL + "\t" + (dr["Folder"].ToString() == "" ? "" : "/") + dr["Folder"].ToString() + "/" + dr["Page"].ToString() + "\t" + dr["Total Hits"].ToString() + "\t" + dr["Most Recent Day"].ToString() + "\n");
              }
            return result.ToString(); 
        } 

        //Method to Get Usage Data
        public static DataTable GetWebUsageData(SPWeb oSPWeb)
        {
            try
            {
                //DataTable for Hits result - Because GetUsageData returns DataTable!
                DataTable dtHits = new DataTable();

                dtHits = oSPWeb.GetUsageData(SPUsageReportType.url, SPUsagePeriodType.lastMonth);
                if (dtHits != null)
                {
                    return (dtHits);
                }
                else
                {
                    return (null);
                }
            }
            catch (Exception Ex1)
            {
                return (null);
            }
        }


        static void Main(string[] args)
        {
            string site;

            try
            {
                if (args.Length == 0)
                {
                    Console.WriteLine("Enter the Site Collection URL:");
                    site = Console.ReadLine();
                }
                else
                {
                    site = args[0];
                }

                SPSite tmpSite = new SPSite(site);
                //objects for the CSV file generation
                StreamWriter sw = new StreamWriter("c:\\SiteUsageReport.csv",false); 

                //Write the CSV Header
                sw.Write("Site \t Page \t Total Hits \t Most Recent Day \n");
                    
                   //Enumerate through each sub-site
                    foreach (SPWeb tmpWeb in tmpSite.AllWebs)
                    {
                            //DataTable for Hits set - Because GetUsageData returns DataTable!
                            DataTable dtHits = new DataTable();
                            dtHits = GetWebUsageData(tmpWeb);

                            if (dtHits != null)
                            {

                            string result = ToCSV(dtHits, tmpWeb.Url);

                                     sw.Write(result);
                            }
                    }
                //Dispose of the Root Site Object
                sw.Close();
                tmpSite.Dispose();
            }

            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("Site Usage Report", ex.Message);
            }
               
        }
    }
}

and the Output:
sharepoint site usage report total hits

 With Pivot Analysis:
sharepoint site hits report

PowerShell version:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
 
#Functions to Imitate SharePoint 2010 Cmdlets in MOSS 2007
function global:Get-SPWeb($url) 
{
  $site= New-Object Microsoft.SharePoint.SPSite($url)
        if($site -ne $null) 
        {
              $web=$site.OpenWeb();       
        }
    return $web
}

 
        #Method to Get Usage Data
        Function GetWebUsageData($Web)
        {
            try
            {
                #DataTable for Hits result - Because GetUsageData returns DataTable!
                $dtHits = New-Object System.Data.DataTable  
 
                $dtHits = $Web.GetUsageData("url", "lastMonth") 

                if ($dtHits -ne $null)
                {
                    return ($dtHits);
                }
                else
                {
                    return ($null);
                }
            }
            catch 
            {
                Write-Host $_.Exception.Message -ForegroundColor Red
                return ($null);
            }
        }
 
    $WebURL = "http://sharepoint.crescent.com/operations/sfdc/"
    
    $CurrentPath = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
    $OutPutFile = Join-path $CurrentPath "SiteUsageReport.txt"
    
    #Get the Web
    $Web = Get-SPWeb $WebURL
 

    #create a CSV file
    "Page `t Total Hits `t Last Accessed" > $OutPutFile #Write the Headers in to a text file

    #Get the Hits Data
    $HitsDT = GetWebUsageData($Web)
    if ($HitsDT -ne $null)
    { 
        foreach($dr in $HitsDT)
        {
          
          $result = $webURL +"/" + $dr["Folder"]+"/"+$dr["Page"] + "`t" + $dr["Total Hits"] + "`t" + $dr["Most Recent Day"]
          $result >> $OutPutFile  #append the data
        }
    }


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


Friday, June 1, 2012

Custom 404 Page Not Found Error Page in SharePoint 2010

Its a best practice to show customized 404 page not found error page for any website when user request for a broken URL or mistyped URLs. SharePoint has no exclusions. By default, SharePoint gives this 404 error screen to the user:
sharepoint page not found 404 error

So, Its great to have custom 404 Page not found error page in SharePoint 2010 to add some user experience, isn't it? Lets see how custom 404 error page in SharePoint can be done:

1. Create an aspx page in Root site collection (say, "\SitePages\CustomError.aspx"). Add some descriptive image and text to it.

2. Go to IIS Manager, Backup the web.config file and proceed with the following steps.

3. Expand the desired web application, open the "Error Pages" feature.
custom 404 page for sharepoint
4. Double click on 404 status code
sharepoint custom 404
 This will open the "Edit Custom Error Page" configuration window.sharepoint custom 404 error
Change the option to: "Execute a URL on this site" and specify the URL as: /SitePages/custom404.aspx (The Error page we have created!). Click Ok and quit IIS.
sharepoint custom 404 web.config

5. By now, If you open the web.config file, you could see the <httpErrors> section as:
        <httpErrors>
            <remove statusCode="404" subStatusCode="-1" />
            <error statusCode="404" prefixLanguageFilePath="" path="/SitePages/custom404.aspx" responseMode="ExecuteURL" />
        </httpErrors>

Add these attributes to <httpErrors> node: errorMode="Custom" existingResponse="Auto" so, the modified code would be:
        <httpErrors errorMode="Custom" existingResponse="Auto">
            <remove statusCode="404" subStatusCode="-1" />
            <error statusCode="404" prefixLanguageFilePath="" path="/SitePages/custom404.aspx" responseMode="ExecuteURL" />
        </httpErrors>

6. Save web.config and do IISReset if needed. In fact, we can just skip the IIS console and place the above code directly in web.config! That's all, we are done with SharePoint custom page not found.

Once done, you should be able to get our custom 404 page content when you hit broken/deleted /mistyped URLs.
custom 404 page for sharepoint 2010

There is an alternate method by setting custom 404 redirect page in SharePoint. Refer the KB Article: http://support.microsoft.com/kb/941329


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...