Wednesday 18 February 2015

PowerShell to do restructuring of SharePoint content

You might have went through scenario where most SharePoint implementations have outgrown the original purpose for which they were designed at initials – what might was envisioned as a simple solution has now become a complex environment. This has resulted your complex environment - one that is constantly undergoing changes in content and usability. However, in spite of these changes, SharePoint continues to cater to the growing and varied needs of the organization. As a result, there is a continuous need for periodic restructuring of content and metadata.

In market you would find many 3rd party tool to done this job, but each of them will require license and this is what lenthy process to bring in operation. You have a great handy tool available to do this job, powerShell.

You can use the Export-SPWeb and Import-SPWeb cmdlets to move heavy subsites to new destination or can even restructure URL:

Import-SPWeb:
http://technet.microsoft.com/en-us/library/ff607613(v=office.14).aspx
Export-SPWeb:
http://technet.microsoft.com/en-us/library/ff607895(v=office.14).aspx

The general syntax of these commands are:

Export-SPWeb [-Identity] <url of the site to be exported> -Path <location and name of the file to be created after export> [-Force] [-IncludeUserSecurity] [-IncludeVersions <LastMajor | CurrentVersion | LastMajorAndMinor | All>] [-ItemUrl <Any specific item to export, like document library or list>]
Import-SPWeb [-Identity] <url of the site to be exported> -Path <location and name of the file to be imported from> [-Confirm] [-Force] [-IncludeUserSecurity] [-UpdateVersions <Append | Overwrite | Ignore>]
You can use the IncludeUserSecurity parameter to export the associated security with the site, library, or list which includes users in the site, authors of documents and lists, when the document or list was created and modified, etc... and the IncludeVersions parameter to specify which versions of the documents or list items you want to export, whether to export current versions, last major versions, last major or minor versions or all versions, etc.

  • If your SQL Server version supports database snapshot (Enterprise and Developer editions) , it is recommended to use UseSqlSnapshot parameter with Export-SPWeb command for a more consistent backup. 
  • Workflows are not included when we export/import contents of sites, libraries, or lists.
Valid migration scenarios when using the Publishing features are the following:
  • Export the site collection starting at the root site and then import it as the root site into a new site collection
  • Export subsites of the site collection and then import them as subsites into an existing site collection that has the Publishing features enabled
Some manual work may be required to ensure master pages and page layouts that are in use in the subsites are copied over to the new site collection.

If your environments have customizations, such as custom template you might receive error as below while import

[2/12/2014 3:14:51 PM]: Progress: Initializing Import.
[2/12/2014 3:15:08 PM]: FatalError: Could not find WebTemplate #10011 with LCID 1033. at Microsoft.SharePoint.Deployment.ImportRequirementsManager.VerifyWebTemplate(SPRequirementObject reqObj) at Microsoft.SharePoint.Deployment.ImportRequirementsManager.Validate(SPRequirementObject reqObj) at Microsoft.SharePoint.Deployment.ImportRequirementsManager.DeserializeAndValidate() at Microsoft.SharePoint.Deployment.SPImport.VerifyRequirements() at Microsoft.SharePoint.Deployment.SPImport.Run() [2/12/2014 3:15:14 PM]: Progress: Import Completed. [2/12/2014 3:15:14 PM]: Finish Time: 2/2/2014 3:15:14 PM. [2/12/2014 3:15:14 PM]: Completed with 0 warnings. [2/12/2014 3:15:14 PM]: Completed with 1 errors.

Use below script to check available webtemplates in the farm or in target farm if you moving to another farm.
get-spwebtemplate | select name,title,id

If any of the missing template(10011) does not exist in target farm, you will need to install those features in farm .

Change SharePoint Farm account

Change SharePoint Farm account
 
Use this powershell script if you would like to replace an existing managed account credential
Introduction
 
Use this powershell script if you would like to replace an existing managed account credential with new managed account. That applies also to the farm admin user. The PowerShell script will scan the following items and replace user account accordingly:
 
• 1- SharePoint Services
• 2- SharePoint Service Applications App Pools
• 3- SharePoint Web application App Pools
 
and there is an extra function added "UpdateFarmCredentials" to update the farm credentials if the need be.
 
I would recommend resetting the IIS after running this script.
 
How to use the script
 
You need to run this script in an elevated command prompt screen from one of the SharePoint servers of the targeted farm running with the farm admin account.
 
At the end of the file make sure you replace the following variables with your desired values:
• 1- $OldUser (The old managed account you want to replace)
• 2- $NewUser (The new managed account you want to register and use)
• 3- $NewUserPassword (The new managed account password)
 
Please note
 
• The script might throw some warnings when you try to use a local account in a farm deployment. You can ignore these warning however, you should know that it’s not recommended to use local accounts. You might also see some errors regarding deploying some of the changes to some of the Service applications. You can ignore these errors as well.
  • The script will register the new managed account for you if it’s not registered yet and will prompt you for the password to be stored in SharePoint.
• This script is written and test on SharePoint 2010 version only.
• Some users reported that the UPA stopped working after replacing the credentials.
 
Run this script at your own risk
 
 
 
 
function UpdateFarmCredentials($userName,$Password)
{
    #Prepare Stsadm to be used through powershell
    Set-Alias -Name stsadm -Value $env:CommonProgramFiles"\Microsoft Shared\Web Server Extensions\14\BIN\STSADM.EXE"
    $Command = "stsadm -o updatefarmcredentials -userlogin '$userName' -password '$Password'"
    trap{"Error updating farm credentials"}
    Invoke-Expression $Command
}
function Ensure-SPAccount($userName)
{
    #Add SharePoint Snap-in
    if((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
    {
        Add-PSSnapin Microsoft.SharePoint.PowerShell;
        Write-Host "SharePoint PowerShell Snap-In added";
    }
    if(Get-SPManagedAccount | Where-Object { $_.UserName -eq $userName }){
      # Managed Account Already exists
      Write-Host “Managed Account: $userName exists”
    } else {
      # Get User Credentials
      $credential = Get-Credential -Credential $userName
      # Create New Managed Account
      New-SPManagedAccount -Credential $credential
    }
}
function Get-SPServiceIdentity()
{
    #Add SharePoint Snap-in
    if((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
    {
        Add-PSSnapin Microsoft.SharePoint.PowerShell;
        Write-Host "SharePoint PowerShell Snap-In added";
    }
    foreach ($ser in Get-SPServiceInstance)
    {
        $T = $ser.GetType()
        if($T.BaseType.Name -like "SPWindowsServiceInstance")
            {
                Write-Host "Service= " $ser.TypeName ", Identity=" $ser.Service.ProcessIdentity.UserName
            }
    }
}
function Replace-SPServiceIdentity($FromUser,$ToUser)
{
    #Add SharePoint Snap-in
    if((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
    {
        Add-PSSnapin Microsoft.SharePoint.PowerShell;
        Write-Host "SharePoint PowerShell Snap-In added";
    }
    $fromUserLower = "$FromUser"
    $fromUserLower = $fromUserLower.ToLower().Trim()
   
    #Make sure Service account is added
    Ensure-SPAccount $ToUser
   
    foreach ($ser in Get-SPServiceInstance)
    {
        $T = $ser.GetType()
        if($T.BaseType.Name -like "SPWindowsServiceInstance" -and $ser.Service.ProcessIdentity.UserName -ne $null)
        {
            $UserName = $ser.Service.ProcessIdentity.UserName.ToLower()
            if($UserName -Like $fromUserLower)
            {
                Write-Host "Updating Service= " $ser.TypeName
                $ser.Service.ProcessIdentity.UserName = $ToUser
                $ser.Service.ProcessIdentity.Update()
                $ser.Service.ProcessIdentity.Deploy()
            }
           
        }
    }
}
function ReplaceServiceAppsApplicationPoolIdentity($FromUser,$ToUser)
{
    #Add SharePoint Snap-in
    if((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
    {
        Add-PSSnapin Microsoft.SharePoint.PowerShell;
        Write-Host "SharePoint PowerShell Snap-In added";
    }
   
    $fromUserLower = "$FromUser"
    $fromUserLower = $fromUserLower.ToLower().Trim()
   
    #Make sure Service account is added
    Ensure-SPAccount $ToUser
   
    #Replace service apps application pool identities
    foreach($appPool in Get-SPServiceApplicationPool)
    {
        if($appPool.ProcessAccountName.ToLower() -Like $fromUserLower)
        {
            Write-Host "Updating" $appPool.Name "..."
            Set-SPServiceApplicationPool  $appPool –Account $ToUser
        }
    }
   
}
function ReplaceWebAppsApplicationPoolIdentity($FromUser,$ToUser)
{
    #Add SharePoint Snap-in
    if((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
    {
        Add-PSSnapin Microsoft.SharePoint.PowerShell;
        Write-Host "SharePoint PowerShell Snap-In added";
    }
    
    $fromUserLower = "$FromUser"
    $fromUserLower = $fromUserLower.ToLower().Trim()
   
    #Make sure Service account is added
    Ensure-SPAccount $ToUser
   
    #Replace web apps application pool identities
    foreach($WebApp in Get-SPWebApplication)
    {
        $appPool = $WebApp.ApplicationPool
        if($appPool.ManagedAccount.UserName.ToLower() -Like $fromUserLower)
        {
            Write-Host "Updating '" $WebApp.Url "' web app applicaiton pool identity..."
            $id = Get-SPManagedAccount $ToUser
            $appPool.ManagedAccount = $id
            $appPool.Update()
        }
    }
   
}
 
 
$OldUser= "rk\spmanagedac1"
$NewUser = "rk\spmanagedac1"
$NewUserPassword = "password01"
#UpdateFarmCredentials $OldUser $NewUserPassword
Replace-SPServiceIdentity $OldUser $NewUser
ReplaceServiceAppsApplicationPoolIdentity $OldUser $NewUser
ReplaceWebAppsApplicationPoolIdentity $OldUser $NewUser