Add a Notification Message in Top Banner of the SharePoint Site using PowerShell

Requirement: Add a message to the top banner area of a SharePoint site collection

PowerShell to Add Site Notification Message in SharePoint:

After migrating from SharePoint 2013 to SharePoint 2016, we wanted to add a message at the top banner of a migrated site.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

Function Add-CustomAction
{
    param 
    (
        [parameter(Mandatory=$true, ParameterSetName='Site')]
        [Microsoft.SharePoint.SPSite]$Site,
        
        [parameter(Mandatory=$true, ParameterSetName='Web')]
        [Microsoft.SharePoint.SPWeb]$Web,
        
        [parameter(Mandatory=$true, ParameterSetName='Site')]
        [parameter(Mandatory=$true, ParameterSetName='Web')]
        [string]$Message,
        
        [parameter(Mandatory=$true, ParameterSetName='Site')]
        [parameter(Mandatory=$true, ParameterSetName='Web')]
        [string]$ActionName,
        
        [parameter(Mandatory=$false, ParameterSetName='Web')]
        [switch]$IncludeSubWebs,

        [parameter(Mandatory=$true, ParameterSetName='Site')]
        [parameter(Mandatory=$true, ParameterSetName='Web')]
        [string][ValidateSet("Red", "Yellow", "Green", "Blue")]$BackGroundColor
    )

    begin
    {
        # To avoid quote conflicts
        $Message = $Message.Replace( "`"", "'");

        $startingSequence = 1100
        $JavaScript = @"

            function Execute_$($ActionName)_MessageBar_$($PSCmdlet.ParameterSetName)()
            {
                var st = document.getElementById('$ActionName');
                if(st != null)
                {
                    st.style.display = '';
                    return;
                }

                st = document.createElement("div");
                st.id = "$($ActionName)_MessageBar_$($PSCmdlet.ParameterSetName)";
                st.innerHTML = "<div class='ms-status-$($BackGroundColor.ToLower())' style='padding: 12px 14px 6px; border: 1px solid; font-family: \"Segoe UI\", Tahoma, sans-serif; font-size: 13px; min-height: 24px;'>$Message</div>";

                document.body.insertBefore(st, document.body.childNodes[0]);
            }

            // don't show on modal dialog windows
            if(!window.location.search.match("[?&]IsDlg=1"))
            {
                Execute_$($ActionName)_MessageBar_$($PSCmdlet.ParameterSetName)();
            } 
"@
    }
    process
    {
        $customAction = $null
        
        if( $PSCmdlet.ParameterSetName -eq "Site" )
        {
            Remove-CustomAction -Site $site -ActionName $ActionName | Out-Null
            $customAction = $Site.UserCustomActions.Add()
        }
        else
        {
            Remove-CustomAction -Web $Web -ActionName $ActionName | Out-Null
            $customAction = $Web.UserCustomActions.Add()
        }

        $customAction.Location    = "ScriptLink"
        $customAction.Sequence    = $startingSequence
        $customAction.Title       = $ActionName
        $customAction.ScriptBlock = $JavaScript
        $customAction.Update()

        if( $IncludeSubWebs )
        {
            foreach($w in $Web.Webs)
            {
                Add-CustomAction -Web $w -Message $Message -ActionName $ActionName -IncludeSubWebs -BackGroundColor $BackGroundColor
            }
        }
    }
    end
    {
    }
}

Function Remove-CustomAction
{
    param 
    (
        [parameter(Mandatory=$true, ParameterSetName='Site')]
        [Microsoft.SharePoint.SPSite]$Site,
        
        [parameter(Mandatory=$true, ParameterSetName='Web')]
        [Microsoft.SharePoint.SPWeb]$Web,
        
        [parameter(Mandatory=$true, ParameterSetName='Site')]
        [parameter(Mandatory=$true, ParameterSetName='Web')]
        [string]$ActionName
    )

    begin
    {
        $existingActions = @()
    }
    process
    {
        if( $PSCmdlet.ParameterSetName -eq "Site" )
        {
            $Site.UserCustomActions | ? { $_.Title -eq $ActionName } | % { $existingActions += $_ }
            $existingActions | % { $Site.UserCustomActions.Item($_.Id).Delete() }
        }
        else
        {
            $Web.UserCustomActions | ? { $_.Title -eq $ActionName } | % { $existingActions += $_ }
            $existingActions
            $existingActions | % { $Web.UserCustomActions.Item($_.Id).Delete() }
        }
    }
    end
    {
    }
}

$Site = Get-SPSite -Identity "https://intranet.crescent.com/"
Add-CustomAction -Site $site -Message "This site has been migrated to SharePoint 2016. Please don't change anything here!" -ActionName "SiteMovedBanner" -BackGroundColor Red

To Set a notification at the web level, use:

$web = Get-SPWeb -Identity "https://intranet.crescent.com/sites/marketing/us"
Add-CustomAction -Web $web -Message "This site has been migrated to SharePoint 2016. Please don't change anything here!" -ActionName "WebMovedBanner" -BackGroundColor Yellow -IncludeSubWebs

To Remove the Custom action, use:

Remove-CustomAction  -Site $site -ActionName "SiteMovedBanner"

Salaudeen Rajack

Salaudeen Rajack - Information Technology Expert with Two-decades of hands-on experience, specializing in SharePoint, PowerShell, Microsoft 365, and related products. He has held various positions including SharePoint Architect, Administrator, Developer and consultant, has helped many organizations to implement and optimize SharePoint solutions. Known for his deep technical expertise, He's passionate about sharing the knowledge and insights to help others, through the real-world articles!

28 thoughts on “Add a Notification Message in Top Banner of the SharePoint Site using PowerShell

  • Thank you for sharing this and your other Sharepoint articles Salaudeen. It takes good will to share such knowledge and time & effort to put it into an article. I really appreciate you’ve put them into it – it made my life easier at work and the employees I support have it easier with Sharepoint.

    Reply
  • We did find a way to do this, and I tried replying with the code, but I keep getting a WordPress error page when I hit “Post Comment”.

    Reply
  • How to locate and remove banner manually
    Query site
    $spsite = Get-SPWeb -Identity $Site
    Locate the custom action by inspecting the “usercustomactions” property
    $spsite.UserCustomActions
    Locate the correct ID for the banner you wish to remove. Sometimes multiple values will be present.
    Confirm you have the correct action by running the following with the ID
    $spsite.UserCustomActions.Item(“”)
    Then run the method to delete
    $spsite.UserCustomActions.Item(“”).delete()

    I am not seeing the banner added to document libraries. Has anyone had luck with this?

    Reply
  • I’ve been using this script for years with no problem (thanks Salaudeen). I was just asked if I could change the text color in the banner. I have enough trouble with HTML, I know nothing about JavaScript. I tried a few things, none of which seemed to work. I added another set to the parameters
    [parameter(Mandatory=$true, ParameterSetName=’Site’)]
    [parameter(Mandatory=$true, ParameterSetName=’Web’)]
    [string][ValidateSet(“Red”, “Yellow”, “Green”, “White”)]$ForeGroundColor
    and added -ForeGroundColor $ForeGroundColor to the Add-CustomAction line, no good. I added
    ‘ms-status-$($ForeGroundColor.ToLower())’ to the st.innerHTML line in the JavaScript three different ways, again, no luck.

    Can anybody help me figure out how (if) this can be done?

    Reply
    • Do you figure this out? I just came across your question, I added the parameter as well as the ms-status for foregroundcolor and am getting the same results as you – which is assuming it was no changes. I also added it to the actual Add-CustomAction in the ForEach for both the Function and the process at the bottom… still no luck. I’ve tried using some tags in message also with no effect.

      I’d love to know if you – or anyone else – has figured this out

      Reply
  • I tried this code on an on premise SharePoint server 2019 site collection but it only seems to work for classic portions of the site collection. For example, I applied the code above for the entire site collection and the banner does not appear. If I browse to the site contents then site settings the banner appears. It seems this code only works for the classic portions of SharePoint. If you are running only classic SharePoint pages then it will work for you. Is there a way to modify this code so it will work with modern SharePoint pages in SharePoint Server 2019?

    Reply
  • This solution has worked great for me for years. Unfortunately, we are migrating to SP 2019 and when I test the script in our new environment it does not seem to work. Is this a known issue and is there a workaround? We would love to be able to continue using it since it has been a part of our tool set for years. Thanks in advance!

    Reply
    • Eric, I know this an old issue but were you ever able to get this to work on SharePoint Server 2019? When I run this script it does not show the banner on any of the modern SharePoint pages. It does show on the classic pages though.

      Steve

      Reply
  • Hi guys, I am trying to run this script for SharePoint Online but getting below error:

    Unable to find type [Microsoft.SharePoint.SPSite].
    At line:8 char:9
    [Microsoft.SharePoint.SPSite]$Site,
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    CategoryInfo : InvalidOperation: (Microsoft.SharePoint.SPSite:TypeName) [], RuntimeException
    FullyQualifiedErrorId : TypeNotFound

    Can someone please help me to resolve this error?

    Reply
  • Hello Guys, After putting up a notification message, I want the site to redirected automatically to newly migrated site in 10 secs. Can someone help me on the same.

    Reply
  • Hi, Is there a way to put a message in the banner and do a auto redirection to the new migrated site in 10 or 20 seconds

    Reply
  • Hi Nitesh,

    Applying background color is not working for me. Others are working like a charm. Could you please help me to apply background color.

    Reply
  • Hello guys, is anyone able to guide towards solution to above query November 17, 2020 at 6:09 PM.

    Reply
  • Is there a way we can add/remove banner onto multiple site collection utilizing the above script.
    Either we pick up site collections URL from single variable or sharepoint list etc.
    I have tried to use below approach, but it throws an error “Add-CustomAction : Cannot process argument transformation on parameter ‘Site’. Cannot convert the “System.Object[]” value of type “System.Object[]” to type “Microsoft.SharePoint.SPSite”.”

    $Site= @(
    “https://contoso./sites/Test”
    “https://contoso.com/sites/Test2”
    )

    Reply
  • Will this work on SharePoint 2010 sites that you are migrating to SharePoint Online?

    Reply
  • How would you add an HREF link in the banner?

    Reply
    • Put it in the Add-CustomAction line:
      Add-CustomAction -Web $web -Message “This site is scheduled to be decommissioned after July 20th. If you need access to this site after that date, please [a href=’PUT URL HERE’] read [/a] the following instructions to submit a change request to claim ownership of this site.[BR][BR]For any general questions, please reach out to [a href=’EMAIL ADDRESS’] Someone@example.com [/a]” -ActionName “WebMovedBanner” -BackGroundColor Red -ForeGroundColor White -IncludeSubWebs

      This example is for the web level banner, but it’s the same for a site level banner. NOTE: I had to use [] instead of <> to get the reply to show the code. There was probably a better way to do that, but HTML isn’t one of my strong points.

      Reply
  • Thanks for the solution, It works in SP 2016. But it is not working in SP online, I tried CSOM with powershell code runs properly but it is not add the banner but i can able add ribbon controls. Please anyone suggest solution for this

    Reply
  • Thanks a ton, this solution works like a charm. I made a little modification around background color used Hex code instead, but awesome!!!!!

    Reply
  • HI All,
    First off this solution is really – really cool way to go.

    I found a very easy solution for the repeating banner problem. Go to Manage Site Features and DEACTIVATE the Minimal Download Strategy Feature.

    Works like a charm for me!

    Stowe

    Reply
  • I have the problem of duplicate banners as well. MyITGuy’s workaround didn’t work for me, it didn’t work at all. Anybody come up with a way to avoid this? Refreshing the page (F5) gets rid of the extra banner, but I’d like to know how to avoid it in the first place.

    Reply
    • Try turning off the Minimal Download Strategy Feature. Works great for me.

      Stowe

      Reply
      • I added the script here (https://www.sharepointdiary.com/2016/02/deactivate-feature-on-all-sites-in-sharepoint-using-powershell.html) as a function to the script above so that the Minimal Download Strategy feature gets disabled right before the banner gets added.

        Reply
  • Thanks for sharing this post; as stated in the comment above, it’s a great post. The only question I have as for my usage experience is how to stop multiple instances of the banner getting added to the top for each page visited.

    Reply
    • I’m having the same issue with multiple instances of the banner getting added?

      Reply
    • The only workaround I was able to came up with to answer the question I posted above was to perform the following addition to the code.

      1. Insert a variable declaration before line 39: [ var firstTimeFlag = “Yes” ]
      2. Enclose line 50 inside a If Statement: [ if(firstTimeFlag == “Yes”) { document.body.insertBefore(st, document.body.childNodes[0]); } ]
      3. Finally, Insert a line to reset the value of flag before line 58: [ firstTimeFlag = “No” ]

      This modification is not necessary if you’re able to get the code to function as is, but in the situation you ran into the issue I was confronted with; then try this modification.

      Reply
  • Great thanks 🙂 Omg you’ve already solved all possible problems with administering,- i’m reading you for more than 4 years and still finding something useful))
    Please keep safe your website and its domain for the future admins generation)
    Tnanks a lot again!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *