When we did our test upgrade I found that “almost” every single page that had a Grouped Listings Web Part (which is basically just a content query web part) had its source changed from showing items from the “Listings” list to instead show all items from the site. Unfortunately there were too many of them to change manually and the gl-retargetcontentquerywebpart command that I had didn’t have sufficient options to restrict the changes to do what I needed (change the web part to use the “Listings” list as the source). So I decided to just create a new command using the gl-retargetcontentquerywebpart code as the basis: gl-retargetgroupedlistingswebpart. The code that actually does the retargetting of the web part is the same code used by the gl-retargetcontentquerywebpart command – I’ve just wrapped the core method with the appropriate looping and filtering constructs:

 1private static void RetargetGroupedListings(SPWeb web, SPList list, SPFile file, string webPartTitle)
 2{
 3    bool wasCheckedOut = true;
 4
 5    if (!Utilities.EnsureAspx(file.Url, true, false))
 6        return; // We can only handle aspx and master pages.
 7
 8    if (file.CheckOutStatus == SPFile.SPCheckOutStatus.None)
 9    {
10        file.CheckOut();
11        wasCheckedOut = false;
12        // If it's checked out by another user then this will throw an informative exception so let it do so.
13    }
14    else if (!Utilities.IsCheckedOutByCurrentUser(file.Item))
15    {
16        // We don't want to mess with files that are checked out to a different user so skip to the next.
17        return;
18    }
19    bool modified = false;
20
21    SPLimitedWebPartManager manager = null;
22    try
23    {
24        manager = web.GetLimitedWebPartManager(file.ServerRelativeUrl, PersonalizationScope.Shared);
25        foreach (WebPart webPart in manager.WebParts)
26        {
27            #pragma warning disable 612
28            ListingSummary cqwp = webPart as ListingSummary;
29            #pragma warning restore 612
30
31            if (cqwp == null)
32                continue;
33
34            if (cqwp.DisplayTitle.ToLowerInvariant() == webPartTitle.ToLowerInvariant())
35            {
36                Guid existingGuid = Guid.Empty;
37                if (!string.IsNullOrEmpty(cqwp.ListGuid))
38                    existingGuid = new Guid(cqwp.ListGuid);
39
40                if (!existingGuid.Equals(list.ID))
41                {
42                    RetargetContentQueryWebPart.AdjustWebPart(cqwp, list, web);
43
44                    manager.SaveChanges(cqwp);
45                    modified = true;
46                }
47            }
48            webPart.Dispose();
49        }
50    }
51    finally
52    {
53        if (manager != null)
54        {
55        manager.Web.Dispose();
56        manager.Dispose();
57        }
58
59        if (modified)
60            file.CheckIn("Checking in changes to page layout due to retargeting of grouped listings web part.");
61        else if (!wasCheckedOut)
62            file.UndoCheckOut();
63
64        if (modified && !wasCheckedOut)
65        {
66            file.Publish("Publishing changes to page layout due to retargeting of grouped listings web part.");
67            if (file.Item.ModerationInformation != null)
68                file.Approve("Auto-approving changes to page layout due to retargeting of grouped listings web part.");
69        }
70    }
71}

The syntax of the command can be seen below:

C:\>stsadm -help gl-retargetgroupedlistingswebpart

stsadm -o gl-retargetgroupedlistingswebpart

Retargets grouped listings web parts upgraded from V2 (points web parts with the specified title to the "Listings" list)

Parameters:
        -url <url to search>
        -scope <Farm | WebApplication | Site | Web | Page>
        [-title <title of web parts to search for (default is "Grouped Listings")>]
        [-publish]

Here’s an example of how to retarget all the grouped listings web parts with a title of “Grouped Listings” to the appropriate “Listings” list in a web application:

stsadm -o gl-retargetgroupedlistingswebpart -url "http://intranet" -scope webapplication -publish