Вопрос

I have a bunch (technical term) of publishing pages within a single subsite of my site collection that contain a broken link. I'm wonder if it's at all possible to use Powershell to perform a 'global' update on all these pages?

Something like:

  1. check out page
  2. open page in edit mode
  3. get HTML from a content editor web part (CEWP)
  4. find the broken link and replace with the correct link
  5. update the CEWP
  6. save, check in and publish the page

Is anything like that possible? Alternatively, is there a way to find text in SQL? I'm wondering if I can locate individual pages within SQL and make the changes?

Cheers

Kevin

Это было полезно?

Решение

Yupp, that's possible using PowerShell and no, do not edit the content database as you'll bring more trouble than fixes.

I've been doing the same operation but within a straight forward console application. You could convert it to a powershell script. Please find below how I parsed a whole site collection and check for specific webpart, update the webpart if the page is not exclusively checked-out and log the whole operation. This will give you most (if not all) the relevant SharePoint object that should be used.

            int processedItemNoActionCount = 0;
            int processedItemSuccessCount = 0;
            int unProcessedItemsWarningCount = 0;
            int unProcessedItemsErrorCount = 0;

            using (SPSite site = new SPSite(*YourSiteCollectionUrl*))
            {
                foreach(SPWeb web in site.AllWebs)
                {
                    Log.Info("Reviewing " + web.ServerRelativeUrl);
                    using(SPWeb currentWeb = site.OpenWeb(web.ID))
                    {
                        PublishingWeb publishingWeb;
                        try
                        {
                            publishingWeb = PublishingWeb.GetPublishingWeb(currentWeb);
                            PublishingPageCollection publishingPageCollection = publishingWeb.GetPublishingPages();

                            foreach (PublishingPage page in publishingPageCollection)
                            {
                                try
                                {
                                    Console.Write(".");
                                    Log.Info("\tReviewing " + page.Uri);


                                    bool reviewRequired = false;
                                    // check if there is any webpart of type WPBanner, WPCarrousel or WPSimulator - the page must be checkout before using the webpart manager -> only check-it out if really necessary !
                                    using (SPLimitedWebPartManager limitedWebPartManager = page.ListItem.File.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))
                                    {

                                        // analyze if any webpart needs to be updated
                                        for (int i = 0; i < limitedWebPartManager.WebParts.Count; i++)
                                        {
                                            System.Web.UI.WebControls.WebParts.WebPart webPart =
                                                limitedWebPartManager.WebParts[i];

                                            string webPartTypeName = webPart.GetType().Name;
                                            if (string.Equals(ConfigurationManager.AppSettings["WebPartBanner"], webPartTypeName, StringComparison.OrdinalIgnoreCase) || 
                                                string.Equals(ConfigurationManager.AppSettings["WebPartCarousel"], webPartTypeName, StringComparison.OrdinalIgnoreCase) || 
                                                string.Equals(ConfigurationManager.AppSettings["WebPartSimulatorTool"], webPartTypeName, StringComparison.OrdinalIgnoreCase))
                                            {
                                                reviewRequired = true;
                                                break;
                                            }
                                        }
                                    }

                                    if (reviewRequired)
                                    {
                                        if (page.ListItem.File.CheckOutType != SPFile.SPCheckOutType.None)
                                        {
                                            Log.WarnFormat("\t-> Warning - WebPart(s) containing WCC reference(s) found but the page is checked-out. Unable to update the webparts without risking data loss. Please review the page {0} manually.", page.Uri);
                                            unProcessedItemsWarningCount++;
                                        }
                                        else
                                        {
                                            page.ListItem.File.CheckOut();

                                            using (SPLimitedWebPartManager limitedWebPartManager = page.ListItem.File.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))
                                            {
                                                for (int i = 0; i < limitedWebPartManager.WebParts.Count; i++)
                                                {
                                                    System.Web.UI.WebControls.WebParts.WebPart wp = limitedWebPartManager.WebParts[i];

                                                    if (string.Equals(ConfigurationManager.AppSettings["WebPartBanner"], wp.GetType().Name, StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        WPBanner wpBanner = wp as WPBanner;
                                                        if (wpBanner != null)
                                                        {

                                                            bool update = false;
                                                            if (ReferencesDictionary.ContainsKey(wpBanner.BannerToDisplayGuid))
                                                            {
                                                                wpBanner.BannerToDisplayGuid = ReferencesDictionary[wpBanner.BannerToDisplayGuid];
                                                                update = true;
                                                            }
                                                            if (ReferencesDictionary.ContainsKey(wpBanner.FallBackBannerGuid))
                                                            {
                                                                wpBanner.FallBackBannerGuid = ReferencesDictionary[wpBanner.FallBackBannerGuid];
                                                                update = true;
                                                            }

                                                            if (update)
                                                            {
                                                                limitedWebPartManager.SaveChanges(wpBanner);
                                                                Log.InfoFormat("\t-> Update - The Banner WebPart '{0}' has been reviewed and updated.",wpBanner.Title);
                                                            }
                                                        }
                                                    }

                                                    else if (string.Equals(ConfigurationManager.AppSettings["WebPartCarousel"],wp.GetType().Name,StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        WPCarousel wpCarousel = wp as WPCarousel;

                                                        if (wpCarousel != null)
                                                        {
                                                            bool update = false;
                                                            if (
                                                                ReferencesDictionary.ContainsKey(wpCarousel.CarouselToDisplayGuid))
                                                            {
                                                                wpCarousel.CarouselToDisplayGuid = ReferencesDictionary[wpCarousel.CarouselToDisplayGuid];
                                                                update = true;
                                                            }
                                                            if (
                                                                ReferencesDictionary.ContainsKey(wpCarousel.FallBackBannerGuid))
                                                            {
                                                                wpCarousel.FallBackBannerGuid = ReferencesDictionary[wpCarousel.FallBackBannerGuid];
                                                                update = true;
                                                            }

                                                            if (update)
                                                            {
                                                                limitedWebPartManager.SaveChanges(wpCarousel);
                                                                Log.InfoFormat("\t-> Update - The Carousel WebPart '{0}' has been reviewed and updated.",wpCarousel.Title);
                                                            }
                                                        }
                                                    }
                                                    else if (string.Equals(ConfigurationManager.AppSettings["WebPartSimulatorTool"], wp.GetType().Name,StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        WPSimulatorTool wpSimulatorTool = wp as WPSimulatorTool;
                                                        if (wpSimulatorTool != null)
                                                        {
                                                            if (ReferencesDictionary.ContainsKey(new Guid(wpSimulatorTool.SimulatorGuid)))
                                                            {
                                                                wpSimulatorTool.SimulatorGuid = ReferencesDictionary[new Guid(wpSimulatorTool.SimulatorGuid)].ToString();
                                                                limitedWebPartManager.SaveChanges(wpSimulatorTool);
                                                                Log.InfoFormat("\t-> Update - The Simulator WebPart '{0}' has been reviewed and updated.",
                                                                    wpSimulatorTool.Title);
                                                            }
                                                        }
                                                    }
                                                }
                                            }

                                            if (page.ListItem.File.CheckOutType != SPFile.SPCheckOutType.None)
                                            {
                                                page.ListItem.File.CheckIn("System Update - WCC Content WebPart(s) have been updated");
                                                page.ListItem.File.CheckIn("", SPCheckinType.MajorCheckIn);
                                                page.ListItem.File.Publish();
                                                page.ListItem.File.Approve();
                                            }

                                            Log.InfoFormat("\t-> Success - The webpart(s) have been updated and the page has been saved successfully (minor checked-in). A major publish might be required.");
                                            processedItemSuccessCount++;
                                        }
                                    }
                                    else
                                    {
                                        Log.Info("\t-> No Action - No relevant webpart found within the page.");
                                        processedItemNoActionCount++;
                                    }
                                }
                                catch (Exception exception)
                                {
                                    Log.ErrorFormat("Unable to review the page located at {0} due to : {1}.", page != null ? page.Url : " [ url property unavailable - page is null ] ", exception);
                                    unProcessedItemsErrorCount++;
                                }
                            }
                        }
                        catch (Exception exception)
                        {
                            Log.ErrorFormat("Unable to review the web located at {0} due to : {1}.", web.ServerRelativeUrl, exception);
                        }
                    }
                }

                OutputMessage("-> Pages reviewed and successfully updated : " + processedItemSuccessCount);
                OutputMessage("-> Pages reviewed but not modified (no action needed) : " + processedItemNoActionCount);
                OutputMessage("-> Pages requiring a manual review (checked-out, deprecated references,...) : " + unProcessedItemsWarningCount);
                OutputMessage("-> Unprocessed pages due to error(s) : " + unProcessedItemsErrorCount);

Другие советы

This is a really interesting question and I would really enjoy writing up a script for you but this would take me a pretty long time. So I will have to stick to giving you some general advice on how to do it.

Using PowerShell

  1. List item
  2. Check out the page.
  3. Download the page to the local FS.
  4. Using Get-Content or similar scrape the page for URLs inside the CEWP.
  5. Once you match the URLs you can use WebRequest to verify that the URLs exist.
  6. If not replace them with your values.
  7. Write back to the ASPX page.
  8. Upload the file back to SharePoint using WebClient and PUT.
  9. Check the item back in.

If I were doing this I might actually use Python for scraping and verifying the URLs as I think it is a little easier to work with strings and such.

WebRequest

$url = "http://companyweb"
$request=[system.Net.HttpWebRequest]::Create($url);
$response = $request.getresponse();
$status = $response.statuscode;
$response.Close();

WebClient - I've not tested this, just giving you an example from memory...

$userName = "userName";
$password = "OhSoSectret!";
$domain = "doamin";
$remoteFileURL = "https://companyweb/teams/it/Shared Documents/" + $fileName;
$filePath = "C:\path\file.aspx"

$webclient = New-Object System.Net.WebClient
$webclient.Credentials = [System.Net.NetworkCredential]::($userName, $password, $domain);
$webclient.UploadFile($remoteFileURL, "PUT", $filePath);
$webclient.Dispose();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с sharepoint.stackexchange
scroll top