0

We have currently updated our SharePoint 2010 Custom application and Now have it running on SharePoint 2013. We have realized that not all of the static content is being updated when we apply the updated wsp that Visual Studio had published.

Example: After installing the wsp against our existing content database, the site comes up fine, but several of the aspx files still contain old SP2010 14.0.0.0 headers instead of the new SP2013 15.0.0.0 headers. To check this, we converted the .wsp to a .cab file and manually verified that the files were indeed updated. This means that for some reason, the PowerShell install/update process is ignoring several files.

What are we missing here?

  • 1
    You say "against our existing content database", so we can assume you are not deploying to the _layouts folder? Also, was the site itself upgraded from SP2010 to SP2013, or are you trying to install your application fresh on a brand new SP2013 site that never had your application on it before? – Dylan Cristy Dec 20 '18 at 20:15
  • @DylanCristy We have been using a fresh "clean" VM to install the SP2013. We setup SP2013 web Application on the VM, then existing SP2010 content DB is mounted. The site is now up running we just have notice 33 or so files are not being updated ( that we have found) or new files being added. While others seem to be updated. I'm unsure what you mean by not deploying to _layout folder. Is that seperate step. We have been using install-spsolution in admin PowerShell. – John DK Dec 20 '18 at 20:45
  • @DylanCristy Also when mounting the Content Database Sharepoint applied an upgrade process that took about 4--5 hours. After WSPs where installed compatibility level 15 the first time, we had to run upgrade-spsite to upgrade site to 15 completely. – John DK Dec 20 '18 at 21:54
  • Are these .aspx pages in the pages library in SharePoint web site or in "_layouts" folder in file system? Has these pages been created using custom page layouts using a custom site definition? Does this .wsp solution has a feature to provision these updated pages? – Prasanna Dec 20 '18 at 22:11
  • Pardon my lack of conventional SP knowledge. If by "library in SharePoint website" you mean the all site content, then yes. All of the files in question are located there. – John DK Dec 20 '18 at 22:31
1

I am almost certain that what you will need to do to get those files updated is do feature upgrades.

In the comments, you said that all your files are located in "all site content", so whether they are in the Style Library or Site Pages or Site Assets, all those are document libraries in the site, and therefore their content is actually in the content database for the site.

By contrast, things that are in the "layouts" folder exist on the file system of the server, not in any database. Explaining the layouts folder is a little beyond the scope of this question, but the relevant point is that files that are deployed to the layouts folder will always be automatically updated and overwritten when doing Install-SPSolution or Update-SPSolution.

Files that are deployed to document libraries (like Site Pages or Site Assets) are deployed through Features that include Modules, and the Modules have the information about the URL for where the file should end up. The thing is, if the feature that deploys the files is already activated on the site, updating the files in the solution will not redeploy the files to the document libraries. It's during the Feature activation process that SharePoint looks at the Elements.xml file from the Module and copies the files into the document libraries. So how do you tell SharePoint to re-copy the files in the Modules into the document libraries? One way would be to deactivate the Features and then re-activate them. But if you have existing data, and the Feature is set up to remove assets (lists, libraries, etc.) when deactivating, then you could end up losing data. So the other way is to upgrade the Feature.

Chris O'Brien has a fantastic series of articles on Feature upgrading, which you should definitely read. But what you will need to do is add to your Feature definition XML with the instructions of what to do during the upgrade, and one of the instructions is ApplyElementManifests, which allows you to tell SharePoint to re-apply the Elements.xml from your Modules, which will essentially re-copy the files into the document libraries.

[Important to note here, as part of the update, you should go into the Modules and add the ReplaceContent="TRUE" attribute to your File element in the Module, which will tell SharePoint that you definitely want to overwrite the files.]

It's kind of a two step process. First, you make your updates to your files in VS, make sure to add the ReplaceContent in the Modules to force the files to get overwritten, and update your Feature definition XML with the upgrade instructions, which might look something like this:

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/" Version="2.0.0.0">
  <UpgradeActions>
    <VersionRange BeginVersion="1.0.0.0" EndVersion="2.0.0.0">
      <ApplyElementManifests>
        <ElementManifest Location="MyCustomPagesModule\Elements.xml" />
      </ApplyElementManifests>
    </VersionRange>
  </UpgradeActions>
</Feature>

Then package up your updated WSP, and deploy it to your farm using Update-SPSolution (not using the Uninstall Remove Add Install cycle). You are halfway there, because now the Feature definition in the Farm has the updated files. Any new activations of your Feature will get the new files. However, Upgrade-SPSolution does not automatically upgrade any Features that are already activated on a site. So the second step of doing a Feature upgrade is to get a hold of the installed/activated Feature on a site, and call its Update() method.

There are a couple ways to get to the installed/activated Features to update, I usually write a Powershell script for each of my solutions that has all the Feature IDs of the Features in that particular solution hard coded into the script. Those look something like this:

if((Get-PSSnapin "Microsoft.SharePoint.PowerShell") -eq $null)
{
      Add-PSSnapin Microsoft.SharePoint.PowerShell
}

$siteFeatureID = 'guid-of-site-scoped-feature'
$webFeatureID = 'guid-of-web-scoped-feature'

Start-SPAssignment -Global
foreach($webApp in (Get-SPWebApplication))
{
    foreach ($site in $webApp.Sites)
    {
        $siteFeatureActive = Get-SPFeature -Site $site -Identity $siteFeatureID -ErrorAction SilentlyContinue
        if ($siteFeatureActive -ne $null)
        {
            Write-Host "My Site Feature Name feature FOUND on Site" $site.Url
            Write-Host "Current farm version:" $siteFeatureActive.Version

            try
            {
                $siteFeature = $site.Features | Where { $_.DefinitionId -eq [Guid]($siteFeatureID) }
                Write-Host "Installed Feature version:" $siteFeature.Version                

                if ($siteFeatureActive.Version -ne $siteFeature.Version)
                {
                    Write-Host "Upgrading..."
                    $siteFeature.Upgrade($false)
                }

                Write-Host
            }
            catch
            {
                Write-Host "Upgrade failed for Site " $site.Url
                Write-Host
                Write-Host $_.Exception.Message
                Write-Host
                Write-Host $_.Exception.StackTrace
                Write-Host
                Write-Host
            }

            foreach ($web in $site.AllWebs)
            {
                $webFeatureActive = Get-SPFeature -Web $web -Identity $webFeatureID -ErrorAction SilentlyContinue
                if ($webFeatureActive -ne $null)
                {
                    Write-Host "My Web Feature Name feature FOUND on Web " $web.Url
                    Write-Host "Current farm version:" $webFeatureActive.Version

                    try
                    {
                        $webFeature = $web.Features | Where { $_.DefinitionId -eq [Guid]($webFeatureID) }
                        Write-Host "Installed feature version:" $webFeature.Version

                        if ($webFeatureActive.Version -ne $webFeature.Version)
                        {
                            Write-Host "Upgrading..."
                            $webFeature.Upgrade($false)
                        }

                        Write-Host
                    }
                    catch
                    {
                        Write-Host "Upgrade failed for Web " $web.Url
                        Write-Host
                        Write-Host $_.Exception.Message
                        Write-Host
                        Write-Host $_.Exception.StackTrace
                        Write-Host
                        Write-Host
                    }
                }
                else
                {
                    Write-Host "Web feature NOT found on " $web.Url
                    Write-Host
                }
                Write-Host "----------------------------------------------------------------"
            }
        }
        else
        {
            Write-Host "Site feature NOT found on" $site.Url
            Write-Host
        }
        Write-Host "----------------------------------------------------------------"
    }
}
Stop-SPAssignment -Global
Write-Host
Write-Host "Complete"

Running that script and calling the Upgrade() method on the installed Feature will trigger the UpgradeActions you have defined in the Feature definition XML, and re-apply the Elements.xml from your Module, and thus re-deploy the updated files to the document libraries.


Addressing @JohnDK's comments:

Where you can add the upgrade action instructions to the feature is, and you were almost there, if you go to your feature interface, click on the "Manifest" tab to get to the manifest XML preview, and then at the bottom of the screen you will see "Edit options" with a plus sign next to it. Click on the plus to expand that section, and it will give you an editor window where you can add the upgrade actions XML, which will be merged with the other XML that's automatically generated by VS when you change things on the "Design" tab:

Edit options button

Edit manifest text area

Where you find the feature IDs is in the same place, in the manifest. If you look at the first line of the VS generated manifest, at the Feature element itself, it will show you Version, Title, Description, etc. If you scroll the window right to look further along that line, you will eventually find the ID:

Feature ID in feature manifest

I'm sure there is probably a way to pull that ID from the Farm using Powershell, but I think it's just easier to go into the manifest and copy it. You can't edit text in that window, but you can highlight text and Ctrl-C.

Another note about my Powershell script above where I use those IDs - keep in mind that for the example I posted here, I'm looping though all Site Collections in a Farm, and if I find one of my Site Collection scoped features activated, I update it, and then I loop through all Webs within that Site Collection looking for Web scoped features. This is because my Site Collection scoped feature had fields and content type definitions, so I wanted to deploy them to the root of the site collection, but the Web scoped feature has a custom list definition that uses the content type from the other feature. So I know for a fact that if the Site Collection scoped feature is not present, none of the Webs in that Site Collection is going to have the custom list definition, because it won't have the content type definition available, so I don't need to bother with looping through those Webs.

Your situation may be different, and you might need to use different logic to target the Site Collections or Webs where you are looking for your features to upgrade. Maybe you want to loop through everything for completeness? Maybe you know for a fact that your features are only present on one specific Web in the entire Farm, and you want to target that Web only by using Get-SPWeb with that site's URL. There are many ways of going about doing it, and you need to figure out the right way that is appropriate to your situation.

  • I'm currently working through the steps you provided, Thanks for the clear explanation. I did want to clarify a few points. First I'm using VS 2017 I can't seem to find the existing feature.xml file to added the upgrade actions instructions. The closest I can get is when looking at my .feature interface and is shows the manifest preview file. I'm trying to determine if this setting needs to be added to the element files for the modules where I added the ReplaceContent = TRUE or if I will need to build the ".wsp" then modify the manifest after wsp is generated? – John DK Dec 26 '18 at 16:40
  • Also in your PowerShell script you declare two guid's "sitefeatureID" and "WebFeatureId" I wanted to confirm how I should go about confirming what those id's should be. – John DK Dec 26 '18 at 16:40
  • 1
    @JohnDK updated my answer to address your other questions. – Dylan Cristy Dec 26 '18 at 22:44
  • Thanks for the all the help I was able to work through most of these issues today, we realized that this feature doesn't seem to effect any list and was able to toggle the feature from to deactivate and back and files seem to have updated. ( did cherry pick the files in the feature manifest so that only files we were concerned about would be updated.) Again thanks for all the help with this!! – John DK Dec 27 '18 at 22:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.