diff --git a/mpcdf_refresh_aggregates.py b/mpcdf_refresh_aggregates.py
new file mode 100644
index 0000000000000000000000000000000000000000..0952e28ef2e26deb952909288fbb7f59e54e76bb
--- /dev/null
+++ b/mpcdf_refresh_aggregates.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python2
+from __future__ import print_function
+
+import os
+import osc
+import osc.conf
+import osc.core
+import osc.cmdln
+
+import mpcdf_common
+
+from osc.util.helper import decode_it
+from xml.etree import ElementTree
+
+
+def do_mpcdf_refresh_aggregates(self, subcmd, opts, *args):
+    """${cmd_name}: Recreates the aggregate packages in software:dist
+
+    Use this only if you know what this means
+
+    Usage:
+        osc ${cmd_name}
+
+    ${cmd_option_list}
+
+    """
+
+    if len(args) != 0:
+        raise osc.oscerr.WrongArgs("Too many arguments")
+
+    if osc.core.store_read_project(os.curdir) != "software:dist" or \
+            osc.core.is_package_dir(os.curdir):
+        raise osc.oscerr.WrongArgs("You must be in the project checkout of software:dist")
+
+    dist = osc.core.Project(".", False)
+
+    apiurl = self.get_api_url()
+
+    def refresh_aggregate(aggregatename, project, source, target):
+        if not os.path.exists(aggregatename):
+            package = osc.core.Package.init_package(apiurl, "software:dist", aggregatename, aggregatename)
+            dist.addPackage(aggregatename)
+        else:
+            package = dist.get_pacobj(aggregatename)
+
+        with open(aggregatename + "/_aggregate", "w") as fd:
+            print('<aggregatelist>', file=fd)
+            print('  <aggregate project="{project}">'.format(project=project), file=fd)
+            print('    <nosources/>', file=fd)
+            print('    <repository target="{target}" source="{source}" />'.format(target=target, source=source), file=fd)
+            print('  </aggregate>', file=fd)
+            print('</aggregatelist>', file=fd)
+
+        if package.status("_aggregate") == "?":
+            package.addfile("_aggregate")
+
+        if package.status("_aggregate") in ("A", "M"):
+            dist.commit((aggregatename,), msg="Refresh aggregate", verbose=True)
+
+        pkg_meta = osc.core.show_package_meta(apiurl, "software:dist", aggregatename)
+        root = ElementTree.fromstringlist(pkg_meta)
+        pkg_meta = ElementTree.tostring(root, encoding=osc.core.ET_ENCODING)
+
+        build = root.find("./build")
+        if build is None:
+            build = ElementTree.SubElement(root, "build")
+
+        for enable in build.findall("./enable"):
+            build.remove(enable)
+
+        node = ElementTree.Element("enable")
+        node.set("repository", target)
+        node.tail = "\n  "
+        build.insert(0, node)
+
+        new_pkg_meta = ElementTree.tostring(root, encoding=osc.core.ET_ENCODING)
+        if pkg_meta != new_pkg_meta:
+            osc.core.edit_meta("pkg", ("software:dist", aggregatename),
+                               data=new_pkg_meta)
+
+    projects = [p for p in osc.core.meta_get_project_list(apiurl)
+                if p.startswith("software") and not (p == "software:dist" or p == "software:images")]
+
+    macros = {}
+    for project in projects:
+        repos = osc.core.get_repositories_of_project(apiurl, project)
+        if project == "software":
+            # Stupid special case
+            target = "SLE_12_SP3-sandybridge"
+        else:
+            target = project[len("software:"):].replace(":", "-")
+
+        macros[target] = []
+        for attribute in mpcdf_common.config_attributes + mpcdf_common.default_attributes:
+            _, name = attribute.split(":")
+            values = mpcdf_common.get_attribute_values(apiurl, project, None, attribute)
+            macros[target].append("%available_{0} {1}".format(name, ",".join(sorted(values))))
+
+        for repo in repos:
+            aggregatename = "zz_aggregate_" + project.replace(":", "-") + "_" + repo
+            refresh_aggregate(aggregatename, project, repo, target)
+
+    prjconf = list(map(decode_it, osc.core.show_project_conf(apiurl, "software:dist")))
+    start_marker = "# Autogenerated by osc mpcdf_refresh_aggregates, do not edit till end of section\n"
+    end_marker = "# End of autogenerated section\n"
+
+    try:
+        start = prjconf.index(start_marker)
+        end = prjconf.index(end_marker)
+    except ValueError:
+        start = None
+        end = len(prjconf)
+
+    prjconf_head = "".join(prjconf[:start])
+    prjconf_tail = "".join(prjconf[end + 1:])
+    prjconf = [start_marker]
+
+    distributions = osc.core.get_repositories_of_project(apiurl, "distributions")
+    for swdistrepo in osc.core.get_repositories_of_project(apiurl, "software:dist"):
+        for distrepo in distributions:
+            if swdistrepo.startswith(distrepo):
+                refresh_aggregate("zz_aggregate_" + swdistrepo + "_distributions", "distributions", distrepo, swdistrepo)
+                break
+            distrepo = None
+        prjconf.append('%if "%_repository" == "{0}"'.format(swdistrepo))
+        prjconf.append("Macros:")
+        prjconf.extend(macros[swdistrepo])
+        prjconf.append("%distribution {0}".format(distrepo))
+        prjconf.append(":Macros")
+        prjconf.append("%endif")
+        prjconf.append("")
+
+    prjconf.append(end_marker)
+    prjconf = prjconf_head + "\n".join(prjconf) + prjconf_tail
+    osc.core.edit_meta("prjconf", "software:dist", data=prjconf)