After a Tridion CMS Database restore from another environment we cannot unpublish Components from the Broker. If we publish to the Broker then we can unpublish. We want to
Components themselves are never published from Tridion, they are only published as part of a Component Presentation (Component + Component Template).
The SetPublishedTo
method on a Component Template takes a Component as a parameter. So by calling it you can set one Component Presentation as Published or Unpublished.
Once you've unpublished all Component Presentations of a Component, that Component implicitly becomes Unpublished.
I use the following C# based code in a command line tool for switching the PublishStates of all my items after a SDL Tridion 2009 environment switch (What version are you using?):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tridion.ContentManager.Interop.TDS;
using Tridion.ContentManager.Interop.TDSDefines;
using System.Xml;
namespace SetAllItemsAsUnpublished
{
/// <summary>
/// A command line script that can enable/disable users
/// </summary>
class Program
{
static void Main(string[] args)
{
TDSE tdse = new TDSE();
User currentUser = tdse.User;
ListRowFilter listRowFilter = tdse.CreateListRowFilter();
String xpath = "/tcm:ListPublishItems/*/*[local-name()='Page' or local-name()='Component']";
listRowFilter.SetCondition("Recursive", true);
listRowFilter.SetCondition("OnlyPublishedPages", true);
listRowFilter.SetCondition("OnlyPublishedCPs", true);
//listRowFilter.SetCondition("ItemType", ItemType.ItemTypePage);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
nsmgr.AddNamespace("tcm", "http://www.tridion.com/ContentManager/5.0");
//Check that the user running the script is an Administrator
if (currentUser.privileges == TDSPrivileges.TdsPrivilegeSystemAdministrator)
{
Publications publications = tdse.GetPublications();
Console.WriteLine("There are " + publications.Count + " to be processed");
int i = 0;
foreach (Publication publication in tdse.GetPublications())
{
++i;
Console.WriteLine(" - Processing " + publication.Title + "(" + i + " of " + publications.Count + ")");
foreach( PublicationTarget target in tdse.GetPublicationTargets()){
Console.Write(" checking target: " + target.Title);
XmlDocument publishedItemsXml = new XmlDocument();
try
{
publishedItemsXml.LoadXml(publication.GetListPublishItems(target.ID, false, false, ListColumnFilter.XMLListID, listRowFilter));
foreach (XmlElement publishedItemNode in publishedItemsXml.SelectNodes(xpath, nsmgr))
{
String uri = publishedItemNode.Attributes["ID"].Value;
Console.Write(".");
if (publishedItemNode.LocalName == "Page")
{
Page page = (Page)tdse.GetObject(uri, EnumOpenMode.OpenModeView, publication, XMLReadFilter.XMLReadAll);
page.SetPublishedTo(target, false, currentUser);
if (page.Info.IsCheckedOut)
{
page.CheckIn(true);
}
}
else
{
foreach (XmlElement ctRenderNode in publishedItemNode.SelectNodes("tcm:RenderWith", nsmgr))
{
String uriCT = ctRenderNode.Attributes["ID"].Value;
ComponentTemplate ct = (ComponentTemplate)tdse.GetObject(uriCT, EnumOpenMode.OpenModeView, publication, XMLReadFilter.XMLReadAll);
ct.SetPublishedTo(uri, target, false, currentUser);
if (ct.Info.IsCheckedOut)
{
ct.CheckIn(true);
}
}
}
}
Console.WriteLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
else
{
//Warn when there is a non-admin user running the script
Console.WriteLine("You must be an SDL Tridion CMS Administrator to run this application");
}
Console.WriteLine();
Console.WriteLine("Done! Hit ENTER key to close");
Console.ReadLine();
}
}
}
So basically setting the CT to UnPublished should do what you need, as the Component is not technically published, it is a Component Presentation based on that CT.