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);