Thursday, December 31, 2015

Add Lookup Field to SharePoint List using PowerShell

PowerShell script to add lookup field to SharePoint list:

Scenario: You have a parent list called "Parent Projects" and child list "Project Milestones". The "Parent Project Name" field in child list is being looked up from the parent list's "Project Name" field.
sharepoint powershell add lookup column to list

PowerShell to Add Lookup Field to SharePoint List:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

#configuration parameters
$WebURL="https://portal.crescent/Projects/"
$ParentListName="Parent Projects"
$ChildListName="Project Milestones"

$ParentLookupColumnName="Project Name"
$ChildLookupColumnName="Parent Project Name"

#Get the Parent and Child Lists
$Web = Get-SPWeb $WebURL
$ParentList = $web.Lists[$ParentListName]
$ChildList = $web.Lists[$ChildListName]

#Check if Field exists already
if(!$childList.Fields.ContainsField($ChildLookupColumnName))
{
    #sharepoint powershell - create lookup field
    $ChildLookupColumn = $ChildList.Fields.AddLookup($ChildLookupColumnName,$ParentList.id,$False)
    $ChildLookupColumn = $ChildList.Fields[$ChildLookupColumnName]

    #Setup lookup Field property
    $ChildLookupColumn.LookupField = $ParentList.Fields[$ParentLookupColumnName]
    #$ChildLookupColumn.AllowMultipleValues=$true
    $ChildLookupColumn.update()
    write-host "Lookup field added successfully!" -f green
}
else
{
    write-host "Field Exists already!" -f red
}
That's all! We've created lookup column using PowerShell in SharePoint list.

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


Wednesday, December 30, 2015

Add Single line of text / Multiple lines of text Fields to SharePoint List using PowerShell

How to programmatically Add a Single Line of Text field or Multiple Lines of text fields in SharePoint using PowerShell:
#configuration parameters
$WebURL="https://portal.crescent.com/"
$ListName="Service Requests"

#Get site and List objects
$web = Get-SPWeb $WebURL
$List = $web.Lists.TryGetList($ListName)

#Check if List Exists
if($List)
{
    #Setup Field Properties
    $FieldName = "Overall Progress"
    $FieldType = [Microsoft.SharePoint.SPFieldType]::Text
    #For Multiple Lines of Text field, use:
    $FieldType = microsoft.sharepoint.SPFieldType]::Note
    $IsRequired = $False

    #Add the Field
    $NewField=$List.Fields.Add($FieldName,$FieldType,$IsRequired)
}
else
{
    write-host "List not found!"
}

PowerShell Scripts to add Single line of text to SharePoint List:
Lets make it a reusable function.
#Function to Add a Single Line of Text
Function Add-SPSingleLineOfTextField([Microsoft.SharePoint.SPList]$List, [string]$DisplayName, [string]$Name, [string]$Required)
{
    if(!$List.Fields.ContainsField($DisplayName))
    {
        $FieldXML = "<Field Type='Text' DisplayName='"+ $DisplayName +"' Required='"+ $Required +"' MaxLength='255' Name='"+ $Name +"' />" 
        $NewField=$List.Fields.AddFieldAsXml($FieldXML,$True,[Microsoft.SharePoint.SPAddFieldOptions]::AddFieldToDefaultView)
        write-host "New Field Added!" -f Green
    }
    else
    {
        write-host "Field exists already!" -f RED
    }        
}
PowerShell to add Multiple lines of text field to SharePoint List
#Function to Add Multiple Lines of Text
Function Add-SPMultipleLinesOfTextField([Microsoft.SharePoint.SPList]$List, [string]$DisplayName, [string]$Name, [string]$Required, [string]$NumLines, [string]$RichText, [string]$RichTextMode)
{
    if(!$List.Fields.ContainsField($DisplayName))
    {
        #Frame Field XML
        $FieldXML = "<Field Type='Note' DisplayName='"+ $DisplayName +"' Name='"+ $Name +"' Required='"+ $Required +"' NumLines='"+ $NumLines +"' RichText='" + $RichText +"' RichTextMode='"+ $RichTextMode +"' Sortable='FALSE'/>"
        #Add Field
        $NewField=$List.Fields.AddFieldAsXml($FieldXML,$True,[Microsoft.SharePoint.SPAddFieldOptions]::AddFieldToDefaultView)
        write-host "New Multiple Linex of Text Field Added!" -f Green
    }
    else
    {
        write-host "Field exists already!" -f RED
    }        
}

Now, We can call the function to add single line of text:
#configuration parameters
$WebURL="https://portal.crescent.com/"
$ListName="Service Requests"

#Get site and List objects
$web = Get-SPWeb $WebURL
$List = $web.Lists.TryGetList($ListName)

#Check if List Exists
if($List)
{
    #Call the function to add single line of Text
    Add-SPSingleLineOfTextField $List "Overall Progress" "Progress" $False
}
else
{
    write-host "List not found!"
}

Lets call the function to add Multiple lines of text field:
#configuration parameters
$WebURL="https://portal.crescent.com/"
$ListName="Service Requests"

#Get site and List objects
$web = Get-SPWeb $WebURL
$List = $web.Lists.TryGetList($ListName)

#Check if List Exists
if($List)
{
    #Add Plain Text
    #Add-SPMultipleLinesOfTextField $List "Stage Comments" "comments" $False 6 $False "Compatible"
    
    #Add Rich Text
    Add-SPMultipleLinesOfTextField $List "Stage Comments" "comments" "FALSE" 6 "TRUE" "Compatible"
    
    #Add Enhanced Rich Text
    #Add-SPMultipleLinesOfTextField $List "Stage Comments" "comments" "FALSE" "6" "TRUE" "FullHtml"
}
else
{
    write-host "List not found!"
}


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


Find Orphan User E-mails in List Items using PowerShell

Requirement: Our customized application for sending newsletters organizational wide, keeps its list of users to send e-mail in a SharePoint list called "Subscriptions". Users are configured in a people picker field of the list. Now, when someone leaves the organization, their account become orphan and their E-mails also goes invalid.

So prior processing the E-mails column, we had to scan the people picker column in the list for orphaned user Emails.

PowerShell script to scan for orphaned Users from their Emails:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
Import-Module ActiveDirectory
 
$Web= Get-SPWeb "https://portal.crescent.com/News/"
$List = $Web.Lists["Subscriptions"]
$FieldName="Members"

foreach($item in $List.Items)
{
  if($Item[$FieldName] -ne $null)
  {
   #Get People picker field values collection
   $UserCollection = New-Object Microsoft.Sharepoint.SPFieldUserValueCollection($Web,$Item[$FieldName].ToString())
         
        #Get each User from the Person or Group field
        foreach($UserObj in $UserCollection)
        {
            #Try to get the user from AD from Email 
            $ADUser= Get-ADUser -Filter {mail -eq $UserObj.User.Email}
          
            #check if user email doesn't exist in AD
            if($ADUser -eq $null)
             {
                "https://portal.crescent.com/News/Pages/ViewUser.aspx?UserId=$($Item['ID'])" + $UserObj.User.LoginName + $UserObj.User.Email
             }
        }
    }
}


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


Add Column to View in SharePoint using PowerShell

How to add a column to SharePoint list view using PowerShell?

PowerShell Script to add a field to View:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#configuration parameters
$WebURL="https://portal.crescent.com/projects"
$ListName="Project Milestones"
$ViewName="All Items"
$FieldInternalName="ProjectDescription"

Function Add-FieldToView([Microsoft.SharePoint.SPList]$List, [String]$ViewName, [string]$FieldInternalName)
{
    #Get the view
    $View = $List.Views[$ViewName]
    #To Get the Default View: List.DefaultView
    
    if($view -eq $Null) {write-host "View doesn't exists!" -f Red; return}
    
    #Check if view has the specific field already!
    if(!$view.ViewFields.ToStringCollection().Contains($FieldInternalName))
    {
        $View.ViewFields.Add($FieldInternalName)
        #To Delete a field from view: $View.ViewFields.delete($FieldInternalName)
        $View.Update()
        write-host "Field added to View!" -f Green
    }
    else
    {
        write-host "Field Already Exists in the view!" -f Red
    }
}

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

#If List Exists
if ($List )
{
    #Call the function
    Add-FieldToView $List $ViewName $FieldInternalName
} 



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


Tuesday, December 29, 2015

Monitor SharePoint Services (Such as Timer Service) - Send Alert Email When They Goes Down!

In continuation to my post Monitor SharePoint App Pools using PowerShell Script ,  If certain Services on SharePoint server goes down, that could cause outages or service interruptions to your SharePoint environment! Although monitoring solutions such as SCOM can monitor services, they can't start the service automatically - when stopped. So, lets address this issue with the help of PowerShell! Here is my nifty PowerShell script to start required services when stopped and send alert emails .

This script not only scans services availability, but also:
  • detects services status if its not in started state
  • Automatically starts the service if its in stopped state
  • Sends alert Email to SharePoint Admin team (or whoever configured!)
PowerShell script to Monitor Services and Send Email notification:
Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue

#Configuration variables
$EmailFrom = "ServiceMonitor@crescent.com"
$EmailTo =  "SPAdmin@crescent.com" # Use commas for multiple addresses
$EmailSubject = "Service(s) went down in SharePoint Server"

#Services to Monitor
$ServicesToMonitor =  "IISADMIN", "SPTimerV4", "SPAdminV4", "SPTraceV4" , "SPUserCodeV4" , "SPWriterV4" , "OSearch14" , "W3SVC"

#Get Outgoing Email Server of the SharePoint Farm
$SMTP= (Get-SPWebApplication -IncludeCentralAdministration | Where { $_.IsAdministrationWebApplication } ) | %{$_.outboundmailserviceinstance.server.address}

#Check the status of each service
Foreach($ServiceName in $ServicesToMonitor)
{
 #Get the service
 $Service = Get-Service -Name $ServiceName
 
 #Check the Service status
 if ($Service.Status -ne "Running")
 {
  Write-Host $Service.DisplayName Found Not running!
  
  Try
  {
     #Set the Error Action
     $ErrorActionPreference = "Stop"
   #Try to start the service
   Start-Service $ServiceName
  }
  catch
  {
    Write-Host "Attempt to start service failed. Find the Error Message below:" -ForegroundColor Red
    Write-Host $_.Exception.Message -ForegroundColor Red
  }
  finally
  {
    #Reset the Error Action to Default
    $ErrorActionPreference = "Continue"
  }

  #Send out the Alert E-mail 
                $EmailBody = "Hi SharePoint Team, `n `n The Service: $($Service.DisplayName) was found in stopped state!. `n`nWe tried Re-starting it... Current State of the Service: $($Service.Status). `n`nPlease take necessary actions if its not started! `n `nThanks, `nSharePoint Monitoring Script."
  Send-MailMessage -From $EmailFrom -To $EmailTo -Subject $EmailSubject -Body $EmailBody -SmtpServer $SMTP -usessl
 }
}
How to Monitor services on each server of the SharePoint Farm?
Just add parameter "-ComputerName $Server.Address" to "Get-Service" and "Start-Service" cmdlets.
So, the code goes like:
#Get all SharePoint Servers
$ServersColl = Get-SPServer | where { $_.role -ne "Invalid"}

Foreach($Server in $ServersColl)
{
 #Wrap the above code
} 

Schedule this PowerShell script in Windows Task scheduler in any Application server (or any other server will do!) to periodically scan App Pool status, Say once per 5 Min! run interval can be adjusted based on your application priority. Here is my another post on Scheduling PowerShell scripts using Windows Task scheduler: Create a Scheduled Task for PowerShell Script with Windows Task Scheduler


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


Sunday, December 27, 2015

PowerShell to Update Multi-valued Peole Picker Field with New Users

Requirement: Update existing People Picker field value using PowerShell in SharePoint.

PowerShell script to Add an new user to existing People Picker field:
We have a field called "Team Members" in Projects list and wanted to add new member(s) to it for a particular list item.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
 
#Configuration parameters
$SiteURL = "http://portal.crescent.com/projects/"
$ListName = "Projects"                
$FieldName= "ProjectTeamMembers"
$UserToAdd="Crescent\Faris"
$ItemID=431

#Get site and List objects
$web = Get-SPWeb $SiteURL
$List = $web.Lists.TryGetList($ListName)

if($List -ne $null)
    {           
        #Get the Item
        $Item = $List.GetItembyID($ItemID)
        
        #Get Existing field value
        $MultiUserCollection = [Microsoft.SharePoint.SPFieldUserValueCollection]$item[$FieldName]
        
        #Prepre the user to add
        $User = $Web.EnsureUser($UserToAdd)
        $NewUser = new-object Microsoft.SharePoint.SPFieldUserValue($Web, $User.ID, $User.LoginName)
        
        #Update Multivalued people Picker field 
        $MultiUserCollection.Add($NewUser)
        $item[$FieldName] = $MultiUserCollection
        $item.update()       
    }
write-host "New User Added and Existing People Picker field value updated!"     
powershell to update people picker in sharepoint

How to Set the People Picker Field using PowerShell:
The above script updates existing people picker field value with new users, this one sets people picker field without updating existing values in it.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
 
#parameters
$SiteURL = "http://portal.crescent.com/projectpipeline/"
$ListName = "Projects"                
$FieldName= "ProjectMembers"
$TeamMembers=@("Crescent\Markb", "Crescent\Andrew")

#Get site and List objects
$web = Get-SPWeb $SiteURL
$List = $web.Lists.TryGetList($ListName)

    #Get the Item
    $Item = $List.GetItembyID(1)
    Write-Host "Processing: "$item["ProjectName"]
    
    #Object Array for People picker value
    $TeamMembersCollection = new-object Microsoft.SharePoint.SPFieldUserValueCollection
    
  #Add Each Team member to the array 
  foreach ($TeamMember in $TeamMembers)
  {      
 #Prepre the user to Add
 $User = $Web.EnsureUser($TeamMember)

 #Add new user to the collection
 $NewUser = new-object Microsoft.SharePoint.SPFieldUserValue($Web, $User.ID,$User.Name)
 $TeamMembersCollection.Add($NewUser)
   }
 #Update the field value
 $item[$FieldName] = $TeamMembersCollection
 $item.update()
 
write-host "Team Member Field updated!"


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


Saturday, December 26, 2015

Break Permission Inheritance and Add-Remove Users to SharePoint List using PowerShell

By default SharePoint Lists and Libraries are inheriting permissions from its parent site when created. There are times where you may want to implements unique permissions on a SharePoint list level. Say for e.g. if there are users who should access only a specific list in a SharePoint site but not any other object. So, to setup a unique permission on SharePoint site, list, library, folder, or item we should break the permission inheritance first. Just follow these steps:
  • Navigate to your target SharePoint List or Library
  • Click on List Settings >> and then Permissions for this list.
  • From the ribbon, Click on "Stop Inhering Permissions" icon as in the below image
    sharepoint 2013 powershell break permission inheritance
  • Remove the Users or Groups who does need to have access to this list.
  • Grant permissions to additional users and groups who needs to have access to this list. 
Make sure you have broken the permission inheritance before adding or removing users to SharePoint list. Otherwise, you'll get "This operation is not allowed on an object that inherits permissions" Exception!

SharePoint 2013 - PowerShell to break permission inheritance:
To break permission inheritance on a SharePoint site or list, use this PowerShell script.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Parameters
$WebURL="http://intranet.crescent.com"
$ListName="Contacts"
$CopyParentPermissions = $True

#Get the List
$Web = Get-SPWeb $WebURL
$List = $web.Lists.TryGetList($ListName)

If ($List -ne $null)
{
    if ($List.HasUniqueRoleAssignments -eq $False)
    {
        $List.BreakRoleInheritance($CopyParentPermissions)
        Write-host "Stopped Inheriting Permissions from the parent." -f Green
    }
    else
    {
        write-host "List is already using Unique Permissions!" -f Red
    }
}
To Remove all permissions already inherited to the list, Set the variable $CopyParentPermissions to $False.

Add permission to SharePoint list using PowerShell:
Once the permissions are broken from its parent, we can add or remove users to the list using PowerShell. Use this PowerShell in SharePoint to add permission to a list.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Parameters
$WebURL="http://intranet.crescent.com"
$ListName="Contacts"

#Get the List
$Web = Get-SPWeb $WebURL
$List = $web.Lists.TryGetList($ListName)

If ($List -ne $null)
{
    #Grant contribute Permission to a User account
    $UserAccount="Crescent\Omar"
    $User = $web.EnsureUser($UserAccount)
    $RoleDefinition = $Web.RoleDefinitions["Contribute"]
    $RoleAssignment = New-Object Microsoft.SharePoint.SPRoleAssignment($User)
    $RoleAssignment.RoleDefinitionBindings.Add($RoleDefinition)
    $List.RoleAssignments.Add($RoleAssignment)
    $List.Update()
    Write-host "Permissions Granted to User Account: $UserAccount" -f Green     

    #Grant Read access to the Members SharePoint Group
    $GroupName="Crescent Intranet Members"
    $Group = $Web.SiteGroups[$GroupName]
    $RoleDefinition = $Web.RoleDefinitions["Read"]
    $RoleAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($Group)
    $RoleAssignment.RoleDefinitionBindings.Add($RoleDefinition);  
    $List.RoleAssignments.Add($RoleAssignment)  
    $List.Update() 
    Write-host "Permissions Granted to SharePoint Group: $GroupName" -f Green
} 

How about Removing permissions from SharePoint List using PowerShell:
Make sure you already broke the permission inheritance prior running this script.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Parameters
$WebURL="http://intranet.crescent.com"
$ListName="Contacts"

#Get the List
$Web = Get-SPWeb $WebURL
$List = $web.Lists.TryGetList($ListName)

If ($List -ne $null)
{
    #Remove User Permissions from the List
    $UserAccount="Crescent\Omar"
    $User = $web.EnsureUser($UserAccount)
    $List.RoleAssignments.Remove($User)
    $List.Update()
    Write-host "Permissions Removed from the User Account: $UserAccount" -f Green     

    #Revoke permission from a SharePoint Group
    $GroupName="Crescent Intranet Members"
    $Group = $Web.SiteGroups[$GroupName]
    $List.RoleAssignments.Remove($Group)  
    $List.Update() 
    Write-host "Permissions Revoked from SharePoint Group: $GroupName" -f Green
}

PowerShell to Remove all Permissions from a List:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Parameters
$WebURL="http://intranet.crescent.com"
$ListName="Contacts"

#Get the List
$Web = Get-SPWeb $WebURL
$List = $web.Lists.TryGetList($ListName)

If ($List -ne $null)
{
    #Get All permissions applied to List
    $RoleAssignmentCount = $List.RoleAssignments.Count

    #Remove All Permissions from the List
    For ($i= $RoleAssignmentCount-1; $i –ge 0; $i--)
    {
        Write-host "Removing Permission from:"$List.RoleAssignments[$i].Member.name
        $List.RoleAssignments.Remove($i)
    }
}


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


Friday, December 25, 2015

Export SharePoint 2013 Search Crawl History to CSV using PowerShell

Requirement: Extract crawl history of SharePoint 2013 search service application to a CSV file.
sharepoint 2013 search crawl history to csv

PowerShell to Extract Last 10 Crawl Log History to CSV file:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Parameters
$ContentSourceName = "Local SharePoint sites"
$ResultsCount = 10

#Get Search Service application and Content Source
$SearchServiceApplication = Get-SPEnterpriseSearchServiceApplication
$ContentSource = Get-SPEnterpriseSearchCrawlContentSource -SearchApplication $searchServiceApplication | ? { $_.Name -eq $contentSourceName }

#Get Crawl History
$CrawlLog = new-object Microsoft.Office.Server.Search.Administration.CrawlLog($searchServiceApplication)
$CrawlHistory = $CrawlLog.GetCrawlHistory($ResultsCount, $ContentSource.Id)

#Export the Crawl History to CSV
$CrawlHistory | Export-CSV "C:\CrawlHistory.csv" -NoTypeInformation


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


Tuesday, December 22, 2015

Update User Profile Properties in SharePoint using PowerShell

SharePoint User Profile properties are usually imported from Active Directory to provide information about SharePoint users. At times, we may have to update SharePoint user profiles manually. My scenario is to update user profile pictures from a SharePoint library. Here is my PowerShell script:

PowerShell Script to update User Profile Property:
#Configuration Variables
$MySiteURL = "https://Mysite.Crescent.com"
$UserLogin="Crescent\Salaudeen"

#Get User Profile Objects
$ServiceContext  = Get-SPServiceContext -site $MySiteURL
$UserProfileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext)

#Check if user Exists
if ($UserProfileManager.UserExists($UserLogin)) 
{
    #Get the User Profile
    $UserProfile = $UserProfileManager.GetUserProfile($UserLogin)

    #Update user profile picture Property
    $userProfile["PictureURL"].Value = "https://intranet.Crescent.com/UserProfileImages/Salaudeen.jpg"
    $userProfile.Commit()  
    write-host "User Picture Updated Successfully!" -f Green
}
else
{
    write-host "$($UserLogin) Not Found!" -f Red
}  
Make sure to remove mapping between SharePoint user profile property and Active Directory under User profile service application's "Manage User Properties" page. If there is a mapping defined, when next time user profile sync runs, your updates will be overwritten!
sharepoint 2010 update user profile properties powershell

Once updated, Run incremental/full search crawl for the updates to reflect in SharePoint search!

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


Saturday, December 19, 2015

Get-Set Person or Group (People Picker) Field Value using PowerShell in SharePoint

Here is my collection of PowerShell scripts to work with People picker field values:

Read People Picker Field Value using PowerShell:
PowerShell script to get value of Person or Group field.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Variables
$SiteURL = "http://portal.crescent.com/sites/Sales"
$ListName = "Tasks"                
$FieldName="Assigned To"
 
#Get site and List objects
$web = Get-SPWeb $SiteURL
$list= $web.lists[$listName]

#Iterate through each row in the list
foreach ($Item in $list.Items)
{
    #Get the People picker field value
    $AssignedTo = New-Object Microsoft.Sharepoint.SPFieldUserValue($Web,$Item[$FieldName])

    #Get the Login Name of the user
    Write-host $AssignedTo.User.LoginName
    #Get the Email
    Write-host $AssignedTo.User.Email
}

Get Multi-valued People Picker Field Value (if Allow multiple selections enabled!) using PowerShell:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Variables
$SiteURL = "http://portal.crescent.com/sites/Sales"
$ListName = "Tasks"                
$FieldName="Assigned To"
 
#Get site and List objects
$web = Get-SPWeb $SiteURL
$list= $web.lists[$listName]

#Iterate through each row in the list
foreach ($Item in $list.Items)
{
    if($item[$FieldName])
    {
        #Get People picker field values collection
        $UserCollection = New-Object Microsoft.Sharepoint.SPFieldUserValueCollection($Web,$item[$FieldName].ToString())
        Write-host Item ID: $item["ID"]
        
        #Get each User from the Person or Group field
        foreach($User in $UserCollection)
        {
             #Get the Display Name of the user
             Write-host $User.LookupValue 
             #Get the Login Name (Account ID)
             Write-host $User.User
             #Get the E-mail
             Write-host $User.User.Email             
        }
    }
}

PowerShell script to Update Person or Group Field:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Variables
$SiteURL = "http://portal.crescent.com/sites/Sales"
$ListName = "Tasks"                
$FieldName="Assigned To"
 
#Get site and List objects
$web = Get-SPWeb $SiteURL
$list= $web.lists[$listName]

#Get the List Item to update
$ListItem  = $List.GetItemByID(2)

#User Account to set
$UserAccount="Crescent\Salaudeen"
#To Add new List Item, use $Item = $List.AddItem()
$User = Get-SPUser -Identity $UserAccount -Web $web
$ListItem[$FieldName] = $User
$ListItem.Update()

Update Multiple Values People Picker Field using PowerShell script
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Variables
$SiteURL = "http://portal.crescent.com/sites/Sales"
$ListName = "Tasks"                
$FieldName="Assigned To"
 
#Get site and List objects
$web = Get-SPWeb $SiteURL
$list= $web.lists[$listName]

#Get the List Item to update
$ListItem  = $List.GetItemByID(2)

#User Account to set
$UserAccounts="Crescent\Salaudeen; Crescent\Ravi"
$UserAccountsColl = $UserAccounts -split ';'

$UserCollection = new-object Microsoft.SharePoint.SPFieldUserValueCollection
foreach($UserAccount in $UserAccountsColl)
{
    #Get the User
    $User=$web.EnsureUser($UserAccount)
    
    #Add to collection
    $UserFieldValue = new-object Microsoft.SharePoint.SPFieldUserValue($Web, $User.ID, $User.LoginName)
    $UserCollection.Add($UserFieldValue)
}

#update the Multiple value Person or Group field
$ListItem[$FieldName] = $UserCollection
$ListItem.Update()


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


Thursday, December 17, 2015

The Managed Metadata Service or Connection is currently not available. The Application Pool or Managed Metadata Web Service may not have been started. Please Contact your Administrator.

Error: The Managed Metadata Service or Connection is currently not  available. The Application Pool or Managed Metadata Web Service may not have been started.  Please Contact your Administrator.
The Managed Metadata Service or Connection is currently not available.
 Steps to troubleshoot:
  • Check Managed Metadata Service is Running from SharePoint Central Administration site >> Manage services on server, Click on "Start" link next to "Managed metadata service"
  • Start MMS Service application pool from IIS 
  • Check IUSR is added in Anonymous Authentication in IIS: Open IIS, Click on your Server Name in left pane. Now open Authentication widget from the middle pane, Right Click on Anonymous Authentication and select Edit, Click on Specific User radio button and click on Set Button. Type IUSR in user name field and then click on OK.
  • Check the permissions on Managed Metadata Service Application to your Web application's app pool account: Go to SharePoint Central Administration >> Application Management  >> Service Applications >> Highlight Managed Metadata Service  >> Click on Permissions button from the ribbon >> Add the application pool account of your web application and provide at least "Read Access to Term Store"
  • Managed Metadata Service is associated with your web application?
    Go to Central Administration >> Application Management >> Configure service application associations >> Select your web application >> Check the Application Proxy Group and make sure that the Managed Metadata Service is listed there. 
  • Recreate MMS Service application with an Existing database: Here is how: Delete the existing MMS service application without deleting the MMS database, Create a new MMS service application, Go to the properties of the new Managed Metadata service application, point to the original database 
  • Check the URL log. If you find something like "Requested registry access is not allowed" (Event viewer ID 6588), then its a problem of Application pool Service account gets access denied. Use: http://technet.microsoft.com/en-us/library/ee513047(v=office.14).aspx to resolve. 
  • Last but not least, Perform IISReset!


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


Monday, December 14, 2015

Get/Set Managed Metadata Column Values using PowerShell

Here is my nifty collection of PowerShell scripts to read and update Managed Metadata field values in SharePoint:
update managed metadata column using powershell


Read Managed Metadata column Value:
PowerShell to get managed metadata field value.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

$WebURL="https://portal.crescent.com/"
$ListName="Deals"
$FieldName="Region"
$ItemID=1

#Get Objects 
$Web = Get-SPWeb $WebURL     
$List= $Web.Lists[$listName]
$Item = $List.GetItembyID($ItemID)

#Get MMS column Value
[Microsoft.SharePoint.Taxonomy.TaxonomyFieldValue]$MMSFieldValue = $item[$FieldName] 

write-host $MMSFieldValue.Label

Get Multiple Value MMS field values using PowerShell:
When "Allow Multiple Values" Selected, here is how we can retrieve the value of it:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

$WebURL="https://portal.crescent.com/"
$ListName="Deals"
$FieldName="Region"
$ItemID=2

#Get Objects 
$Web = Get-SPWeb $WebURL     
$List= $Web.Lists[$listName]
$Item = $List.GetItembyID($ItemID)

#get managed metadata field value powershell
[Microsoft.SharePoint.Taxonomy.TaxonomyFieldValueCollection]$MMSFieldValueColl = $item[$FieldName] 

#Concatenate each term in the value collection
$MMSFieldTerms=""
Foreach ($MMSFieldValue in $MMSFieldValueColl)
{
    if($MMSFieldValue.label -ne $null)
    {
        $MMSFieldTerms+=$MMSFieldValue.label+"; "
    }
}

write-host $MMSFieldTerms                   

Update Managed Metadata Column Value using PowerShell:
Here is how to update managed metadata column with PowerShell.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

#Variables
$WebURL="https://portal.crescent.com"
$ListName="Deals"
$FieldName="Region"
$ItemID=1

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

#Get the Term from Term store
$TaxonomySession = Get-SPTaxonomySession -Site $web.Site
$TermStore = $TaxonomySession.TermStores["Managed Metadata Service"]
$TermGroup = $TermStore.Groups["Knowledge Portal"]
$TermSet = $TermGroup.TermSets["Regions"]
$Term = $Termset.Terms["America"]

#You can also get the term directly as: $Term = "15;#America|1c58d657-9bd1-4bff-b1b0-74e52eb717dd"
#Use SharePoint Manager

#Get the List and List Item
$List= $Web.Lists[$listName]
$Item = $List.GetItembyID($ItemID)

#set managed metadata field value powershell
$MMSField = [Microsoft.SharePoint.Taxonomy.TaxonomyField]$Item.Fields[$FieldName]
$MMSField.setFieldValue($Item,$Term)
$Item.Update()

Write-host "Managed Metadata Field value updated!"

Update Managed Metadata Column value for Multiple Values
SharePoint 2013 set managed metadata field using PowerShell
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

#Variables
$WebURL="https://portal.crescent.com"
$ListName="Deals"
$FieldName="Region"
$ItemID=2

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

#Get the Term store, Group and Term Set
$TaxonomySession = Get-SPTaxonomySession -Site $web.Site
$TermStore = $TaxonomySession.TermStores["Managed Metadata Service"]
$TermGroup = $TermStore.Groups["Knowledge Portal"]
$TermSet = $TermGroup.TermSets["Regions"]

#Get the List, List Item and Field
$List= $Web.Lists[$listName]
$Item = $List.GetItembyID($ItemID)
$MMSField = [Microsoft.SharePoint.Taxonomy.TaxonomyField]$Item.Fields[$FieldName]

#Actual Term Values to update
$TermValuesColl = @("Africa","Asia","Europe")

#Create a Term field value collection
$MMSValueCollection = new-object Microsoft.SharePoint.Taxonomy.TaxonomyFieldValueCollection($MMSField)
#Form each Term
foreach($TermValue in $TermValuesColl)
{
        $Term = $Termset.Terms[$TermValue]
        $MMSFieldValue = new-object Microsoft.SharePoint.Taxonomy.TaxonomyFieldValue($MMSField)
        $MMSFieldValue.TermGuid = $Term.Id
        $MMSFieldValue.Label = $Term.Name
        $MMSValueCollection.Add($MMSFieldValue)
 }

#updating sharepoint managed metadata columns with powershell: Multi-value MMS column
$MMSField.setFieldValue($Item,$MMSValueCollection)
$Item.Update()

Write-host "Managed Metadata Field value updated!"


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


Managed Metadata Columns Usage Report in SharePoint

Requirement: Find the usage of all Managed Metadata columns in SharePoint environment.

PowerShell script to find managed metadata column usage:
Here is the PowerShell script to find all managed metadata columns in SharePoint site collection.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

$SiteCollURL="https://portal.crescent.com"
$ReportOutput="c:\MMS-Columns.csv"

$WebsColl = (Get-SPSite $SiteCollURL).AllWebs

#Array to hold Results
$ResultColl = @()

#Loop through each site, List and Fields
Foreach($web in $WebsColl)
    { 
        Write-host "Scanning Web:"$Web.URL
        Foreach($list in $web.Lists)            
        {
            Foreach($Field in $list.Fields)            
            {            
                if($field.GetType().Name -eq "TaxonomyField")
                {
                    $Result = New-Object PSObject
                    $Result | Add-Member -type NoteProperty -name "List Name" -value $List.Title
                    $Result | Add-Member -type NoteProperty -name "URL" -value "$($List.ParentWeb.Url)/$($List.RootFolder.Url)"
                    $Result | Add-Member -type NoteProperty -name "Field Name" -value $Field.Title
       
                    $ResultColl += $Result
                }
            }
        }
    }
#Export Results to a CSV File
$ResultColl | Export-csv $ReportOutput -notypeinformation
Write-Host "Managed Metadata columns usage Report has been Generated!" -f Green 
This script scans each and every list of given site collection and generates report in CSV.

PowerShell script to find All Managed Metadata Terms in use:
Now the next part. Get what terms are being used in these MMS columns? Their values:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

$SiteCollURL="https://portal.crescent.com"
$ReportOutput="c:\MMS-Terms-Usage.csv"

$WebsColl = (Get-SPSite $SiteCollURL).AllWebs

#Array to hold Results
$ResultColl = @()

#Loop through each site, List and Fields
Foreach($web in $WebsColl)
    { 
        Write-host "Scanning Web:"$Web.URL
        Foreach($list in $web.Lists)            
        {
            #Get all Managed metadata fields
            Foreach($Field in $list.Fields | where {$_.GetType().Name -eq "TaxonomyField"})
                {
                    Foreach ($item in $list.Items)
                    {
                        #Get All values of MMS field
                        $MMSFieldValueColl = $item[$Field.Title] #-as [Microsoft.SharePoint.Taxonomy.TaxonomyFieldValueCollection]
                        
                        #concatenate each term in the collection
                        $MMSFieldTerms=""
                        Foreach ($MMSFieldValue in $MMSFieldValueColl)
                        {
                            if($MMSFieldValue.label -ne $null)
                            {
                                $MMSFieldTerms+=$MMSFieldValue.label+";"
                            }
                        }
                        
                        #Collect the result
                        if($MMSFieldTerms -ne "")
                        {
                            $Result = New-Object PSObject
                            $Result | Add-Member -type NoteProperty -name "MMs Column Name" -value $Field.Title
                            $Result | Add-Member -type NoteProperty -name "MMS Column Value" -value $MMSFieldTerms
                            #Get the URL of the Item
                            $ItemURL= $Item.ParentList.ParentWeb.Site.MakeFullUrl($item.ParentList.DefaultDisplayFormUrl)
                            $ItemURL=$ItemURL+"?ID=$($Item.ID)"
                            $Result | Add-Member -type NoteProperty -name "Item URL" -value $ItemURL
                            $Result | Add-Member -type NoteProperty -name "List Name" -value $List.Title
                            $Result | Add-Member -type NoteProperty -name "List URL" -value "$($List.ParentWeb.Url)/$($List.RootFolder.Url)"
       
                            $ResultColl += $Result
                        }
                    }
                }
        }
    }

#Export Results to a CSV File
$ResultColl | Export-csv $ReportOutput -notypeinformation
Write-Host "Managed Metadata columns usage Report has been Generated!" -f Green 


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


Sunday, December 13, 2015

How to Rename a List or Library in SharePoint

How to rename a SharePoint list? Well, renaming SharePoint list is fairly a simple two step process. Lets rename a document library in SharePoint 2013.
  • Browse to the document library >> Click on "Document Library Settings" under Library Settings group of the ribbon.
  • Click on "List Name, Description and Navigation" link under General Settings.
    rename sharepoint list name
  • Provide a new name to your list under "Name" field.
    how to rename sharepoint list
  • Click Save button to commit your changes. This renames list title in SharePoint.
Rename a SharePoint list URL: 
Renaming a list from SharePoint Web User Interface doesn't change the web address of the list. So, If you want to rename list URL, you can use SharePoint Designer, Explorer View or even PowerShell. Refer this post for further details: How to Rename SharePoint List URL using SharePoint Designer or PowerShell

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


Saturday, December 12, 2015

How to Add a Column to SharePoint List using PowerShell

Requirement:
Add columns to SharePoint list using PowerShell.

PowerShell Script to Add Columns to SharePoint List:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

Function Add-FieldToList($SiteURL,$ListName, $FieldName, $FieldType, $IsRequired)
{
    #Set the Error Action
    $ErrorActionPreference = "Stop"

    Try{
        #Get the List
        $List = (Get-SPWeb $SiteURL).Lists.TryGetList($ListName)
        
        #Check if List with specific name exists
        if($List -ne $null)
        {
            if(!$List.Fields.ContainsField($FieldName))
            {      
                #Add columns to the List 
                $List.Fields.Add($FieldName,$FieldType,$IsRequired)

                #Update the List
                $List.Update()

                #Update the default view to include the new column
                $View = $List.DefaultView # OR $List.Views["All Items"]
                $View.ViewFields.Add($FieldName)
                $View.Update()

                write-host "New Column '$FieldName' Added to the List!" -ForegroundColor Green
            }
            else
            {
                write-host "Field '$FieldName' Already Exists in the List" -ForegroundColor Red
            }
        }
        else
        {
            write-host "List '$ListName' doesn't exists!" -ForegroundColor Red
        }        
    }
     catch {
        Write-Host $_.Exception.Message -ForegroundColor Red
    }
    finally {
        #Reset the Error Action to Default
        $ErrorActionPreference = "Continue"
    }
}

#Parameters 
$SiteURL="http://intranet.crescent.com/"
$ListName = "Customer Directory"

#Add 'Name' - Single Line of Text Field
$FieldType = [Microsoft.SharePoint.SPFieldType]::Text
$FieldName="Name"
$IsRequired = $False
#Call the funtion to Add Field to List
Add-FieldToList $SiteURL $ListName $FieldName $FieldType $IsRequired

#Add Phone Number - Number Field
$FieldType = [Microsoft.SharePoint.SPFieldType]::Number
$FieldName="Phone Number"
$IsRequired = $False
#Call the funtion to Add Field to List
Add-FieldToList $SiteURL $ListName $FieldName $FieldType $IsRequired

#Date of Joing - Date Field
$FieldType = [Microsoft.SharePoint.SPFieldType]::DateTime
$FieldName="Date of Join"
$IsRequired = $False
#Call the funtion to Add Field to List
Add-FieldToList $SiteURL $ListName $FieldName $FieldType $IsRequired

You can also add fields to SharePoint list from their field schema. Here is how:
#Field Schemas
$NameFldSchema="<Field Type='Text' DisplayName='Name' Required='False' MaxLength='255' StaticName='Name' Name='Name' />"
$PhoneNoFldSchema="<Field Type='Number' DisplayName='Phone Number' Required='False' MaxLength='255' StaticName='PhoneNumber' Name='PhoneNumber' />"
$DOBFldSchema="<Field Type='DateTime' DisplayName='Date of Birth' Required='False' MaxLength='255' StaticName='DateOfBirth' Name='DateOfBirth' /> "
#For Field schemas, Refer: https://msdn.microsoft.com/en-us/library/office/aa979575(v=office.15).aspx
  
#Add Columns to the List
$List.Fields.AddFieldAsXml($NameFldSchema, $True,[Microsoft.SharePoint.SPAddFieldOptions]::AddFieldToDefaultView)

While the above script is fairly simple, to add other type of fields such as choice fields, lookups, etc.  refer below posts:


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


Monday, December 7, 2015

PowerShell to Add-Remove Fields to Content Type in SharePoint


If you have a requirement to add a field to content type or remove a field from existing content type, use this PowerShell script:

PowerShell script to Add a field to content type:
#Get Web Object
$web = Get-SPWeb "http://sharepoint.company.com"

#Get Content Type and Field
$ContentType=$web.ContentTypes["Content-Type-Name"]
$FieldToAdd=$web.Fields["Field-Name"]

#Add Field to Content type
$FieldLink=New-Object Microsoft.SharePoint.SPFieldLink($FieldToAdd)
$ContentType.FieldLinks.Add($FieldLink)
$ContentType.Update()

Lets add some error handling and make a reusable function to add site column to content type using PowerShell!

PowerShell to Add Site Column to Content type in SharePoint 
#Add SharePoint Snap-in
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

Function Add-FieldToContentType([Microsoft.SharePoint.SPWeb] $web, [string]$ContentTypeName, [string]$SiteColumnName)
{
 #Get Content Type and Field (Site column) objects 
 $ContentType=$web.ContentTypes[$ContentTypeName]
 #Check if the content type exists
 if($ContentType -ne $null)
 {
  #Check if the content type has the Field already
  if(!$ContentType.Fields.ContainsField($SiteColumnName))
  {
   #Check if the site column exists
   if($web.Fields.ContainsField($SiteColumnName))
   {
    $FieldToAdd=$web.Fields.GetField($SiteColumnName)#[$SiteColumnName]
    #Add Site column to the content type
    $FieldLink= New-Object Microsoft.SharePoint.SPFieldLink($FieldToAdd)
    $ContentType.FieldLinks.Add($FieldLink)
    $ContentType.Update($true)
    Write-Host "Site Column Field Added to the Content Type!" -ForegroundColor Green
   }
   else
   {
    Write-Host "Site Column Not Found!"  -ForegroundColor Red
   }
  }
  else
  {
   Write-Host "Field Exists Already!" -ForegroundColor Red
  }
 }
 else
 {
  Write-Host "Content type not found!" -ForegroundColor Red  
 }
}

Remove field from content type using PowerShell:
Here is how you can delete a site column from a content type programmatically
Function Remove-FieldFromContentType([Microsoft.SharePoint.SPWeb] $web, [string]$ContentTypeName, [string]$FieldNameToRemove)
{
 #Get Content Type and Field (Site column) objects 
 $ContentType=$web.ContentTypes[$ContentTypeName]
 #Check if the content type exists
 if($ContentType -ne $null)
 {
  #Check if the content type has the Field 
  if($ContentType.Fields.ContainsField($FieldNameToRemove))
  {
   #Rempve the Field from the content type
   $ContentType.FieldLinks.Delete($FieldNameToRemove)
   $ContentType.Update($true)
   Write-Host "Field removed from the Content Type!" -ForegroundColor Green
  }
  else
  {
   Write-Host "Field Doesn't Exists in the Content Type!" -ForegroundColor Red
  }
 }
 else
 {
  Write-Host "Content type not found!" -ForegroundColor Red  
 }
}

Now, Lets call the respective function to add or remove site column from content type using PowerShell:
#Configuration parameters
$WebURL="http://portal.crescent.com"
$ContentTypeName="CrescentInvestments"
$FieldName="FullName"  # Internal Name of the field

#Get the Web
$Web = Get-SPWeb -Identity $WebURL 

#Call the method to Add field to content type
Add-FieldToContentType $Web $ContentTypeName $FieldName
#Remove-FieldFromContentType $Web $ContentTypeName $FieldName
and the result goes here:
sharepoint 2013 powershell add field to content type

This Programmatically Updates the given Content Type. Here is my another post on PowerShell script to add site column to SharePoint: Create Site Column in SharePoint 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, December 6, 2015

Publish Content Type in SharePoint using PowerShell

To publish a Content Type from the content type hub in SharePoint, browse to your content type hub site collection, Navigate to:
  • Site Settings >> Site Content Types 
  • Select the content type that you would like to publish. 
    sharepoint content type hub publish
  • In content type settings page, Click on "Manage publishing for this content type" link.
  • From this page, you can Publish the content type.
    publish content type sharepoint 2013 powershell
How to push changes from Content Type Hub to Site Collections immediately:
Once the content type is published it may take up to an hour for the subscribing Site Collections to get it. This is internally done by a timer job called "Content Type Subscriber" that is scheduled to run once an hour. To publish a content type and want to see them in your site collections immediately on-demand, go to:
  • Central Administration >> Monitoring > Review Job Definitions 
  • Pick the "Content Type Subscriber" job of your target web application and click on Run now 
  • Now, your content type should be available for use in subscribed sites.
    sharepoint powershell publish content type
Publish content type SharePoint 2013 using PowerShell
If the content type publishing activity is too frequent and repeating, we can automate it with PowerShell. Lets publish the content type in SharePoint using PowerShell.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

# Function to publish the content types
Function Publish-ContentType($HubSiteURL, $ContentTypeName)
{
    #Get the objects from Parameters
    $HubSite = Get-SPSite $HubSiteURL
    $ContentType = $HubSite.RootWeb.ContentTypes | Where {$_.Name -eq $ContentTypeName}

    #Check if the content type exists
    if($ContentType -ne $null)
    {
        #Create a new content type publisher 
        $Publisher = New-Object Microsoft.SharePoint.Taxonomy.ContentTypeSync.ContentTypePublisher($HubSite)
    
        #Publish-Unpublish
        $Publisher.Publish($ContentType)

        Write-Host "Published Content Type $ContentTypeName" -foregroundcolor Green
    }
    else
    {
         Write-Host "Content Type $ContentTypeName Not Found!"  -ForegroundColor Red
    }
}

#Configuration Parameters
$HubSiteURL="http://intranet.crescent.com/CTypeHub"
$ContentTypeName="Sales Proposal v.1"

#call the function to publish content type
Publish-ContentType $HubSiteURL $ContentTypeName

How about Publishing all Content Types from a Content Type Group?
#Configuration Parameters
$HubSiteURL="http://intranet.crescent.com/CTypeHub"
$ContentTypeGroup="Crescent Templates"

#Get the content type hub
$HubSite = Get-SPSite $HubSiteURL

#Publish each content type from the group
$HubSite.RootWeb.ContentTypes | where { $_.Group -match $ContentTypeGroup } | ForEach-Object {
   Publish-ContentType $HubSiteURL $_.Name 
  }

To Trigger the Timer job using PowerShell:
$SubscriberWebAppURL="http://intranet.crescent.com/"

#Run the Content Type Subscriber timer job for a specific Web Application
$CTypeSubscriberTimerJob = Get-SPTimerJob "MetadataSubscriberTimerJob" -WebApplication $SubscriberWebAppURL
$CTypeSubscriberTimerJob.RunNow()


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


Friday, December 4, 2015

Create Content Type Hub in SharePoint using PowerShell

Content type hub in SharePoint is a central location to manage content types. Any web application subscribed to the content type hub can consume content types from this store. Creating content type hub in SharePoint using Central Administration web UI is explained in my another article: How to Create Content Type Hub in SharePoint 2013, Now lets create content type hub in SharePoint 2013 using PowerShell.

PowerShell script to create Content Type Hub in SharePoint:
Creating content type hub in SharePoint involves three steps:
  1. Create an explicit Managed path for content type hub (optional)
  2. Create a top level site collection for content type hub
  3. Activate content type hub syndication feature
Here is the Script:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Parameters
$WebAppURL="http://intranet.crescent.com"
$ManagedPath="CTypeHub"
$HubOwner="Crescent\SPAdmin"

$WebApp = Get-SPWebApplication $WebAppURL

###  Step 1: Create Managed Path ###
#Check if the managed path exist already
$ManagedPathExists = Get-SPManagedPath -WebApplication $WebAppURL -Identity $ManagedPath -ErrorAction SilentlyContinue
 
 if ($ManagedPathExists -eq $null)
 {
    #Go ahead and create the managed path
    $CTypeHubPath=New-SPManagedPath –RelativeURL $ManagedPath -WebApplication $WebAppURL -Explicit
    Write-host "Managed Path Created!" -f Green
 }
 else
 {
    Write-Host "Managed path $ManagedPath already exists!" -f Yellow
 }

###  Step 2: Create Site Collection for Content type hub ###
#Check if ContentType hub site already exists
$CTypeHubURL = $WebAppURL+"/"+$ManagedPath

$CTypeHubExists = Get-SPSite $CTypeHubURL -ErrorAction SilentlyContinue

if($CTypeHubExists -eq $null)
{
    #Create site collection
    $CTypeHub = New-SPSite -Url $CTypeHubURL -Template 'STS#0' -OwnerAlias $HubOwner -Name "Content Type hub" 
}
else
 {
    Write-Host "Content Type Hub Site $CTypeHubURL already exists!" -f Yellow
 }

###  Step 3: Activate Content Type hub feature  ###
#Check if ContentType hub feature is already enabled
$Feature = Get-SPFeature -site $CTypeHubURL –Identity "ContentTypeHub" -ErrorAction SilentlyContinue 

If($Feature -eq $null) 
{      
    #Activate feature
    Enable-SPFeature –Identity "ContentTypeHub" –url $CTypeHubURL -Force -ErrorAction SilentlyContinue 
    Write-Host "Activated Content Type hub feature" -F Green 
}
else
{
    write-host "Content Type Hub Feature already enabled!" -F Yellow
}
Don't forget to set the content type hub in Managed Metadata service application: Setting up Content Type Hub in Manage Metadata Service Application

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


Wednesday, December 2, 2015

Create Lookup Site Column from Subsite using PowerShell

Creating lookup field as site column was explained in my another post: Create a Cross-Site Lookup Site Column in SharePoint 2013. Now got a requirement to create a lookup site column from the subsite's list! Unfortunately, there is no UI to create a site column from subsite list values. Lookup site columns can be created only from the lists of the same site.

PowerShell comes to rescue! We can create a lookup site column referencing any site of the site collection using PowerShell! Here is the PowerShell script to create a lookup column from list on another site.

PowerShell script to create lookup site column from subsite's (or different site) list:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

#Where the Source List for Lookup Exists
$ParentWebURL="https://portal.crescent.com/sales/"
$ParentListName="Regions"
$ParentLookupColumnName="Region"

#Where the Lookup Site column Going to get created
$ChildWebURL="https://portal.crescent.com"
$ChildLookupColumnName="Sales Region"
 
#Get the Parent and Child Webs and List
$ParentWeb = Get-SPWeb $ParentWebURL
$ParentList = $ParentWeb.Lists[$ParentListName]
$ChildWeb = Get-SPWeb $ChildWebURL

#Check if Field exists already
if(!$ChildWeb.Fields.ContainsField($ChildLookupColumnName))
{
    #Add Lookup Field
    $ChildLookupColumn = $ChildWeb.Fields.AddLookup($ChildLookupColumnName,$ParentList.id,$False)
    $ChildLookupColumn = $ChildWeb.Fields[$ChildLookupColumnName]
 
    #Setup lookup Field property
    $ChildLookupColumn.LookupWebId = $ParentWeb.ID
    $ChildLookupColumn.LookupField = $ParentList.Fields[$ParentLookupColumnName].InternalName
    #$ChildLookupColumn.AllowMultipleValues=$true
    $ChildLookupColumn.update()
    write-host "Lookup field added successfully!" -f green
}
else
{
    write-host "Field Exists already!" -f red
} 
This PowerShell script creates SharePoint lookup column from list on another site! BTW, Site columns must be created on Root web, so that it can be consumed by any subsite underneath.

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


Tuesday, December 1, 2015

How to Create a Cross-Site Lookup Site Column in SharePoint 2013

Lookup columns are used to get its value from a field in an another list in SharePoint sites. Lookup fields also provides a relationship between lists/libraries. Is it possible to create a lookup column from list on another site? sure, use site columns, so that you can utilize SharePoint 2013 lookup column from an different site!

Site columns are available to its subsites, So create it in the Root site!

SharePoint Site column Hierarchy:

Create Cross-Site Lookup Site Column in SharePoint:
Why to create Lookup as Site column? Because, If its created as a site column, it can be used at any subsite under the site collection while the lookup source list is at the parent site (or root site)! In short, create your lookup site column at parent site, so that it can be used on any underlying subsites of the site collection!

Assuming, you have an existing list with all available lookup values in a "Single Line of Text" column, Here is how to create a cross site lookup site column in SharePoint 2013:
  1. Go to the root level site of your SharePoint site collection. Navigate to Settings >> Click on "Site Columns" link
    sharepoint cross site lookup column
  2. In Site columns page, Click on "Create" link
    sharepoint create lookup site column
  3. Provide Name, Column type, Group, Source List, Source Column values. Click on "OK" button once done.
    sharepoint lookup column from another site
  4. Navigate to your sub-site list >> Click on List settings >> Click on "Add from existing site columns" link
    cross site column lookup sharepoint 2013
  5. Choose the site column group in which you placed your site column, Select and Add the column, Click on "OK" button once done.
    sharepoint 2013 lookup column different site
  6. Now, In your sub-site list, You have the site column ready!
    sharepoint lookup column from list on another site


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


Monday, November 30, 2015

Remove Field from View using PowerShell in SharePoint

In SharePoint, If you want to remove field from view programmatically using PowerShell, Here you go:

SharePoint delete column from view using PowerShell:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

#Function: sharepoint powershell delete field from view
Function Remove-FieldFromView([Microsoft.SharePoint.SPList]$List, [String]$ViewName, [string]$FieldInternalName)
{
    #Get the view
 $View = $List.Views[$ViewName]
    #To Get the Default View: List.DefaultView
    
    if($view -eq $Null) {write-host "View doesn't exists!" -f Red; return}
    
    #Check if view has the specific field already!
    if($view.ViewFields.ToStringCollection().Contains($FieldInternalName))
    {
        #Remove field from view: 
        $View.ViewFields.delete($FieldInternalName)
     $View.Update()
     write-host "Field Removed from the View!" -f Green
    }
    else
    {
    write-host "Field Doesn't Exists in the view!" -f Red
    }
}

#configuration parameters
$WebURL="https://portal.crescent.com/projects/"
$ListName="Project Milestones"
$ViewName="All Items"
$FieldName="ProjectDescription"

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

#Call the function to remove column from view 
Remove-FieldFromView $List $ViewName $FieldName

This PowerShell script removes given field from the given view.

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


Create Content Type Hub in SharePoint 2013

What is Content Type Hub SharePoint 2013?
Content Type Hub is a centralized repository of SharePoint Content types where we can manage and publish content types. Any Web application that subscribed to this content type hub can consume content types from this store. Content type hub is associated with the help of Managed Metadata Service Application.

Why we need content type hub in SharePoint?
Well, content types are limited within site collection scope. When you have a requirement to consume content types beyond site collection boundary, or even between different SharePoint farms (E.g. Dev-UAT-Production) - Content type hub is the answer! Without content type hub, You'll end up creating same content type again and again on all of the site collections - I'm sure this situation is pretty common in your  organization.

How to configure content type hub SharePoint 2013?
Content Type Hub is actually a Site Collection. You can either create a dedicated web application and then a top level site collection in it or create a separate site collection in any existing web application. Technically, You can choose any existing site collection and make it as a content type hub, however, as a best practice, lets create a dedicated site collection explicitly for content type hub.
Content type should be created/modified on the content type hub site collection and published to push the changes to all subscribed sites!

Create a content type hub SharePoint 2013:
Creating a new Content Type Hub is really a simple process. As the best practice says: Use explicit site collection for content type hub, Lets create an explicit managed path for content type hub.
  • Go to SharePoint 2016 Central Administration site
  • Application Management >> Select the Web application from the list, Click on "Managed Path" button from the ribbon.
    setting up content type hub sharepoint 2013
  • Add a new path "CtypeHub", choose the Type as "Explicit Inclusion" and click on "Add Path" button.
    content type hub sharepoint 2013 web application
  • As stated already, you can just create a new site collection inside any existing web application. the above step is completely options. Alright, lets create a site collection on the managed path we created. Go to: Application Management >> Create site collections 
  • Select the web application , provide a Title for the content type hub site collection, select the Web site address as "CtypeHub" 
    create a content type hub sharepoint 2013
  • Scroll down and select Template as "Team Site", select Site Administrators,etc. and click on "OK" to create content type hub.
Enable "Content Type Syndicate Hub Feature" for Content type Hub site Collection
  • Go to: Site Settings >> Site Collection Features under Site Collection Administration section.
  • Find the Content Type Syndication Hub Feature and Click on Activate Button to use this site as a Content Type Hub.
    how to configure content type hub sharepoint 2013
 Now, we have the content type hub ready. The next step is to associate it with Managed Metadata Service Application

Connect content type hub with Manage Metadata Service Application:
Lets Set up content type hub in Managed metadata service in Manage Service Applications from Central Administration.
  • Go to Central Administration >> click the Application Management >> under Service Applications, Select Managed Metadata Service >> Click on Properties from the ribbon.
  • In Managed metadata service application properties, Enter your Content Type Hub site collection URL in Content Type. In my case its: http://intranet.crescent.com/ctypehub
    how to setup content type hub in sharepoint 2013
  • Go back to Service Applications page, Select the Managed Metadata Service Connection >> Click on Properties from the ribbon, and set "Consume content type from the content type gallery"
    sharepoint 2013 content type hub step by step
That's all! We have completed setting up content type hub SharePoint 2013. Now your Content Type Hub Site Collection is registered with Managed Metadata Service Application. Content Type hub is available to all Lists or Libraries in the farm. Web applications can subscribe to this hub and pull down the published content types.

Last but not least: If you want to change content type hub URL in SharePoint, use PowerShell: Change content type hub URL 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


Saturday, November 28, 2015

Cascading Dropdown in SharePoint List using Infopath Forms

What is Cascading drop downs? Well, Cascading drop downs are linked drop down controls where the content of the second drop down depends on the selection of the first one. E.g. When you Choose Country in the first drop down, the second drop down State is automatically filtered to the list of states actually in that county. Cascading drop downs are quite a common requirement and unfortunately, SharePoint doesn't support it Out of the box.

In this article, I'm documenting the implementation of cascading drop down functionality in SharePoint list forms using InfoPath forms step by step (at least for my own reference! even a simple mistake takes hours to resolve).

In short: You create a new data source to retrieve "Region" and "Country" columns from the Countries list and then filter the countries drop down to show only items matching with the "Region" selected in "Regions" drop down.

Cascading Drop down List Setup:
Here is my List setup:
  1. Regions - List of Regions - Parent List for Countries list's Region column.
  2. Countries -List of Countries with Region as lookup column from "Regions" list
  3. Projects List - List to capture project data, Where Region and Country columns are from above lists as lookup columns.

Step 1: Customize SharePoint List in InfoPath Designer

Open the Project SharePoint list in browser, Click on "Customized Form" button under List Tab. This opens your SharePoint list form in InfoPath Designer. Alternatively, You can open InfoPath Designer and Customize SharePoint List form. This establishes the data connections between SharePoint list and InfoPath.
infopath cascading dropdown from sharepoint list
BTW, To utilize InfoPath browser farms you need to have SharePoint Server Enterprise edition and "SharePoint Server Enterprise Site Collection features" feature activated at site collection level.

Step 2: Create New Data Connection:

Add new data connection in InfoPath to retrieve Country & its respective Region. 
  • In InfoPath Designer, Click on Data Tab, Click on Data Connections, Click on Add button
    infopath cascading drop down boxes
  • In Data Connection Wizard, Click on Receive data then on Next
    infopath cascading dropdown filter
  • Click on SharePoint Library or list and then on Next button
    sharepoint 2010 infopath forms cascading dropdown
  • Provide the URL of Countries List then on Next
    infopath cascading dropdowns in browser forms
  • Select the Countries list then on Next
    cascading dropdown in sharepoint 2010 infopath
  • Select the Country and Region fields, and click on Next
    cascading dropdown in sharepoint 2013 infopath
  • Provide a name to your data connection (say: Country) and click on Finish.
    sharepoint infopath cascading drop down lists

Step 3: Change the Data Source of the "Country" Drop down and Apply Filter:

Once we created the data source for Country,
  • Select the "Country" Drop Down in InfoPath form designer, Right Click and choose "Drop down List box Properties" to get the Control Properties window. 
  • In Data source dropdown, Select the new data source we created in Step 1 (In my case its: "Country"). Now, proceed to step.
    infopath cascading dropdown sharepoint list
Apply Filter to Country Drop down:
The Next step is to filter country values in the Country drop down based on the selected Region. 
  • In Entries section, click on the tree button. This brings Select Field or Group window.
    infopath 2010 cascading dropdown sharepoint list
  • Select the d:SharePointListItem_RW node under "DataFields" and click on Filter Data button.
  • In Filter Data window, click on Add button
  • In specify Filter Conditions, 
    • In the Country drop down, Add filter for Region. That is: Region from Countries data connection = Region from main data connection. since Region is a Lookup column – The matching rows will be retrieved. Here is how: In the first drop-down list choose "Region" field, Set the condition to: is equal to, in the next drop down choose: Select a field or group - This brings an another window to select the field.
    • Under "Fields" drop down, Change the drop down value from "Country(secondary)" to "Main".
    • Once you select "Main" in fields drop down, you'll get list of fields of the main data connection (In my case, its "Project:" list fields). Select the Region field from the list, and click on OK.
      Click on OK again to go back to the Country drop down properties window
Set Value and display Name Fields of Country Drop down:
Finally in the Country drop down properties, Set the Value and Display name fields to ID and Title respectively by selecting it through the tree button. This is because Country drop down is a lookup field and it stores lookup ID value internally. If you leave it as d:Title you will get an error when you try to save the list item.
sharepoint infopath cascading dropdown

Step 4: Add a Rule to "Regions" Drop down to Clear Countries Drop down on Re-selection:

This is important, because You'll have to clear the secondary cascading drop downs upon re-selection of primary drop down.
  • Select the Region Drop down in InfoPath designer, From the ribbon click on Add Rule, Select This Field Changes, Set a Field's value.
    infopath cascading dropdown from sharepoint list
  • Choose the field as "Country", leave the Value as blank and click OK.
    sharepoint 2010 infopath cascading dropdown
That's it! Now, from InfoPath Designer, Save and Publish the form!

There is a way to achieve cascading drop down functionality with SharePoint OOTB list forms and SPServices-Webservice-Javascript! Refer: Cascading Drop down In SharePoint Lists using jQuery

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


Friday, November 27, 2015

Create Word Automation Service Application using PowerShell in SharePoint 2016

The Word Automation Services Service Application provides developers a way to perform server-side conversion of documents that are supported by Microsoft Word (such as .doc, .docx, .rtf, etc) into other formats such as PDF,XPS, RTF, Docx,etc. In other words, Word Automation Services provides the "Save As" like functionality of the Microsoft Word client for SharePoint.

How to Create Word Automation Service Application using SharePoint 2016 Central Administration:
To create a Word Automation Service Application from SharePoint 2016 Central Administration site, Go to:
  • Application Management >> Manage Service Applications.
  • On the Service Applications tab, click New >> and then click Word Automation Services Application.
  • In the Create New Word Automation Services Application dialog box, Enter the Name, Application Pool, Select "Add to Default Proxy List" and click on next.
    sharepoint 2013 configure word automation service application
  • Enter the Database Server name and name of the database for word automation service application. Click Finish. 
    sharepoint 2016 create word automation service application powershell
  • Once created, The new instance of Word Automation Services appears in the list of service applications on the Service Applications tab.
PowerShell Script to Create Word Automation Service Application:
Use this PowerShell script to create word automation service application in SharePoint 2013/SharePoint 2016.
# Configuration Parameters
$InstanceName = "Word Automation Services"
$ServiceAppName = "Word Automation Service Application"
$AppPoolName = "Service Application App Pool"
$DBName = "SP16_Services_WordAutomation"

Write-Host "Starting the $InstanceName Instance..."
Get-SPServiceInstance | where-object {$_.TypeName -eq $InstanceName} | Start-SPServiceInstance

#There is no New-SPWordConversionServiceApplicationProxy, we can't therefore set it's name
#The -default parameter adds the automatically created proxy to the default proxy group
Write-Host "Creating $ServiceAppName Application & Proxy..."
$ServiceApp = New-SPWordConversionServiceApplication -Name $ServiceAppName -ApplicationPool $AppPoolName -DatabaseName $DBName -Default

Write-Host "Word Automation Service App Created!" 
There is no cmdlet for creating service application proxy for word automation service (such as: New-SPWordConversionServiceApplicationProxy. So the -Default switch in the above cmdlet adds the automatically created proxy to the default proxy group.

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


Thursday, November 26, 2015

How to Remove Content Database in SharePoint using PowerShell

SharePoint content databases are the most important artifacts in SharePoint platform as they hold majority of the data. However, at times we may have to delete the content database from SharePoint. Here is how you can utilize PowerShell to delete database:

SharePoint 2010: Remove content database using PowerShell
To delete content database from SharePoint, use: Remove-SPContentDatabase cmdlet, which removes the content database from SharePoint web application and deletes it from the SQL Server also.
Syntax:
Get-SPContentDatabase -Identity "ContentDB-Name" | Remove-SPContentDatabase

E.g. 
Get-SPContentDatabase -Identity "SP10_Intranet_Content02" | Remove-SPContentDatabase
sharepoint powershell delete content database
This deletes SharePoint Content database from SharePoint as well as from SQL Server permanently! As stated, use: Dismount-SPContentDatabase cmdlet if you want to remove the database from SharePoint alone!

Related Posts:


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


Sunday, November 22, 2015

Get/Set Hyperlink Field Values in SharePoint using PowerShell

Here is my PowerShell scripts to get and set hyperlink column values:

Get Hyperlink Field Value using PowerShell:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Variables
$SiteURL = "http://intranet.crescent.com/"
$ListName = "UserProfiles"
$FieldName="Picture"

#Get the Web, List Objects
$web = Get-SPWeb $SiteURL
$List = $Web.Lists.TryGetList($ListName)

If($list)
{
    foreach($Item in $List.Items)
    {
        #Get the Hyperlink column
        $Picture = New-Object Microsoft.SharePoint.SPFieldUrlValue($Item[$FieldName])
        #Get the URL of the Hyperlink
        $Picture.URL
        #Get the Decription - Title
        $Picture.Description
    }        
}
Update Hyperlink Field value using PowerShell:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Configuration Variables
$SiteURL = "http://intranet.crescent.com/"
$ListName = "UserProfiles"
$FieldName="Picture"

#Get the Web, List Objects
$web = Get-SPWeb $SiteURL
$List = $Web.Lists.TryGetList($ListName)

If($list)
{
    #Prepare the Hyperlink column
    $Picture = New-Object Microsoft.SharePoint.SPFieldURLValue
    $Picture.Description = "Profile Picture"
    $Picture.URL = "http://intranet.crescent.com/UserProfiles/Images/profile.jpg"
    
    #Add new List Item
    $Item = $List.AddItem()
    $Item[$FieldName] = $Picture
    $Item.Update()  
    
    Write-host "New Item Added Successfully!"
}


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