Thursday, October 30, 2014

Change Page Layout in SharePoint 2013 using PowerShell

In a public internet SharePoint web site based on publishing site template, We got a requirement to update existing page layouts and create new ones. So, the development team created new page layouts, Updated existing Page layouts with required changes. Any page going to be created with these updated page layouts will have the changes reflected. Well, How about existing pages created with the old page layouts? There is a requirement to switch page layouts for few pages.

While its possible to change page layout through SharePoint web interface (Click on Edit Page >> Under "Page" Tab, Click on "Page Layout" and pick the different page layout you would like to set!), It would take hours to update page layout of all existing pages. So, I wrote this script to change page layout in SharePoint 2013 using PowerShell.

Change SharePoint page layout using PowerShell:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Variables for Web and Page URLs
$WebURL="http://portal.crescent.com/sites/sales/"
$PageURL="http://portal.crescent.com/sites/sales/Pages/About-us.aspx"
$PageLayout="http://portal.crescent.com/_catalogs/masterpage/GlobalFunctionsPageLayout.aspx"

#Get the web and page
$Web = Get-SPWeb $WebURL
$File = $Web.GetFile($PageURL)

#change page layout sharepoint 2013 powershell 
$File.CheckOut("Online",$null)
$File.Properties["PublishingPageLayout"] = $PageLayout
$File.Update()
$File.CheckIn("Page layout updated via PowerShell",[Microsoft.SharePoint.SPCheckinType]::MajorCheckIn)

$Web.Dispose() 

In an another case, During a site migration, I had to use this same method to change page layouts using PowerShell.
"This page is not using a valid page layout. To correct the problem edit page settings and select a valid page layout." 

This is because, Page layout URLs are hard-coded in publishing pages. When you move them from one site to another, We got to update it.

SharePoint 2010 change page layout using PowerShell:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Variables for Web and Page URLs
$WebURL="http://www.crescent.com/company-profile/"
$OldPageLayoutName="About-us.aspx"
$NewPageLayoutName="About-us-V2.aspx"

#Get the web and page
$Web = Get-SPWeb $WebURL

#Get Publishing Site and Web
$PublishingSite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($Web.Site)
$PublishingWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)

#Get New Page Layout
$SitePageLayouts = $PublishingSite.GetPageLayouts($false)
$NewPageLayout = $SitePageLayouts | ? {$_.Name -eq $NewPageLayoutName}

#Get Pages Library
$PublishingPages = $PublishingWeb.GetPublishingPages()

#Iterate throgh each page
foreach ($Page in $PublishingPages)
{
    if ($Page.Layout.Name -eq $OldPageLayoutName)
    {
        $Page.CheckOut()
        $Page.Layout = $NewPageLayout
        $Page.ListItem.Update();
        $Page.CheckIn("Page layout Updated via PowerShell")
    
        #$page.ListItem.File.Publish("")
        if ($Page.ListItem.ParentList.EnableModeration)
        {
            $Page.ListItem.File.Approve("Publishing Page Layout Updated!");
        }

     write-host "Updated Page layout on: "$Page.url
    }
}
$Web.Dispose() 

The above script scans all publishing pages with an existing old page layout and changes page layout in 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


Wednesday, October 29, 2014

Archive SharePoint Library Files into Sub-Folders using PowerShell

Requirement: We've a very large library with more than 20,000 files stored in the root of the document library without any sub-folders. Got to move files into Sub-folders to improve performance.

Solution: We analyzed the library content and decided to move files into sub-folders based on file's created date.

PowerShell script to move files into sub-folders in SharePoint document library:
#Import PowerShell Snap-in
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue

#Create a custom function to archive files
Function Archive-Files($WebURL, $ListName)
{
 #Get the web and List
 $Web = Get-SPWeb $WebURL
 $List= $web.Lists[$ListName]

 $RootItems = $List.RootFolder.files 
 Write-host "Total number of files found in the Root: "$RootItems.count

 #Move each file in the root folder to archive folder
 foreach($item in $RootItems)
 {
   #Get the File
   $file = $Web.GetFile($item.URL)

   #Get the Month & Year values from the File's crated date
   $MonthYearValue = $file.TimeCreated.ToString('MMM-yyyy')
   
   # Try to Get the Archive Sub-Folder in the target Library
   $TargetFolder = $List.ParentWeb.GetFolder($List.RootFolder.Url + "/" +$MonthYearValue);
   
   #If the Archive folder doesn't exist, Create it!
   if ($TargetFolder.Exists -eq $false)
    {
       $TargetFolder = $List.Folders.Add("", [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, $MonthYearValue)
       $TargetFolder.Update() 
    }
    #Move the File
    $file.MoveTo($TargetFolder.Url + "/" + $File.name)  
  }
}

#Call the function to Archive Files
Archive-Files "http://sharepoint.crescent.com/sites/marketing/" "Invocies"
This script preserves Metadata, BTW! You can also move files into sub-folders of an another SharePoint library for archival.

Move List Items to Sub-Folders using PowerShell:
In an another scenario, had to move List items to Sub-folders. Here is the script:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

#Variables
$WebURL = "https://portal.crescent.com/News/"
$ListName ="News List"

#Get site object
$Web = Get-SPWeb $WebURL
$List = $Web.Lists[$ListName]
$TargetFolder = $Web.ServerRelativeUrl + "/" + $List.RootFolder.Url + "/"+ "2014/Jan"

#Get all Files Created specific time frame
$Query = '<Where><And><Geq><FieldRef Name="Date" /><Value Type="DateTime">2014-01-01T00:00:00Z</Value></Geq><Leq><FieldRef Name="Date" /><Value Type="DateTime">2014-01-31T00:00:00Z</Value> </Leq> </And> </Where>'
$SPQuery = new-object Microsoft.SharePoint.SPQuery
$SPQuery.ViewAttributes = "Scope='Recursive'" #To include Sub-folders in the library
$SPQuery.Query = $Query
$ItemCollection =$List.GetItems($SPQuery)

Foreach($Item in $ItemCollection)
{
    $File=$Web.GetFile($Item.URL)
    $TargetPath=$TargetFolder+"/"+$Item.ID.ToString()+"_.000"
    $File.MoveTo($TargetPath)
    write-host "Moved Item:"$Item.ID
}

Write-host "Total Items Moved:"$ItemCollection.count


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


Monday, October 27, 2014

Get SharePoint Documents Inventory Report with PowerShell

This PowerShell script generates detailed report on the given SharePoint library's inventory in addition with its storage data. The output report contains:
  • File Name
  • File Size(KB)
  • Versions Size(KB)
  • Total File Size(KB)
  • Created on
  • Last Modified
  • Created by
  • Parent Folder
  • URL
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue

# Function to retrieve detailed Library storage Report
Function GetLibraryStorageRpt($Folder)
{
    #Array to hold Storage data for all files
    $StorageDataCollection = @()
    
    $FileSize = 0
 $TotalFileSize = 0
    foreach ($File in $Folder.Files)
    {
        #Get File Size
        $FileSize = $File.TotalLength
        
        $VersionSize = 0
        #Get the Versions Size
        foreach ($FileVersion in $File.Versions)
        {
            $VersionSize +=$FileVersion.Size
        }
        $TotalFileSize = $FileSize + $VersionSize
  
        $StorageDataResult = New-Object PSObject
 
        $StorageDataResult | Add-Member -type NoteProperty -name "File Name" -value $File.Name
        $StorageDataResult | Add-Member -type NoteProperty -name "File Size(KB)" -value $($FileSize/1KB)
        $StorageDataResult | Add-Member -type NoteProperty -name "Versions Size(KB)" -value $($VersionSize/1KB)
        $StorageDataResult | Add-Member -type NoteProperty -name "Total File Size(KB)" -value $($TotalFileSize/1KB)
        $StorageDataResult | Add-Member -type NoteProperty -name "Created on" -value $File.TimeCreated 
        $StorageDataResult | Add-Member -type NoteProperty -name "Last Modified" -value $File.TimeLastModified 
        $StorageDataResult | Add-Member -type NoteProperty -name "Created by" -value $File.Author.Name        
        $StorageDataResult | Add-Member -type NoteProperty -name "Parent Folder" -value $File.ParentFolder.URL
  $StorageDataResult | Add-Member -type NoteProperty -name "URL" -value $File.URL

        $StorageDataCollection += $StorageDataResult
 #Write-Host "Processing File:"$File.Name
    } 
      #Get Files in Sub Folders
        foreach ($SubFolder in $Folder.SubFolders)
        {   
         if($SubFolder.Name -ne "Forms") #Leave "Forms" Folder which has List default Aspx Pages.
             {
                GetLibraryStorageRpt($SubFolder)          
             }
        }   
    return $StorageDataCollection
}

#Input Variables 
$WebURL = "http://sharepoint.crescent.com/sites/operations" 
$ListName ="Documents"

#Get the List
$List = Get-SPWeb $WebURL | Select -ExpandProperty "Lists" | Where-Object{$_.Title -eq $ListName}

#Call the function to get data 
$StorageDetails = GetLibraryStorageRpt($List.RootFolder)

write-host "Total Number of Files:" $List.ItemCount 
write-host "Library Created by:" $List.Author

#Calculate the Total Size
$TotalSize = ($StorageDetails | Measure-Object 'Total File Size(KB)' -Sum | Select -expand Sum)  
Write-host "Library Size in MB: "([Math]::Round( ($TotalSize/1024),2))

#Export the data to CSV File
$StorageDetails | sort-object "Total File Size" -descending | Export-csv "$($ListName)_LibraryStroageRpt.csv" -notypeinformation
Write-Host "Storage Report has been Generated!"
 


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


Saturday, October 25, 2014

Some Farm Products and patches were not detected on this or other servers - Fix

After patching a SharePoint 2013 Farm, Attempted running SharePoint Products configuration wizard and receive this error message:
"Error: Some farm products and patches were not detected on this or other servers.  If products or patches are missing locally, you must quit this program and install the required products and patches on this server before restarting this wizard. If products or patches are missing on other servers, you must install the required products and patches on the specific servers, and you may then click the Refresh button to perform the status check again."
Error: Some Farm Products and patches were not detected on this or other servers

Root Cause:
To enforce consistency, SharePoint 2013 checks installed product version automatically on running Products configuration wizard. If any server is missing a specific patch, You get this error message and SharePoint would not let the SharePoint Configuration Wizard to proceed.

Solution:
Install the missing patches on your SharePoint Servers and rerun this wizard!

But wait, in my case, I'm sure all patches are installed without error on all servers. I tried running the patch again and got "The upgrade is already installed on this system" error. I verified it via Control panel >> Programs and Features >> recently installed updates. Tried restarting each SharePoint server, Still SharePoint thinks I have not patched one of the server! Hmmm...

Finally, Found this solution: Run this PowerShell command from servers reported:
Get-SPProduct -local
This command refreshes the installed patch data. Triggering "Product Version Job" timer job also helps!

Tail: If you are very sure, You have patched all servers with similar installers, you can bypass the check by:
psconfig.exe -cmd installcheck -noinstallcheck

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


SharePoint Active Directory Group Membership Sync Problem and Solution

Problem: SharePoint AD group permissions are not working immediately. Active directory group users get access denied in SharePoint!

In a SharePoint site where users are managed from AD security groups, newly added members to Active Directory security groups couldn't access SharePoint sites immediately. But the next day, they are able to login without any issues. Same way, users removed from a AD security group which is granted access to SharePoint sites, still able to access!
sharepoint ad group permissions not working
So, the catch here is: SharePoint AD group permissions not working as AD group permissions are not getting reflected in SharePoint immediately - So, they gets access denied! For example if you remove a user from the AD security group - user is still able to access the site. If you add a new user to the AD security group membership , user still receives access denied error message in SharePoint.

Root cause:
In SharePoint Web Applications configured to use Claims Based Authentication, When user hits SharePoint sites, SharePoint checks the security token store cache for the user's claims. If claims found in the cache, SharePoint uses it to authorize the user. If not, SharePoint queries for claims again from the AD.

Since, SharePoint has no clues on modified permissions on AD group, it periodically expires the claims token to sync with AD group permissions. By default, this sync happens once per 10 Hours!

Solution:
Lets use PowerShell to set the token life time and expiration schedules:
Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue

#Get Security Token Service Configuration
$STSConfig = Get-SPSecurityTokenServiceConfig

#Default value: 10 Hours
$STSConfig.WindowsTokenLifetime = (New-TimeSpan -minutes 2)

#Default value: 10 Minutes
$STSConfig.LogonTokenCacheExpirationWindow = (New-TimeSpan -minutes 1)
$STSConfig.Update()

IISReset
Important: If you set Token lifetime lesser than the token expiration window, You’ll start seeing a message "The context has expired and can no longer be used. Exception from HRESULT: 0x80090317", So don't do it!

SharePoint ad group new members gets access denied - permission problem in Classic Mode?
On classic mode authentication, This behavior is controlled by a property:token-timeout by default, its set to 24 hours! You can adjust it accordingly.

To check the current timeout value: stsadm -o getproperty -propertyname token-timeout

E.g. stsadm -o setproperty -pn token-timeout -pv 5


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


Thursday, October 23, 2014

Set SharePoint Application Pool Recycle Time

By design application pools in IIS are restarted once per every 29 hours to provide best performance and stability. The very first user access SharePoint after app pool recycle will experience considerable delay, as .net assemblies needs to be recompiled to the memory. So, we use Warm-up scripts for SharePoint 2013 to mitigate this issue.

Configure Application Pool Recycle time Settings
Lets customize SharePoint 2010/SharePoint 2013 application pool recycling settings, So that our Warmup script run just after the specific time.

  • Go to IIS Manager >> Application Pools >> Pick your App Pool 
  • Right Click and choose "Recycling..." .

You'll find the recycling conditions. time attribute under "Recycling " group. You can adjust this setting to incorporate with your Warm-up script schedule. Just make your warmup script to run after the App Pool recycle time. Enter the specific time, Click Next and then Finish.

You can also set the recycle time in Application pool's advanced settings
sharepoint application pool recycle time
Don't disable Application Pool recycling by removing the Time Span values, You'll run in to memory leaks which could lead to web server out of memory issues!

Configure Application Pool Recycling time with PowerShell:
Import-Module WebAdministration

$AppPoolName = "SP13_Intranet_AppPool"

Set-ItemProperty -Path "IIS:\AppPools\$AppPoolName" -Name Recycling.periodicRestart.schedule -Value @{value="03:00"}
Consider Recycling application pools at different times in different Web servers to provide maximum availability!


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


Wednesday, October 22, 2014

Copy List Permissions in SharePoint using PowerShell

Ever wanted to clone permissions between SharePoint lists or Libraries? Well, Here is the nifty PowerShell script to copy permissions between SharePoint lists:
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue

#PowerShell Function to copy permissions between Lists in SharePoint
Function Copy-ListPermissions()
{
 param(
     $WebURL,
     $SourceListName,
     $TargetListName
 )
 #Get the Web
 $Web = Get-SPweb $WebURL

 #Get Source and Target Lists
 $SourceList = $Web.lists[$SourceListName]
 $TargetList = $Web.lists[$TargetListName]

 #if permissions are Inherited in Source, apply it in Target list 
  if($SourceList.Permissions.Inherited)
   {
      $TargetList.ResetRoleInheritance()
   }
  else #Copy permissions from Source to Target List
  {
     #Reset the Inheritence in Target List
     $TargetList.BreakRoleInheritance($false)

     #Copy Source list permissions to Destination List
     $SourceList.RoleAssignments | foreach-object {
     $targetList.RoleAssignments.Add($_)
      }
  }
 $TargetList.Update()
}
#Call the function to copy list permissions 
Copy-ListPermissions "http://sharepoint.crescent.com/sites/operations/us" "Documents" "Invoice"
This script copies all users and groups from the source list to target list. Any custom permissions already applied on the target list will be lost!

The above method can be used to copy permissions between SharePoint list items and sites.

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


How to Add HOST file Entry using PowerShell

Here is the nifty PowerShell script to add HOST file entry using PowerShell:
$HostFile = 'C:\Windows\System32\drivers\etc\hosts'

# Create a backup copy of the Hosts file
$dateFormat = (Get-Date).ToString('dd-MM-yyyy hh-mm-ss')
$FileCopy = $HostFile + '.' + $dateFormat  + '.copy'
Copy-Item $HostFile -Destination $FileCopy

#Hosts to Add
$Hosts = @("intranet.Crescent.com", "Intranet", "mysite.crescent.com")

# Get the contents of the Hosts file
$File = Get-Content $HostFile

# write the Entries to hosts file, if it doesn't exist.
foreach ($HostFileEntry in $Hosts) 
{
    Write-Host "Checking existing HOST file entries for $HostFileEntry..."
    
    #Set a Flag
    $EntryExists = $false
    
    if ($File -contains "127.0.0.1 `t $HostFileEntry") 
    {
        Write-Host "Host File Entry for $HostFileEntry is already exists."
        $EntryExists = $true
    }
    #Add Entry to Host File
    if (!$EntryExists) 
    {
        Write-host "Adding Host File Entry for $HostFileEntry"
        Add-content -path $HostFile -value "127.0.0.1 `t $HostFileEntry"
    }
}
SharePoint HOST File PowerShell
Add entry to HOST file using PowerShell


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


Sunday, October 19, 2014

Expand Collapse SharePoint Web Parts using jQuery

Requirement: Expand Collapse SharePoint list view web parts in Home page.

Solution: We can implement Expand collapse functionality in SharePoint 2013 using jQuery. Here is how to expand/collapse web parts in SharePoint using jQuery.

Just grab the IDS of List view web part (WebPartWPQ3) and Web part header (in my case: WebPartTitleWPQ3) using IE developer toolbar or Firebug in Firefox.
 expand collapse webparts in sharepoint 2010

jQuery to provide Expand-Collapse functionality for SharePoint 2013 web parts:
Add this jQuery to the page with Script editor web part.
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" >
  jQuery(document).ready(function() {
  jQuery("#WebPartWPQ3").hide();

//Add Expand Icon to Web Part Header
    $('Span#WebPartTitleWPQ3').find('h2').append("<span style='padding-left:0.5em; text-decoration:none'> <img id='ExpandCollapse' src='/_layouts/images/Expand.gif'></span>");

  //toggle the component with class msg_body
  jQuery(".ms-webpart-chrome-title ").click(function()
  {
    jQuery(this).next("#WebPartWPQ3").slideToggle(400);

   //Replace Expand-Collapse Image   
   var ExpandCollIMG = $('img#ExpandCollapse').attr('src');
   if (ExpandCollIMG === '/_layouts/images/COLLAPSE.gif' ) 
    {
        $('img#ExpandCollapse').attr('src', '/_layouts/images/Expand.gif');
    }
   
   if ( ExpandCollIMG === '/_layouts/images/Expand.gif' ) 
    {
        $('img#ExpandCollapse').attr('src', '/_layouts/images/COLLAPSE.gif');
    }
  });
});

</script>

Result: You'll get Expand-collapse buttons next to web part titles.
how to expand/collapse webparts in sharepoint using jquery
Expaned document library:
expand collapse sharepoint 2010 webpart

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


Saturday, October 18, 2014

Add-Remove Permissions to SharePoint List using PowerShell

Here is my PowerShell script to grant and remove permissions to SharePoint sites, lists and libraries,

Grant Permission to a user or group to SharePoint List
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Function to Grant Permission to List
function Grant-PermissionToList($WebUrl, $ListName, $UserAccount, $PermissionLevel)
{
    #Get Web and List objects
    $Web = Get-SPWeb -Identity $WebUrl
    $List = $web.Lists.TryGetList($ListName)

    if ($List -ne $null)
    {
        #We must break inheritance to grant permission directly on the list
        if ($List.HasUniqueRoleAssignments -eq $False)
        {
            $list.BreakRoleInheritance($True)
        }

        #Get the user object
        $User = $web.EnsureUser($UserAccount)
        #FOR GROUPS use: $group = $web.SiteGroups[$GroupName]
        #$assignment = new-object Microsoft.SharePoint.SPRoleAssignment($group)
            
        #Get the permission level
        $role = $web.RoleDefinitions[$PermissionLevel]
        $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($User)
        $assignment.RoleDefinitionBindings.Add($role) 
        $list.RoleAssignments.Add($assignment)
        $list.Update()

        Write-Host "Granted permission $($PermissionLevel) to $($UserAccount) in list $($ListName)." -foregroundcolor Green        
    }
    $web.Dispose()
}

#Call the function to grant access to a list
Grant-PermissionToList "http://sharepoint.crescent.com" "Documents" "Global\Auditors" "Contribute" 
                
PowerShell script to remove permission from the List:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Function to Remove Permission from List
function Remove-PermissionFromList($WebUrl, $ListName, $GroupName, $PermissionLevel)
{
    #Get Web and List objects
    $Web = Get-SPWeb -Identity $WebUrl
    $List = $web.Lists.TryGetList($ListName)

    if ($List -ne $null)
    {
        #We must break inheritance to remove permission directly from the list
        if ($List.HasUniqueRoleAssignments -eq $False)
        {
            $list.BreakRoleInheritance($True)
        }

        #Get the Group or user object
        $group = $web.SiteGroups[$GroupName]
        
        if($group -ne $null)
        {
            #For User, use: $User = $web.EnsureUser($UserAccount)
            #To Remove All permissions of the group, use: 
            #$list.RoleAssignments.Remove($group)    

             #If group doesn't has access to the given list, it triggers an error! So, lets handle it.
             try
             {
                #Set the Error Action
                $ErrorActionPreference = "Stop"
                #Get the permission level
                $role = $web.RoleDefinitions[$PermissionLevel]
                $assignment = $list.RoleAssignments.GetAssignmentByPrincipal($group)
                #Remove the permissions
                $assignment.RoleDefinitionBindings.Remove($role)
                $assignment.Update()

                $list.Update()
                Write-Host "Removed permission $($PermissionLevel) of $($GroupName) from list $($ListName)." -foregroundcolor Green

             }
             catch [ArgumentException] 
             {
                Write-Host "Group ($GroupName) doesn't has access on $($ListName)!" -ForegroundColor Red
             }
             finally
             {
                #Reset the Error Action to Default
                $ErrorActionPreference = "Continue"
             }            
        }
        else
        {
            Write-Host "Cannot find Group Name: $($GroupName) in site $($WebUrl)." -foregroundcolor red
        }        
    }
    $web.Dispose()
}

#Call the function 
Remove-PermissionFromList "http://Sharepoint.crescent.com/sites/sales" "Sales Documents" "Sales Members" "Edit"              
Although this script shows adding removing permissions to SharePoint list objects, This can be utilized in the places of Site, Folder, List Item object also! Just replace $list object with other objects such as web, folder or list item. You can grant or remove permission either to a particular user, To a SharePoint group or to a Security group from Active directory.

To add user to SharePoint group with PowerShell, Refer: How to Add User To SharePoint Site using PowerShell

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


Friday, October 17, 2014

SharePoint PowerShell Error: Cannot open database "Database-Name" requested by the login. The login failed. Login failed for user 'Domain\UserName'.

Problem:  SharePoint Admin tried backing up a SharePoint 2013 site collection with Backup-SPSite PowerShell cmdlet and got an error "Cannot open database "WSS_Content_demo" requested by the login. The login failed. Login failed for user 'HOSTING\DemoUser'."
Cannot open database database-name requested by the login. The login failed. Login failed for user

Root cause:
Although the SharePoint administrator is granted permission with "Add-SPShellAdmin" cmdlet, it grants permission to the user only on existing SharePoint content databases at the time of running this command. For new content databases created later on, we have to grant permission again!

Solution:
Run "Add-SPShellAdmin" cmdlet for the user. This gives access to all SharePoint databases:
 Get-SPDatabase | Add-SPShellAdmin "Domain\User"

Read more: How to grant access to run PowerShell cmdlets in SharePoint 2013


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


Thursday, October 16, 2014

Fix "We can't connect to the specified SharePoint site" in SharePoint 2013 - OneDrive for Business Error

In our SharePoint 2013 setup, few users reported they are facing issues while trying to setup sync from SharePoint document library.
"Microsoft OneDrive for Business Error - We cant connect to the specified SharePoint site..."
We can't connect to the specified SharePoint site

Root Cause: We found this issue occurs mostly with Non-Internet Explorer browsers! E.g. from Firefox or from Google Chrome! While trying to setup sync, user are prompted for credentials. If user makes a typo in user name/password/domain, OneDrive Sync client caches it and the credentials get saved in Windows credential store

Solution: 
  • Go to Control Panel >> User Accounts >> Pick your user name >> Manage Saved Credentials >> Delete if any! 
  • Add Site to Trusted Sites Zone in Internet Explorer.
  • Restart the Microsoft OneDrive for business Sync client (Exit the OneDrive client from notification area!) You can also try reinstalling the updated client from: http://support.microsoft.com/kb/2903984
  • Make sure, user's permission level consists of "Use Client Integration Feature" permission!


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


How to Sync SharePoint 2013 Document Library with Local Folder

In SharePoint Server 2013, users can perform two way sync between files stored in SharePoint document libraries and their local machine. The OneDrive for Business sync client performs the synchronization of files between document libraries and the user's local disk, So that users can take their files offline from SharePoint, work on them while offline, and then synchronize them with their document library when they reconnect to SharePoint Server 2013.

SharePoint 2013 sync requirements
You must have the Microsoft OneDrive for Business sync client (formerly SkyDrive Pro) installed in your machine for the sync functionality to work. If its not already installed, download and install it from: http://support.microsoft.com/kb/2903984, otherwise, SharePoint 2013 sync does not work!
sharepoint 2013 sync client
Sync functionality doesn't need any additional permission for one way sync. even the least permission level: "View only" would do!

How to sync SharePoint 2013 Library with Local Folder:
Follow these steps to sync any SharePoint library with local folder of your workstation
  • Navigate to your SharePoint library or page where library is placed.
  • Click on "Sync" icon from the top right section of the page. 
    sharepoint 2013 foundation sync
  • This brings a window for the first time sync setup. Click on "Sync Now" button.
     sharepoint 2013 desktop sync
  • Depending up the size of your library, sync setup may take a while to complete.
    sharepoint 2013 sync library to computer
  • Once completed, you may click on "Show my files…" to open synched files in the windows explorer.
     sharepoint 2013 sync documents
  • This enable offline sync! You may now open or edit files from your windows explorer. 
    sharepoint 2013 sync document library
SharePoint 2013 sync button not working?
Nothing happens when you click on "Sync" button in SharePoint 2013? Well, verify SharePoint 2013 sync button requirement: OneDrive sync client is installed in your machine! Try re-installing the client again.

How do I disable sync button in SharePoint 2013
Sure, you can turn-off sync button by disabling "Search and Offline Availability" option either at site level or library level. Find more to remove sync button at: How to Disable Sync button in SharePoint 2013

SharePoint 2013 sync button missing?
It could be sync turned off based on "Search and Offline Availability" choice at document library or site level.
  • Check Sync is enabled at Site level: Go to Site settings >> Click on "Search and Offline Availability" on Search group >> choose "Allow items from this site to be downloaded to offline clients" option to "Yes" on "Offline Client Availability" >> Click on "OK" to save your changes.
  • Check Sync feature at Library level: Navigate to your document library >> Go to Library Settings >> Advanced Settings >> Scroll down and choose "Allow items from this document library to be downloaded to offline clients?"to "Yes" on "Offline Client Availability" section.
Checkout-Checkin and OneDrive:
As the SharePoint - OneDrive sync is two way - files will be automatically synched if they are changed in either of the place. But if you checkout files in SharePoint site, it stops any other users from editing files in SharePoint until its checked-in back by the checked-out user! While it allows other users to edit files from their local OneDrive,  it doesn’t allow them to sync checked out files from OneDrive files to SharePoint until its checked-in back in SharePoint site! If they try to sync while the file is in checked-out state in SharePoint, OneDrive sync client gives an Sync issue error message!
 
SharePoint 2013 sync options:
The sync client provides options to setup new sync, trigger on-demand sync and to remove syncing a folder. You can access it from notification area. 
sharepoint 2013 sync library to computer
Stop syncing a folder in SharePoint 2013 
E.g. to remove remove sync folder, just right click on the OneDrive sync client and choose "Stop syncing a folder", Choose your source folder in the list and confirm stop syncing.
sharepoint 2013 sync stop syncing a folder
Warning: Do not delete a folder directly from your sync location - That will also delete the folder from SharePoint site!


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


Wednesday, October 15, 2014

Find and Replace URL Links from Hyperlink Columns in SharePoint

Requirement:
We had a SharePoint portal site called "Crescent Portal" with URL: http://portal.crescent.com. After migrating from SharePoint 2010 to SharePoint 2013, we made a decision to replace both site name and URL as "Crescent Intranet" with URL "http://intranet.crescent.com".

We understand there are plenty of lists and libraries hard-coded with the old site URL in its Hyperlink columns. Now, we got to find and replace those old links from all SharePoint lists and libraries.

PowerShell script to find and replace links in Hyperlink columns of SharePoint:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

Function Replace-LinkFields($WebURL, $OldLinkURL, $OldLinkTitle, $NewLinkURL, $NewLinkTitle)
{
    #Get the Web
    $Web = Get-SPWeb $WebURL

    #Get all lists - Exclude System lists
    $ListCollection = $web.lists | Where-Object  { ($_.hidden -eq $false) -and ($_.IsSiteAssetsLibrary -eq $false) -and ($_.Author.LoginName -ne "SHAREPOINT\system") }
 
    #Iterate through each list
    foreach ($List in $ListCollection)
    {
        #find all HyperLink fields in list
        $HyperlinkFields = @()
        foreach ($field in $list.Fields) 
        {
            if ($field.TypeAsString -eq "URL") 
            {
                $HyperlinkFields = $HyperlinkFields + $field.Title      
            }
        }    
        write-host "Processing list at: $($web.url)/$($list.RootFolder.Url)"

        #Process all hyperlink fields found
        
        #Proceed with next list if Hyperlink field is not found in the list
        if($HyperlinkFields.Count -eq 0) { continue }

        foreach ($Item in $List.Items) 
        {
            #Iterate through HyperLink fields
            foreach ($field in $HyperlinkFields) 
            {
                #Get field value
                $FieldValue = $item[$field]
                #Skip nulls
                if($FieldValue -ne $null) 
                { 
                    # Check for OldLinkURL or OldLinkTitle
                    if( ($FieldValue.contains($OldLinkURL)) -or ($FieldValue.contains($OldLinkTitle)) )
                    {             
                        #Replace the OLD URL with New URL
                        $Item[$field] = ($item[$field] -Replace $OldLinkURL,$NewLinkURL) 
                        #Replace OLD link title with new link title
                        $Item[$field] = ($item[$field] -Replace $OldLinkTitle,$NewLinkTitle) 

                        $Item.update()
                        Write-host "Found and replaced a old link item at: $($web.Url)/$($list.RootFolder.Url) - Item id: $($item.id)"      
                    }
                }
            }
        }
    }   
}

#Call the function to Replace Links in lists
Replace-LinkFields "http://Intranet.crescent.com/" "http://portal.crescent.com" "Crescent Portal" "http://intranet.crescent.com" "Crescent Intranet"
This script scans all lists and libraries of the given site and replaces old links. You can change the logic to process all sites in the web application to replace the old links across your web application.

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


Copy-SPSite - Clone SharePoint Site Collection using PowerShell

Copy-SPSite is a new feature introduced in SharePoint 2013, allows us to copy an existing site collection in to a new site collection. Copy-SPSite cmdlet clones/duplicates existing site collection into new one. Optionally, You can specify "Destination Database" parameter to copy the site collection into new database.

Copy-SPSite Example:
Syntax: 
Copy-SPSite {Source-Site-Collection-URL} [-DestinationDatabase {Destination-Database-Name}] -TargetUrl {Target-Site-Collection-URL}
Example:
Copy-SPSite http://intranet.crescent.com/sites/sales -TargetUrl http://intranet.crescent.com/sites/sales2 -DestinationDatabase SP13_Intranet_ContentDB005
This gets you a duplicate of a site collection on a fresh new URL!  

Using Copy-SPSite cmdlet to rename existing site collection:
To rename site collections, we used to follow backup-delete-restore process as in my another article: Rename site collection in SharePoint 2010 using PowerShell. Of course, there is a risk involved as you delete site collections - There are chances to loose data. Fortunately, SharePoint 2013 came with new functionality "Copy-SPSite". As the name suggest, Its used to make a copy of SharePoint site under a new name (URL) without any risk of losing data!

Tips: Want to copy SharePoint site to another server? Use Backup-SPSite and Restore-SPSite cmdlets to copy site between farms!

Copy SharePoint site to another web application
While its simple and straight forward to copy site to different site collections, I had few glitches while copy SharePoint site to another web application. Copy SharePoint site to another web application using Copy-SPSite doesn't work!
Copy-SPSite : The site collection being moved and the destination content database must be within the same Web application.
copy-spsite different web application
Solution: Use Backup-SPSite and Restore-SPSite cmdlets!


Copying Host Named Site Collections
I tried copy a SharePoint site to another on path-based site collections, It went through well. But when I tried copying a host-named site collection, ended up with an error!
Copy-SPSite -Identity 'http://sales.crescent.com' -TargetUrl 'http://sales2.crescent.com' -HostHeaderWebApplication 'http://hosting.com'
and got this error:
Copy-SPSite : Another site already exists at http://sales.crescent.com/. Delete this site before attempting to create a new site with the same URL, choose a new URL, or create a new inclusion at the path you originally specified.
copy-spsite site already exists
Workaround: Remove site url and then run copy site!
Remove-SPSiteURL -URL http://your-hnsc-site-url
You can't copy a site collection in SharePoint 2007/SharePoint 2010/SharePoint 2013 within the same content database!


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


Tuesday, October 14, 2014

This view cannot be displayed because the number of lookup and workflow status columns it contains exceeds the threshold (8) enforced by the administrator.

"This view cannot be displayed because the number of lookup and workflow status columns it contains exceeds the threshold (8) enforced by the administrator."
This view cannot be displayed because the number of lookup and workflow status columns it contains exceeds the threshold (8) enforced by the administrator.
Usually, You'll get this error message when your List view has many Lookup fields. Threshold feature is introduced in SharePoint 2010 to avoid performance hits in SharePoint Server. So, the simplest solution would be limit the number of lookup/workflow fields in SharePoint list view.

Please not, Not just "Lookup" fields are counted for threshold!  If you have below columns in the view, they are also counted:
  • Managed Metadata columns
  • People/Group Columns (including: Created by, Modified by)
  • Workflow Status column
How to Increase List view Threshold value in SharePoint 2013:
In case you want to increase this limit, follow these steps:
  • Go to your SharePoint 2010/SharePoint 2013 Central Admin site
  • Click on Application Management >> Manage web applications
  • Select your target web application >> Click on "General settings >> Resource throttling" from the ribbon.
  • In the Resource throttling page, You can increase the List View Lookup Threshold from the default value to whatever you need.
Increase Threshold values in SharePoint 2013
Warning: You may burden your SharePoint server by increasing these default threshold values as it increases CPU, Memory loads on the server. So, be careful!


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


Saturday, October 11, 2014

Check if SharePoint Site Collection, Site, List, Document, Column Exists in PowerShell

Here is my nifty PowerShell scripts to check if the given Site collection, Site, List, Document (File) and column objects exists in SharePoint. You can utilize these helper functions wherever required.

PowerShell to check if Site Collection Exists:
Here is my custom function and function usage with PowerShell to check if site collection exists.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Custom Function to Check if Site Collection Exists in Given URL
Function Check-SiteExists($SiteURL)
{
    return (Get-SPSite $SiteURL -ErrorAction SilentlyContinue) -ne $null     
}

#Variable for Site collection
$SiteURL= "http://demo.crescent.com/sites/operations" 

#Call the function to check site exists
if(Check-SiteExists($SiteURL))
 {
    write-host "Yes, Given Site Collection do Exists!" 
    #Proceed with your script
 }
Alternatively,
$SiteURL = "http://portal.crescent.com/"
 
try{ 
    $Site=Get-SPSite $SiteURL -ErrorAction SilentlyContinue
   }
catch{ 
    write-host Site Collection with URL:$SiteURL Does not Exists!
    return
 }  


PowerShell Script in to check if  SharePoint site exists in given URL:
#Custom Function to Check Site(Web) Exists or Not
Function Check-WebExists($WebURL)
{
    return (Get-SPWeb $WebURL -ErrorAction SilentlyContinue) -ne $null     
}
SharePoint PowerShell to Check If List Exists:
#Function to Check if List Exists 
Function Check-ListExists()
{
   Param( [Parameter(Mandatory=$true)] [string]$SiteURL, [Parameter(Mandatory=$true)] [string]$ListName ) 

   Return  (Get-SPWeb $SiteURL).lists.TryGetList($ListName) -ne $null
}

#Variable for Site collection
$varSiteURL= "http://intranet.crescent.com/sites/Sales"
$varListName = "Invoice"

#Call the function to check list exists
if(Check-ListExists -SiteURL $varSiteURL -ListName $varListName)
 {
    write-host "Yes, Given List do Exists!" 
    #Proceed with your script
 } 

Check if Site Column already exists using PowerShell
Lets check if site column exists using PowerShell:
#Function to Check if File Exists 
Function Check-SiteColumnExists()
{
   Param( [Parameter(Mandatory=$true)] [string]$SiteURL, [Parameter(Mandatory=$true)] [string]$ColumnName ) 

   Return  (Get-SPWeb $SiteURL).Fields.ContainsField($ColumnName) 
}

#Variable for Site collection
$varSiteURL= "http://intranet.crescent.com"
$varColumnName = "Department"

#Call the function to check list exists
if(Check-SiteColumnExists -SiteURL $varSiteURL -ColumnName $varColumnName)
 {
    write-host "Yes, Given Site Column do Exists!" 
    #Proceed with your script
 }

SharePoint PowerShell check document exists
and finally, lets check file exists in given location:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Function to Check if File Exists 
Function Check-FileExists()
{
   Param( [Parameter(Mandatory=$true)] [string]$SiteURL, [Parameter(Mandatory=$true)] [string]$FileURL ) 

   Return  (Get-SPWeb $SiteURL).GetFile($FileURL).Exists
}

#Variable for Site collection
$varSiteURL= "http://intranet.crescent.com"
$varFileURL = "http://intranet.crescent.com/Sales/Invoices/Inv-5060203.docx"

#Call the function to check list exists
if(Check-FileExists -SiteURL $varSiteURL -FileURL $varFileURL)
 {
    write-host "Yes, Given File do Exists!" 
    #Proceed with your script
 } 


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


Saturday, October 4, 2014

Fix "This page can't be displayed" "Internet Explorer Cannot Display This Page" Errors when Creating Web Application in SharePoint 2013

Web application creation process through SharePoint 2013 central administration site stopped in middle with error messages "This page can't be displayed", Internet Explorer Cannot Display This Page"!. However, I noticed that the IIS Web Sites, Application Pools, content database are created! But There is no content inside the virutual directory in IIS. I couldn't manage the web application throgh Central admin UI - So, the web application is in unsupported state.

Internet Explorer 11 error message:
This page can't be displayed error on sharepoint 2013 web application creation
Internet Explorer 10 and below:
Internet explorer cannot display the webpage error on sharepoint 2010 web application creation

Root cause:
Usually occurs when your SharePoint server's configuration is low and its performing poor! You may be running the SharePoint server with below recommended hardware (CPU, Memory, Disk space).

Solution:
To resolve the issue do the following: Increase the "Shutdown Time Limit" value of Central Administration's Application Pool in IIS! Here is how:
  • Login to your SharePoint server which hosts Central Administration
  • Open IIS manager >> Expand the server name and click on Application Pools.
  • Locate the SharePoint Central Administration v4 application pool. Right click on it and choose Advanced Settings.
  • In the Process Model section, set the Shutdown Time Limit to a greater value. E.g 900.
  • Restart IIS.
In some cases, you may have to increase: Ping Maximum Response Time and Startup Time Limit properties too. 

Deleted the corrupted Web Application, Application Pool from IIS before tried creating a new web application, Now, I'm able to create Web Applications without any issues! Microsoft KB addressing this issue: http://support.microsoft.com/kb/2543306

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


Fix The website cannot display the page - HTTP 500 Internal Server Error in SharePoint

Problem: 
When I open SharePoint 2013 Central Administration site, it returned an error message: HTTP 500 Internal Server Error: The website cannot display the page error message!
Fix HTTP 500 Internal Server Error in SharePoint
Troubleshooting:
  • Update passwords on IIS Application Pool identities. Make sure they are not stopped or Offline. Update the identity password for "SecurityTokenServiceApplicationPool " application pool and start it.
  • In most of the cases, Its due to web.config issues! Restore the web.config file from backups or Create a dummy web app, copy-paste the web.config file from it.
  • If your SharePoint Farm account password is changed/expired, Update it with: stsadm -o updatefarmcredentials -userlogin "domain\username" -password "password"
  • Make sure IIS Web sites are running. SharePoint Timer service is running. SQL Server instance is running in Database server.
  • If you are experiencing this issue with SharePoint 2010 Central Administration site, try re-provision it:  How to Re-Provision SharePoint Central Admin Site . Try Running the SharePoint Configuration wizard again - don't disconnect.
  • It could be due to SQL Server issues! Check the database server connectivity issues. 
  • Try Re-register Asp.net framework by running : C:\Windows\Microsoft.NET\Framework\<<.NET VERSION >>  aspnet_regiis.exe –iru
  • Make sure your SharePoint setup account is added under Administrator group.
  • Do a simple IIS Reset! 


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


Wednesday, October 1, 2014

SharePoint Error - Cannot complete this action. Please try again

Problem:
Users get "Error - Cannot complete this action. Please try again" error when trying to delete documents from Context menu (But file gets deleted!). While deleting documents from SharePoint 2013 ribbon button "delete document" works without any issues, choosing "Delete" from document's context menu gives this error.
Also, While trying to create a new View or Modify view: when you hit save button, you get: https://your-sharepoint-site.com/_vti_bin/owssvr.dll?CS=65001 - in the URL with blank page.

Troubleshooting:
Tried bypassing the load balancer by logging into individual WFEs and verified that the above errors are not happening in both the scenarios.

Temporary Fix: Disable "Minimal Download Strategy" feature from site settings >> Manage site features page. 
Permanent fix:
Compared response headers from SharePoint WFEs and from Load balancers using fiddler - Found load balancer response missing the response header "Accept-Encoding" field!

Update: You can find the more info on this issue here: https://finarne.wordpress.com/2014/12/10/sharepoint-2013-error-after-creating-a-view/

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