The reason I think DSLs are good but macros are bad is because DSLs make you think long and hard about the costs of implementing a new language. You have to pay for it up-front by writing a compiler and hooking it into your build system, even if you have help from the host language's libraries, and then you'll end up with something that's clearly a separate language and must be documented and learned separately. That cost makes it clear that creating a DSL is not something to do lightly, and you need a problem domain where there really are much higher-level abstractions that can't be captured by an existing programming language.
The problem with macros is that you can create a new language construct with a half dozen or so lines of code, use it in a few hundred places in the codebase, and now your maintainers have a few hundred problems.
Is it just that, when a maintainer sees a function call it's easier to guess what it does, then when they see the use of a macro?
This does not refute your point at all -- that macros can be very helpful when implementing DSLs -- just wanted to point out that macros are not a requirement for doing so.
Also, a DSL expressed using first-class entities will fit into and integrate with its host language more nicely.