Wednesday, February 29, 2012

PowerShell script to add Publishing Pages

Following PowerShell script can be used to add pages to the pages Library. The page details are saved in an xml file. And also pagers are checked in and approve using the same script. 

PowerShell script:

void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
function New-SPPage{
[CmdletBinding()]
                Param(
                [Parameter(Mandatory=$true)]
                [string]$SiteUrl,   
                [Parameter(Mandatory=$false)]
                [switch]$CreateFromXml,
                [Parameter(Mandatory=$false)]
                [string]$XmlInput
    )
    # Create From Xml
    if ($CreateFromXml) {
        # Read in list of pages from XML
        [xml]$pagesXML = Get-Content $($XmlInput)
        if ($pagesXML -eq $null) { return } 

        # Get publishing web
        $siteUrl = $pagesXML.configuration.siteUrl
        $regionUrl =$pagesXML.configuration.regionUrl
        $site = New-Object Microsoft.SharePoint.SPSite($SiteUrl)
        $psite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($site)
        # Loop through each web node to extract filename
        $pagesXML.configuration.webs.web | ForEach-Object {
            $webUrl = [string]$_.GetAttribute("url")
            $fullUrl = $siteUrl + $regionUrl +$webUrl
            $sitecol = New-Object Microsoft.SharePoint.SPSite($fullUrl)
            $web = $sitecol.OpenWeb()
            $pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
            $pagesnode = $_.pages

            #loop through each page node to get the page properties
            $pagesnode.page | ForEach-Object {
                $PageTitle = [string]$_.pageTitle
                $PageUrl = [string]$_.pageUrl
                $PagePublishingPageImage =[string]$_.PublishingPageImage  
                $PublishingPageContent = [string]$_.PublishingPageContent
                $PublishingPageContent2 = [string]$_.PublishingPageContent2
                $PageLayoutCT = [string]$_.pageLayoutCT
                $PageLayoutName =[string]$_.pageLayoutName  
                $PageHeading = [string]$_.pageHeading
                $ctype = $psite.ContentTypes[$PageLayoutCT]
                $layout = $psite.GetPageLayouts($ctype, $true) | where{$_.name -eq  $PageLayoutName}              

                Write-Host "Creating $($PageTitle)"
                # Create blank page
                $pages = $pWeb.GetPublishingPages($pWeb)
                            $page = $pages.Add($PageUrl, $Layout)
                            #$newPage = $pWeb.AddPublishingPage($PageUrl,$PageLayout)
                $page.Update()
                # Update the filename to the one specified in the XML
                $item = $page.ListItem
                 $item["Title"] = $PageTitle;
                 $item["Page Image"] = $PagePublishingPageImage;
                 $item["Page Content"] = $PublishingPageContent;
                 $item["Page Content 2"] = $PublishingPageContent2
                 $item["Page Heading"] = $PageHeading;
                 $item.Update()
                # Check-in and publish pages
                CheckInPage -page $page -web $web
                # and approve pages
                ApprovePage -page $page
            }#End ForEach Pages
        $web.Dispose()
        $sitecol.Dispose()
        } #End ForEach Loop Web
        # Dispose of the web
        $site.Dispose()
    } #End CreateFromXml
} #End function 

function CheckInPage ($page, $web)
{
    #Check to ensure the page is checked out by you, and if so, check it in
    if ($page.ListItem.File.CheckedOutBy.UserLogin -eq $web.CurrentUser.UserLogin)
    {
        $page.CheckIn("Page checked in automatically by PowerShell script")
        write-host $page.Title"("$page.Name") has been checked in"
    }
    else
    {
        write-host $page.Title"("$page.Name") has not been checked in as it is currently checked out to"$page.ListItem.File.CheckedOutBy
    }
}

function ApprovePage ($page)
{
    if($page.ListItem.ListItems.List.EnableModeration)
    {
        #Check to ensure page requires approval, and if so, approve it
        if ($page.ListItem["Approval Status"] -eq 0)
        {
             write-host $page.Title"("$page.Name") is already approved"
        }
        else
        {
            $page.ListItem.File.Approve("Page approved automatically by PowerShell script")
            write-host $page.Title"("$page.Name") has been approved"
        }
    }
    else
    {
        write-host $page.Title"("$page.Name") does not require approval in this site"
    }
} 

Add-PSSnapin "Microsoft.SharePoint.PowerShell" -EA "SilentlyContinue" 
new-sppage -createfromxml -xmlinput "C:\Projects\BuildScripts\ArticlePages.xml" -siteurl <siteUrl>
Write-Host "Press any key to continue ..." 
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Add your <siteUrl> and the  correct path to the xml file
xml file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <siteUrl>http://<siteurl></siteUrl> 
  <webs>
    <web url="/Test">
      <pages>     
        <page>
          <pageTitle>Article 1</pageTitle>
          <pageUrl>pages/Article 1.aspx</pageUrl>
          <pageHeading>Our Employee Referral Program</pageHeading>
          <PublishingPageImage>&lt;img alt=&quot;HR News&quot; src=&quot;/_layouts/Images/ SampleImages/Sample.png&quot; style=&quot;BORDER: 0px solid; &quot;&gt;</PublishingPageImage>
          <PublishingPageContent>
                Mauris sem eros, pellentesque eu gravida a, congue quis ipsum. In at odio iaculis odio
          </PublishingPageContent>        
          <PublishingPageContent2>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec in felis elit. Etiam a ante a
          </PublishingPageContent2>
          <pageLayoutCT>News Article</pageLayoutCT>
          <pageLayoutName>TestPageLayout.aspx</pageLayoutName>
        </page>
        <page>              
          <pageTitle>Article 2</pageTitle>
          <pageUrl>pages/Article 2.aspx</pageUrl>
          <pageHeading>Article 2</pageHeading>
         <PublishingPageImage>
&lt;img alt=&quot;HR News&quot; src=&quot;/_layouts/Images /SampleImages/Sample.png&quot; style=&quot;BORDER: 0px solid; &quot;&gt;
         </PublishingPageImage>
          <PublishingPageContent>
                Nunc posuere lorem a turpis pellentesque pulvinar. In nec pretium neque.
          </PublishingPageContent>
         <PublishingPageContent2>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sit amet risus urna
          </PublishingPageContent2>
          <pageLayoutCT>News Article</pageLayoutCT>
          <pageLayoutName>TestPageLayout.aspx</pageLayoutName>
        </page>  
      </pages>
    </web>
  </webs>
</configuration>                 

Powershell Script to Customize Sharepoint default Left Navigation

We can use the following script to delete/add navigation urls to the sharepoint default left navigation. Following script deletes the existing navigation nodes and add according to the given structure in the xml file.

Powershell script:

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
function New-SPNavigation{
[CmdletBinding()]
                Param(   
                [Parameter(Mandatory=$false)]
                [switch]$CreateFromXml      
    )
# Create From Xml
if ($CreateFromXml) {
    #Get XML File
    $xmlFilePath = "C:\Projects\BuildScripts\LeftNavigation.xml"
    $xmlFile = [xml](Get-Content($xmlFilePath))
    Write-Host $xmlFile.Navigation.WebUrl

    #Get Web and Quick Launch objects
    $siteUr = $xmlFile.Navigation.WebUrl

    $site = New-Object Microsoft.SharePoint.SPSite($siteUr)
    $web = $site.OpenWeb()
    $currentLinks = @()
    $qlNav = $web.Navigation.QuickLaunch  

    #Clear Quick Launch links
    $qlNav | ForEach-Object {
        $currentLinks = $currentLinks + $_.Id     
    }  

    $currentLinks | ForEach-Object {
        $currentNode = $web.Navigation.GetNodeById($_)    
        write-host "Deleting" $currentNode.Title "and all child navigation links..."
        $qlLibraries = $currentNode.Children   
        $qlNav.Delete($currentNode)
    }

    #Create Quick Launch Links
    $xmlFile.Navigation.Headings.Heading | ForEach-Object {
        $headingNode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode($_.Title, $_.Url, $true)
        write-host "Creating Heading:" $_.Title
        $heading = $qlNav.AddAsLast($headingNode)
        $a=$_.NavLink.Count
        if($a -gt 0)
        {
            $_.NavLink | ForEach-Object {
                $linkNode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode($_.Title, $_.Url, $true)
                write-host "Creating Navigation Link:" $_.Title
                $link = $heading.Children.AddAsLast($linkNode)
            }
        }     
        $web.Update()
    }#End ForEach Hedding 

    $web.Dispose()
    $site.Dispose()
  }
 

Add-PSSnapin "Microsoft.SharePoint.PowerShell" -EA "SilentlyContinue"
new-spnavigation -createfromxml 
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") 

XML File: 

<?xml version="1.0" encoding="utf-8" ?>
  <Navigation>
  <WebUrl>http://<site url></WebUrl> 
    <Headings>
      <Heading Title='My Profile' Url='/test'></Heading>
      <Heading Title='My Place' Url='/test/'>
        <NavLink Title='Home' Url='/test/Pages/Home.aspx'></NavLink>
        <NavLink Title='Google Map' Url='/test/Pages/GoogleMap.aspx'></NavLink>
      </Heading>
      <Heading Title='My Links' Url='/test'>
        <NavLink Title='Yahoo' Url='http://www.yahoo.com'></NavLink>
        <NavLink Title='Facebook' Url='http://www.facebook.com'></NavLink>
         <NavLink Title='Google' Url='http://www.google.com'></NavLink>
      </Heading>  
    </Headings>
  </Navigation>

References:

How to get the latest tweet in to a sharepoint Control

In a previous sharepoint project, I got a task to do a contorl to get the latest tweet. We can use the following simple java script to get the latest tweeter. 
Following are the steps: 

Java script:

<script type="text/javascript">
function GetLatestTweet(user)
{
// set your twitter id
       if(user!='')
             
                var tweeturl = 'http://twitter.com/statuses/user_timeline.json?screen_name=' + user + '&count=1&callback=?';     
                 // using jquery built in get json method with twitter api, return only one resul 
                 $.getJSON(tweeturl, function(data){    
                 // Get the latest Tweet
                 if(data[0]!=null)
{
                                 $("#lblLatestTweetHeader").css('display', 'inline');
                                var tweet = data[0].text;                                         

                                 // Get the created time of the latest Tweet
                                 var tweetCreatedDate=data[0].created_at;                              

                                // format date and get duration
                                var newTweetCreatedDate=parseTwitterDate(tweetCreatedDate);                                                                            

                                // process links and reply        
                               tweet = tweet.replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, function(url) {
                                return '<a href="'+url+'">'+url+'</a>';    
                                }).replace(/B@([_a-z0-9]+)/ig, function(reply) {
                                return  reply.charAt(0)+'<a href="http://twitter.com/'+reply.substring(1)+'">'+reply.substring(1)+'</a>';   
                                });               

                                var dateTimeOfTweet ='<span class="tw_time">'+newTweetCreatedDate+'</span></div>';
                                tweet='<div class=\"tweetBox\">'+tweet ;                

                                // output the result        
                                $("#tweet").html(tweet+ dateTimeOfTweet);     
                }
         });
     }       
} 

    // format date and get duration
    function parseTwitterDate(tdate) {
        if(tdate!=null){
            var system_date = new Date(Date.parse(tdate));
            var user_date = new Date();   
            if (K.ie) {       
            system_date = Date.parse(tdate.replace(/( \+)/, ' UTC$1'))   
            }
             var tweetdate=tdate;
            var month = tweetdate.substring(4,7);
            var day = tweetdate.substring(8,10);  

             // get Time difference in seconds
            var diff = Math.floor((user_date - system_date) / 1000); 
            if (diff <= 1) {return "now";}   
            if (diff < 60) {return " about "+ diff + " seconds ago";}
            if (diff <= 120) {return " one minute ago";} 
            if (diff <= 3600) {return " about "+ Math.floor(diff / 60) + " minutes ago";}
            if (diff < 7200) {return " about 1 hour ago";}   
            if (diff < 86400) {return " about "+ Math.floor(diff / 3600) + " hours ago";}   
            return " on " +day  + " " + month ;
        }
    }  

    var K = function () {   
    var a = navigator.userAgent;   
    return {       
    ie: a.match(/MSIE\s([^;]*)/)   
    }}();

</script> 

The function  “parseTwitterDate” can be used to get the duration of the tweet  

Following code is used in the controler: 

/// <summary>
/// Markup format used to get latest Tweet.
/// </summary>

private const string ScriptFormat = "GetLatestTweet(\"{0}\");";

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{

   base.Render(writer);

   SPSecurity.RunWithElevatedPrivileges(delegate
   {

       var markupBuilder = new StringBuilder();
       var tweeterMarkupBuilder = new StringBuilder(); 

       string latestTweetHedding = “Latest Tweet”
       markupBuilder.Append("<span id=\"lblLatestTweetHeader\" style=\"display: none;\">");
       markupBuilder.Append(latestTweetHedding);
       markupBuilder.Append("</span>");
       markupBuilder.Append("<p id=\"tweet\"></p>"); 

       markupBuilder.Append("<!-- ctrl -->");
       markupBuilder.Append("<table class=\"tblSocial\" width=\"90%\" border=\"0\"                                                 cellpadding=\"0\" cellspacing=\"0\">");

       string userName = “nirasha”;
       if (!string.IsNullOrEmpty(userName))
       {
           tweeterMarkupBuilder.Append("<script language='javascript'>");
           tweeterMarkupBuilder.Append("$(document).ready(function() {");
           tweeterMarkupBuilder.Append(string.Format(ScriptFormat, userName));
           tweeterMarkupBuilder.Append("});");
           tweeterMarkupBuilder.Append("</script>");
       } 

           markupBuilder.Append("</table>");
           markupBuilder.Append("<!-- ctrl -->");

           // Finally emit the content
           writer.Write(tweeterMarkupBuilder.ToString());
           writer.Write(markupBuilder.ToString());
    });
 }