Crickets :)
So digging into the DNN source, found pieces I think will work from the Recycle Bin code (most of source omitted). Thinking this will work, just wanted to follow up in case someone else is searching.
//dnn source code
//Load data is getting the list of deleted tabs and deleted modules by PortalID
protected List<TabInfo> DeletedTabs { get; private set; }
protected List<ModuleInfo> DeletedModules { get; private set; }
private void LoadData()
{
var currentLocale = LocaleController.Instance.GetCurrentLocale(PortalId);
TabCollection tabsList = modeButtonList.SelectedValue == "ALL"
? TabController.Instance.GetTabsByPortal(PortalId)
: TabController.Instance.GetTabsByPortal(PortalId).WithCulture(currentLocale.Code, true);
DeletedTabs = tabsList.Values.Where(tab => tab.IsDeleted)
.OrderBy(tab => tab.TabPath)
.ToList();
DeletedModules = ModuleController.Instance.GetModules(PortalId)
.Cast<ModuleInfo>()
.Where(module => module.IsDeleted && (modeButtonList.SelectedValue == "ALL" || module.CultureCode == currentLocale.Code))
.ToList();
}
//empty recycle bin
private void OnEmptyBinClick(Object sender, EventArgs e)
{
foreach(var module in DeletedModules)
{
DeleteModule(module);
}
//Delete tabs starting with the deepest children
foreach(var tab in DeletedTabs.OrderByDescending(t => t.Level))
{
DeleteTab(tab, true);
}
}