Wednesday, 22 September 2010

Check in and approve all publishing pages using PowerShell

This PowerShell script performs the following tasks on a SharePoint Server 2010 site collection containing publishing sites:

  • Checks each site in the site collection to test if it is a publishing site
  • If it is a publishing site, grab all the pages in the Pages library
  • Check in any page currently checked out by you
  • On sites requiring approval for publishing pages, approve any page that has been checked in but still has a Draft approval status

To use, you must first run the following script:

function PublishAllPages ($url)
{
    $site = Get-SPSite -Identity $url
    #Walk through each Publishing Web and check in every page
    $site | Get-SPWeb -limit all | ForEach-Object {
        #Check to see if site is a publishing site
        if ([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($_)) {
            write-host "Reviewing pages in"$_.Title"site...."
            #Get the Publishing Web and pages within it
            $publishingWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($_)
            $publishingPages = $publishingWeb.GetPublishingPages()
            foreach ($publishingPage in $publishingPages)
            {
                #Check to ensure the page is checked out, and if so, check it in
                if ($publishingPage.ListItem.File.CheckOutStatus -ne "None")
                {
                    CheckInPage -page $publishingPage -web $_
                }
                else
                {
                    #Notify administrator that the page is already checked in
                    write-host $publishingPage.Title"("$publishingPage.Name") has already been checked in"
                }
                #Check to ensure page is checked in, and is so, approve it
                if ($publishingPage.ListItem.File.CheckOutStatus -eq "None")
                {
                    ApprovePage -page $publishingPage
                }
            }
        }
        else
        {
            #Notify administrator that the site is not a publishing site
            write-host $_.Title"is not a publishing site"
        }
    }
    #Dispose of the site object
    $site.Dispose()
}

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"
    }
}

Once the script has been run, you can call it using the following command:

PublishAllPages -url sitecollectionurl

For example, for a site collection with the address http://portal, type the following command:

PublishAllPages -url http://portal

When you run this command, a progress report will be shown in the PowerShell console – an example of which is shown below:

PS C:\> PublishAllPages -url http://portal
Reviewing pages in PAC Portal site....
Home ( default.aspx ) has not been checked in as it is currently checked out to domain\aansell
Contact Us ( contactus.aspx ) has already been checked in
Contact Us ( contactus.aspx ) is already approved
Products ( products.aspx ) has already been checked in
Products ( products.aspx ) has been approved
Test ( test.aspx ) has been checked in
Test ( test.aspx ) has been approved

Note that I decided not to check in ALL pages on each site - i.e., those not checked out by you. Doing this could potentially cause lots of issues as users will lose any changes made since they checked the page out. However, if you wanted to do this, you could remove the if ($page.ListItem.File.CheckedOutBy.UserLogin -eq $web.CurrentUser.UserLogin) check performed in the CheckInPage function.

17 comments:

  1. Thanks for this script. Worked really well. I modified it to include publishing the page as well by adding a call to a function like this within the main loop:

    function PublishPage ($page, $web)
    {
    if($page.ListItem.ListItems.List.ForceCheckout)
    {
    write-host "Publishing"$page.Title"("$page.Name")"
    $page.ListItem.File.Publish("Page published automatically by PowerShell script")
    }
    }

    ReplyDelete
  2. Nice - thanks for posting Daniel

    Phil

    ReplyDelete
  3. Hi... thanks for the above script and thank you Daniel for publishing script.
    I have one problem regarding the publishing.

    In the versioning setting, I have to choose Major version only (2nd option). As a result, when I run the mentioned publish script, I got the following error message:

    "You can only publish, unpublish documents in a minor version enabled list"

    Do you know any solution to solve this problem?

    Appreciate your help..
    looking to hear from you soon...
    Regards,
    Adeeb

    ReplyDelete
  4. Phil,

    Love your site! Really really great work!
    This script looks like it'll work for any doc lib with approval enabled. Would you agree if I remove the chaeck for publishing and provide a doc lib name it should work?

    Thanks Josh

    ReplyDelete
  5. This seems to work for regular documents libraries. Thanks Again.

    function PublishAllDocs ($WebUrl, $ListName)
    {

    $web = Get-SPWeb $WebUrl
    $list = $web.Lists[$ListName]

    if($list.EnableModeration)
    {
    #Go through each item in the list
    $list.Items | ForEach-Object {

    #Check to ensure the item is checked out, and if so, check it in
    if ($_.File.CheckOutStatus -ne "None")
    {
    CheckInitem -item $_ -web $web
    }
    else
    {
    #Notify administrator that the item is already checked in
    write-host $_.Title"("$_.Name") has already been checked in"
    }
    #Check to ensure item is checked in, and is so, approve it
    if ($_.File.CheckOutStatus -eq "None")
    {
    Approveitem -item $_
    }
    }
    }
    else
    {
    write-host $_.Title"("$_.Name") does not require approval in this site"
    }

    #Dispose of the site object
    $web.Dispose()
    }

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

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

    ReplyDelete
  6. Thanks for posting the script, Josh!

    ReplyDelete
  7. thanks Phil for the script, could you please tell me how to run the first script?? Powersheel or batch file..?

    ReplyDelete