Subscribe: SharePoint SharePoint SharePoint

Tuesday, February 4, 2014

Check in and approve all publishing pages using PowerShell in SharePoint

We have a SharePoint 2013 farm setup for our company Intranet. There are huge number of sites in the intranet. Each site is maintained by a separate group. Now the people who maintain those sites are non-technical people.

Since all the sites are publishing sites, so the pages need to be published everytime they are edited. I have repeatedly sent mails to all groups stating that this procedure has to followed everytime they make changes.

But alas! , everyday my mailbox is clogged with requests reporting that "changes are not being reflected to site visitors". Instead of sending separate mails to each of them, i made a powershell script to publish all their pages together.

Note: The image is just for reference. Its not actual screenshot of the below code.

I actually used a timer service to run this script everyday at 5 AM. Finally after few days, i started getting very few requests. So thought of sharing the script:

 $listname = "Pages"   
 $url = "http://myWebApp/sites/mySite"  
    
 function approvePublishContent ($w, $listName) {  
  $list = $w.Lists |? {$_.Title -eq $listName}  
  foreach ($item in $list.Items)   
  {
   //Checking if item is locked
   if(($item -ne $null) -and ($item.LockId -ne $null)) {  
    $item.ReleaseLock($item.LockId)  
   }  
   if( $item.File -ne $null) { $itemFile = $list.GetItemById($item.ID).File }  
   else { $itemFile = $list.GetItemById($item.ID) }  
   
   //Checking in the item
   if( $itemFile.CheckOutStatus -ne "None" ) {   
    $itemFile.CheckIn("Automatic CheckIn. (SysAdmin)")  
    if( $item.File -ne $null) { $itemFile = $list.GetItemById($item.ID).File }  
    else { $itemFile = $list.GetItemById($item.ID) }  
   }  

   //Publishing the item
   if( $list.EnableVersioning -and $list.EnableMinorVersions) {   
    $itemFile.Publish("Automatic Publish. (SysAdmin)")  
    if( $item.File -ne $null) { $itemFile = $list.GetItemById($item.ID).File }  
    else { $itemFile = $list.GetItemById($item.ID) }  
   }  

   //Approving it in case approval is required
   if( $list.EnableModeration ) {   
    $itemFile.Approve("Automatic Approve. (SysAdmin)")   
   }  
  }  
 }  
 $site = Get-SPSite $url  
 foreach ( $web in $site.AllWebs )  
 {  
  approvePublishContent $web $listname  
 }  
 Write-Output "OK"  
   

Monday, February 3, 2014

Updating Web part properties using PowerShell in SharePoint

Web part properties define the structure as well as functionality of a web part. They are quite useful while configuring a web part. We have a huge list of web part properties which have been defined by microsoft. you can have a look over these properties from the link below:

SharePoint Web part properties

Now once i ran into a situation wherein i had to change the "ChromeType" property of a web part in the landing page of all the subsites as well as root site in my site collection. There were a total of 32 subsites. So in order to do this through User Interface would have required a considerable amount of time.
SharePoint 2010

So i created a powershell script to do so and voila! I was able to do so in a single shot.

Each web part page is associated with a "SPWebPartManager" class. This class in particular contains references to all the web parts on the page. So in order to access my web part i have to iterate through the "SPWebPartManager" class.

Here the web part name is "Relevant Articles" and the chrome property has to be set to "TitleAndBorder".
  
 //Get reference to the SPSite object
 $SPsite = Get-SPSite "http://mywebapp/sites/mySite"  
   
 //Iterate through all sub sites and root site  
 foreach($SPWeb in $SPsite.AllWebs){  
   
 //Get reference to the landing page. Since it is a publishing site so default.aspx is the landing page  
 $page = $SPWeb.GetFile("Pages/default.aspx")  
   
 //Checkout the page  
 $page.CheckOut()  
   
 //Get reference to the webpartmanager class  
 $webpartmanager = $SPWeb.GetLimitedWebPartManager("Pages/default.aspx",   
 [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)    
   
   
 //Iterate through webparts in webpartmanager class  
  for($i=0;$i -lt $webpartmanager.WebParts.Count;$i++)  {   
   
 //Check for the name of required web part   
  if($webpartmanager.WebParts[$i].title -eq "Relevant Articles")   
  {    
   
     //Get reference to the web part  
     $wp=$webpartmanager.WebParts[$i];  
       
     //Set the chrome property  
     $wp.ChromeType="TitleAndBorder";  
   
     //Save changes to webpartmanager. This step is necessary. Otherwise changes won't be reflected  
     $webpartmanager.SaveChanges($wp);  
       
     break;   
   
  }   
 }   
   
  //Check in and Publish the page  
  $page.CheckIn("Relevant Articles")  
  $page.Publish("Relevant Articles")  
   
  // Update the SPWeb object  
  $SPWeb.Update();   
    
  //Dispose SPWeb object  
  $SPWeb.Dispose();  
 }  

Sunday, February 2, 2014

New Delegate Controls in SharePoint 2013

Delegate Controls are very significant medium to make changes to master page without touching the code part. In SharePoint 2010, we had a lot of delegate controls. To name a few we had : AdditionalPageHead, SmallSearchInputBox etc.

Now in SharePoint 2013, three new delegate controls were introduced. These were actually based on the new master page structure in SP 2013. Since in SharePoint 2013 we have "suites" defined in layout i.e left suite bar and right suite bar, so the delegate controls are based on them.

They may be summarized as below:

  • PromotedActions
  • SuiteBarBrandingDelegate
  • SuiteLinksDelegate

  • PromotedActions delegate control is that part of header which contains links like "Share","Edit" etc. So we can use this delegate control to add our own controls to the header as shown below:

    SharePoint Delegate Controls
    And the code for user control is as simple as :

     <a title="Open Facebook" class="ms-promotedActionButton" style="display: inline-block;" href="http://www.facebook.com">  
     <span class="s4-clust ms-promotedActionButton-icon" style="width: 16px; height: 16px; overflow: hidden; display: inline-block; position: relative;">  
     <img style="position:absolute;" alt="facebook" src="/_layouts/15/images/MyDelegateControls/facebook.png"/>  
     </span>  
       <span class="ms-promotedActionButton-text">Post on Facebook</span>  
     </a>  
    

    SuitingBarBrandingDelegate  Delegate Control facilitates us to override the left-top corner text for the site. By default it is "SharePoint". So we can replace it with the title of our own site:

    SharePoint Delegate Controls


    User Control: (SuiteBarBrandingDelegateCustom ascx)
     <div class="ms-core-brandingText" id="SiteTitleControl" runat="server" />   
    
    Code behind: (SuiteBarBrandingDelegateCustom.ascx.cs)
     protected void Page_Load(object sender, EventArgs e)  
     {  
       SiteTitleControl.Controls.Add(new Literal  
       {  
         Text = string.Format("<a href='{0}'><img src='{1}' alt='{2}' /></a>", SPContext.Current.Site.Url,  
         "/_layouts/15/images/MyDelegateControls/sitelogo.png", SPContext.Current.Site.RootWeb.Title)  
       });  
     }  
    

    SuiteLinksDelegate delegate control allow us to add  links in right suite bar like "Newsfeed","Sites" etc. :

    SharePoint Delegate Controls


    User Control Code Behind:
     protected override void Render(HtmlTextWriter writer)  
       {  
         writer.RenderBeginTag(HtmlTextWriterTag.Style);  
         writer.Write(".ms-core-suiteLinkList {display: inline-block;}");  
         writer.RenderEndTag();  
         writer.AddAttribute(HtmlTextWriterAttribute.Class, "ms-core-suiteLinkList");  
         writer.RenderBeginTag(HtmlTextWriterTag.Ul);  
         RenderSuiteLink(writer, "http://www.myreports.com", "Report", "TimeManagement", false);  
          writer.RenderEndTag();  
         base.Render(writer);  
       }  
    

    Note : For all these delegate controls , you need to add a reference in Elements.xml file to specify the control id and control source properties:
     <?xml version="1.0" encoding="utf-8"?>  
     <Elements xmlns="http://schemas.microsoft.com/sharepoint/">  
      <Control ControlSrc="/_controltemplates/15/MyDelegateControls/UserControl.ascx"  
          Id="DelegateControlID" //ID of DelegateControl e.g. "SuiteLinksDelegate"  
          Sequence="1" />  
     </Elements>