I've done it in Javascript/JQuery with SPServices. Maybe you can use these ideas in another language. Call getAllEmails once per site collection with the site collection URL. I used this to see how many we used, since SharePoint online doesn't allow them. One of our sticking points of migrating to online.
function getAllEmails(url) { siteList = "<table><tr style='background-color: #78FF78'><td class='fmgTD'><b>Site</b></td><td class='fmgTD'><b>List</b></td><td class='fmgTD'><b>Email Address</b></td></tr>"; getSiteLists(url, "Home"); $().SPServices({ operation: "GetWebCollection", webURL: url, async: false, completefunc: function(xData, status) { // alert(xData.responseText); $(xData.responseXML).find("Web").each(function() { getSiteLists($(this).attr("Url"),$(this).attr("Title")); url = $(this).attr("Url"); getSubSites(url); }); } }); siteList += "</table>"; $('#emailSites').append(siteList); } function getSiteLists(weburl ,webtitle) { $().SPServices({ operation: "GetListCollection", webURL: weburl, async: false, completefunc: function(xData, status) { var count = 0; $(xData.responseXML).find("List").each(function() { if($(this).attr("EmailAlias") && $(this).attr("EmailAlias").substr(0,13) != 'recordscenter'){ if(count == 0) { siteList += "<tr><td class='fmgTD'>" + webtitle + "</td>"; } else { siteList += "<tr><td class='fmgTD'> </td>"; } count++; siteList += "<td class='fmgTD'>" + $(this).attr("Title") + "</td><td class='fmgTD'><b>" +$(this).attr("EmailAlias") + "</b>@THEEMAILADDRESS</td></tr>"; } }); } }); } function getSubSites(weburl) { $().SPServices({ operation: "GetWebCollection", webURL: weburl, async: false, completefunc: function(xData, status) { // alert(xData.responseText); $(xData.responseXML).find("Web").each(function() { // now get all ists for this web getSiteLists($(this).attr("Url"),$(this).attr("Title") ); getSubSites($(this).attr("Url")); }); } }); }