diff --git a/zircon/system/core/devmgr/devcoordinator/coordinator.cpp b/zircon/system/core/devmgr/devcoordinator/coordinator.cpp
index 5b9cc7904bad61973d385040063cd6595425bed1..cfa42e8ed37c8b2ec1b683e95c1c4b41c0ec77fe 100644
--- a/zircon/system/core/devmgr/devcoordinator/coordinator.cpp
+++ b/zircon/system/core/devmgr/devcoordinator/coordinator.cpp
@@ -31,7 +31,6 @@
 #include <lib/fzl/owned-vmo-mapper.h>
 #include <lib/zircon-internal/ktrace.h>
 #include <lib/zx/job.h>
-#include <lib/zx/socket.h>
 #include <libzbi/zbi-cpp.h>
 #include <zircon/assert.h>
 #include <zircon/processargs.h>
@@ -132,36 +131,6 @@ zx_status_t Coordinator::InitializeCoreDevices(const char* sys_device_driver) {
     return ZX_OK;
 }
 
-zx_status_t Coordinator::DmCommand(size_t len, const char* cmd) {
-    if (InSuspend()) {
-        log(ERROR, "devcoordinator: rpc: dm-command \"%.*s\" forbidden in suspend\n",
-            static_cast<uint32_t>(len), cmd);
-        return ZX_ERR_BAD_STATE;
-    }
-    if ((len == 6) && !memcmp(cmd, "reboot", 6)) {
-        Suspend(DEVICE_SUSPEND_FLAG_REBOOT);
-        return ZX_OK;
-    }
-    if ((len == 17) && !memcmp(cmd, "reboot-bootloader", 17)) {
-        Suspend(DEVICE_SUSPEND_FLAG_REBOOT_BOOTLOADER);
-        return ZX_OK;
-    }
-    if ((len == 15) && !memcmp(cmd, "reboot-recovery", 15)) {
-        Suspend(DEVICE_SUSPEND_FLAG_REBOOT_RECOVERY);
-        return ZX_OK;
-    }
-    if ((len == 7) && !memcmp(cmd, "suspend", 7)) {
-        Suspend(DEVICE_SUSPEND_FLAG_SUSPEND_RAM);
-        return ZX_OK;
-    }
-    if (len == 8 && (!memcmp(cmd, "poweroff", 8) || !memcmp(cmd, "shutdown", 8))) {
-        Suspend(DEVICE_SUSPEND_FLAG_POWEROFF);
-        return ZX_OK;
-    }
-    log(ERROR, "dmctl: unknown command '%.*s'\n", (int)len, cmd);
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
 const Driver* Coordinator::LibnameToDriver(const fbl::String& libname) const {
     for (const auto& drv : drivers_) {
         if (libname == drv.libname) {
@@ -981,19 +950,6 @@ zx_status_t Coordinator::PublishMetadata(const fbl::RefPtr<Device>& dev, const c
     return ZX_OK;
 }
 
-zx_status_t fidl_DmCommand(void* ctx, zx_handle_t raw_log_socket, const char* command_data,
-                           size_t command_size, fidl_txn_t* txn) {
-    zx::socket log_socket(raw_log_socket);
-
-    auto dev = fbl::WrapRefPtr(static_cast<Device*>(ctx));
-    if (log_socket.is_valid()) {
-        dev->coordinator->set_dmctl_socket(std::move(log_socket));
-    }
-
-    zx_status_t status = dev->coordinator->DmCommand(command_size, command_data);
-    dev->coordinator->set_dmctl_socket(zx::socket());
-    return fuchsia_device_manager_CoordinatorDmCommand_reply(txn, status);
-}
 
 zx_status_t fidl_DmMexec(void* ctx, zx_handle_t raw_kernel, zx_handle_t raw_bootdata) {
     zx_status_t st;
@@ -1273,7 +1229,7 @@ void Coordinator::Suspend(SuspendContext ctx) {
     if (suspend_context().flags() == SuspendContext::Flags::kSuspend) {
         return;
     }
-    // Move the socket in to prevent the rpc handler from closing the handle.
+
     suspend_context() = std::move(ctx);
 
     auto completion = [this](zx_status_t status) {
@@ -1283,8 +1239,6 @@ void Coordinator::Suspend(SuspendContext ctx) {
             // do not continue to suspend as this indicates a driver suspend
             // problem and should show as a bug
             log(ERROR, "devcoordinator: failed to suspend: %s\n", zx_status_get_string(status));
-            // notify dmctl
-            ctx.CloseSocket();
             if (ctx.sflags() == DEVICE_SUSPEND_FLAG_MEXEC) {
                 ctx.kernel().signal(0, ZX_USER_SIGNAL_0);
             }
@@ -1299,8 +1253,6 @@ void Coordinator::Suspend(SuspendContext ctx) {
             // on arm, if the platform driver does not implement
             // suspend go to the kernel fallback
             ::suspend_fallback(root_resource(), ctx.sflags());
-            // this handle is leaked on the shutdown path for x86
-            ctx.CloseSocket();
             // if we get here the system did not suspend successfully
             ctx.set_flags(devmgr::SuspendContext::Flags::kRunning);
         }
@@ -1328,12 +1280,12 @@ void Coordinator::Suspend(uint32_t flags) {
         vfs_exit(fshost_event());
     }
 
-    Suspend(SuspendContext(SuspendContext::Flags::kSuspend, flags, std::move(dmctl_socket_)));
+    Suspend(SuspendContext(SuspendContext::Flags::kSuspend, flags));
 }
 
 void Coordinator::DmMexec(zx::vmo kernel, zx::vmo bootdata) {
     Suspend(SuspendContext(SuspendContext::Flags::kSuspend, DEVICE_SUSPEND_FLAG_MEXEC,
-                           zx::socket(), std::move(kernel), std::move(bootdata)));
+                           std::move(kernel), std::move(bootdata)));
 }
 
 // device binding program that pure (parentless)
diff --git a/zircon/system/core/devmgr/devcoordinator/coordinator.h b/zircon/system/core/devmgr/devcoordinator/coordinator.h
index 12158756f8eb52196d46e60f22a7d1e1b4eb0d1d..139eb0ed93dac574de01fd7626bebada85a787c9 100644
--- a/zircon/system/core/devmgr/devcoordinator/coordinator.h
+++ b/zircon/system/core/devmgr/devcoordinator/coordinator.h
@@ -17,7 +17,6 @@
 #include <lib/zx/event.h>
 #include <lib/zx/job.h>
 #include <lib/zx/process.h>
-#include <lib/zx/socket.h>
 #include <lib/zx/vmo.h>
 
 #include <utility>
@@ -44,10 +43,10 @@ public:
 
     SuspendContext() = default;
 
-    SuspendContext(Flags flags, uint32_t sflags, zx::socket socket,
-                   zx::vmo kernel = zx::vmo(), zx::vmo bootdata = zx::vmo())
-        : flags_(flags), sflags_(sflags), socket_(std::move(socket)),
-          kernel_(std::move(kernel)), bootdata_(std::move(bootdata)) {}
+    SuspendContext(Flags flags, uint32_t sflags, zx::vmo kernel = zx::vmo(),
+                   zx::vmo bootdata = zx::vmo())
+        : flags_(flags), sflags_(sflags), kernel_(std::move(kernel)),
+          bootdata_(std::move(bootdata)) {}
 
     ~SuspendContext() {}
 
@@ -63,9 +62,6 @@ public:
     const zx::vmo& kernel() const { return kernel_; }
     const zx::vmo& bootdata() const { return bootdata_; }
 
-    // Close the socket whose ownership was handed to this SuspendContext.
-    void CloseSocket() { socket_.reset(); }
-
 private:
     fbl::RefPtr<SuspendTask> task_;
 
@@ -74,9 +70,6 @@ private:
     // suspend flags
     uint32_t sflags_ = 0u;
 
-    // socket to notify on for 'dm reboot' and 'dm poweroff'
-    zx::socket socket_;
-
     // mexec arguments
     zx::vmo kernel_;
     zx::vmo bootdata_;
@@ -184,7 +177,6 @@ public:
                                    const fuchsia_device_manager_DeviceComponent* components,
                                    size_t components_count, uint32_t coresident_device_index);
 
-    zx_status_t DmCommand(size_t len, const char* cmd);
     void DmMexec(zx::vmo kernel, zx::vmo bootdata);
 
     void HandleNewDevice(const fbl::RefPtr<Device>& dev);
@@ -208,7 +200,6 @@ public:
     void set_loader_service(DevhostLoaderService* loader_service) {
         loader_service_ = loader_service;
     }
-    void set_dmctl_socket(zx::socket dmctl_socket) { dmctl_socket_ = std::move(dmctl_socket); }
 
     fbl::DoublyLinkedList<Driver*, Driver::Node>& drivers() { return drivers_; }
     const fbl::DoublyLinkedList<Driver*, Driver::Node>& drivers() const { return drivers_; }
@@ -248,10 +239,6 @@ private:
     bool system_loaded_ = false;
     DevhostLoaderService* loader_service_ = nullptr;
 
-    // This socket is used by DmPrintf for output, and DmPrintf can be called in
-    // the context of a const member function, therefore it is also const. Given
-    // that, we must make dmctl_socket_ mutable.
-    mutable zx::socket dmctl_socket_;
 
     // Services offered to the rest of the system.
     svc::Outgoing outgoing_services_;
@@ -318,8 +305,6 @@ bool driver_is_bindable(const Driver* drv, uint32_t protocol_id,
 // Path to driver that should be bound to components of composite devices
 extern const char* kComponentDriverPath;
 
-zx_status_t fidl_DmCommand(void* ctx, zx_handle_t raw_log_socket, const char* command_data,
-                           size_t command_size, fidl_txn_t* txn);
 zx_status_t fidl_DmMexec(void* ctx, zx_handle_t raw_kernel, zx_handle_t raw_bootdata);
 zx_status_t fidl_DirectoryWatch(void* ctx, uint32_t mask, uint32_t options,
                                 zx_handle_t raw_watcher, fidl_txn_t* txn);
diff --git a/zircon/system/core/devmgr/devcoordinator/device.cpp b/zircon/system/core/devmgr/devcoordinator/device.cpp
index 14c26330150bea91ef1466d0231b6b67a1dd699d..ea89efe9c64fa019ea2c56594539f1adddeec1b4 100644
--- a/zircon/system/core/devmgr/devcoordinator/device.cpp
+++ b/zircon/system/core/devmgr/devcoordinator/device.cpp
@@ -321,7 +321,6 @@ static const fuchsia_device_manager_Coordinator_ops_t fidl_ops = {
     .PublishMetadata = fidl_PublishMetadata,
     .AddCompositeDevice = fidl_AddCompositeDevice,
 
-    .DmCommand = fidl_DmCommand,
     .DmMexec = fidl_DmMexec,
     .DirectoryWatch = fidl_DirectoryWatch,
 };
diff --git a/zircon/system/core/devmgr/dmctl/dmctl.cpp b/zircon/system/core/devmgr/dmctl/dmctl.cpp
index 97263d83a5db0479b50b9ed6a556ee686871d2b8..bf1b65f271f550d42acb836e96eb3384e3d8551e 100644
--- a/zircon/system/core/devmgr/dmctl/dmctl.cpp
+++ b/zircon/system/core/devmgr/dmctl/dmctl.cpp
@@ -18,7 +18,7 @@
 namespace {
 
 class Dmctl;
-using DmctlBase = ddk::Device<Dmctl, ddk::Messageable, ddk::Writable>;
+using DmctlBase = ddk::Device<Dmctl, ddk::Messageable>;
 
 class Dmctl : public DmctlBase {
 public:
@@ -48,36 +48,6 @@ void Dmctl::DdkRelease() {
     abort();
 }
 
-zx_status_t Dmctl::DdkWrite(const void* buf, size_t count, zx_off_t off, size_t* actual) {
-    const zx::channel& rpc = *zxdev()->rpc;
-    zx_status_t status, call_status;
-    status = fuchsia_device_manager_CoordinatorDmCommand(
-        rpc.get(), ZX_HANDLE_INVALID, static_cast<const char*>(buf), count, &call_status);
-    if (status != ZX_OK) {
-        return status;
-    } else if (call_status != ZX_OK) {
-        return call_status;
-    }
-    *actual = count;
-    return ZX_OK;
-}
-
-static zx_status_t fidl_ExecuteCommand(void* ctx, zx_handle_t raw_log_socket,
-                                       const char* command_data, size_t command_size,
-                                       fidl_txn_t* txn) {
-    zx::socket log_socket(raw_log_socket);
-    auto zxdev = static_cast<zx_device_t*>(ctx);
-    const zx::channel& rpc = *zxdev->rpc;
-
-    zx_status_t status, call_status;
-    status = fuchsia_device_manager_CoordinatorDmCommand(rpc.get(), log_socket.release(),
-                                                         command_data, command_size, &call_status);
-    if (status == ZX_OK) {
-        status = call_status;
-    }
-    return fuchsia_device_manager_ExternalControllerExecuteCommand_reply(txn, status);
-}
-
 static zx_status_t fidl_PerformMexec(void* ctx, zx_handle_t raw_kernel, zx_handle_t raw_bootdata) {
     zx::vmo kernel(raw_kernel);
     zx::vmo bootdata(raw_bootdata);
@@ -89,7 +59,6 @@ static zx_status_t fidl_PerformMexec(void* ctx, zx_handle_t raw_kernel, zx_handl
 }
 
 static fuchsia_device_manager_ExternalController_ops_t fidl_ops = {
-    .ExecuteCommand = fidl_ExecuteCommand,
     .PerformMexec = fidl_PerformMexec,
 };
 
diff --git a/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl b/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl
index 3178b1d6ba295002c27c26b67ac395c105ed153f..c6e224ef55c4ac03b0c308a7d58c18f6df2a9e78 100644
--- a/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl
+++ b/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl
@@ -34,9 +34,6 @@ const uint32 DEVICE_ARGS_MAX = 1024;
 /// Maximum number of bytes in a metadata payload
 const uint32 METADATA_MAX = 4096;
 
-/// Maximum number of bytes in a command string
-const uint32 COMMAND_MAX = 1024;
-
 /// Maximum number of properties that can be attached to a device
 const uint32 PROPERTIES_MAX = 256;
 
@@ -209,11 +206,6 @@ protocol Coordinator {
     // Special commands for implementing the dmctl device.
     // TODO(teisenbe): We should revisit how these are carried over.
 
-    /// Execute the given string command.  This is mostly used for accessing debug
-    /// interfaces, but also as a backdoor for plumbing that has not been fully
-    /// solved.
-    DmCommand(handle<socket>? log_socket, string:COMMAND_MAX? command)
-        -> (zx.status status);
 
     /// Perform an mexec with the given kernel and bootdata.
     /// See ZX-2069 for the thoughts on deprecating mexec.
diff --git a/zircon/system/fidl/fuchsia-device-manager/dmctl.fidl b/zircon/system/fidl/fuchsia-device-manager/dmctl.fidl
index 9d4df1ee2eff28ff251fe5f8eda0f4ffc152a041..d3d2c918ce115aef4bda08f3a041dbc1871b44cf 100644
--- a/zircon/system/fidl/fuchsia-device-manager/dmctl.fidl
+++ b/zircon/system/fidl/fuchsia-device-manager/dmctl.fidl
@@ -4,18 +4,10 @@
 
 library fuchsia.device.manager;
 
-using zx;
-
 /// Interface for requesting devmgr perform miscellaneous actions.
 /// These methods are all work-arounds that should go away eventually.
 [Layout = "Simple"]
 protocol ExternalController {
-    /// Execute the given string command.  This is mostly used for accessing debug
-    /// interfaces, but also as a backdoor for plumbing that has not been fully
-    /// solved.
-    ExecuteCommand(handle<socket>? log_socket, string:COMMAND_MAX? command)
-        -> (zx.status status);
-
     /// Perform an mexec with the given kernel and bootdata.
     /// See ZX-2069 for the thoughts on deprecating mexec.
     PerformMexec(handle<vmo> kernel, handle<vmo> bootdata);
diff --git a/zircon/third_party/uapp/dash/src/bltin/zircon.c b/zircon/third_party/uapp/dash/src/bltin/zircon.c
index 57f24734dfbf887a3bbb628933c1705b38e96c9e..d980bcbf0483a76d2d8d1daa1596bc81f9af5d08 100644
--- a/zircon/third_party/uapp/dash/src/bltin/zircon.c
+++ b/zircon/third_party/uapp/dash/src/bltin/zircon.c
@@ -479,66 +479,6 @@ static int print_dm_help() {
     return 0;
 }
 
-static int send_dmctl(const char* command, size_t length) {
-    int fd = open("/dev/misc/dmctl", O_WRONLY);
-    if (fd < 0) {
-        fprintf(stderr, "error: cannot open dmctl: %d\n", fd);
-        return fd;
-    }
-    zx_handle_t dmctl;
-    zx_status_t status = fdio_get_service_handle(fd, &dmctl);
-    if (status != ZX_OK) {
-        return -1;
-    }
-
-    if (length > fuchsia_device_manager_COMMAND_MAX) {
-        fprintf(stderr, "error: dmctl command longer than %u bytes: '%.*s'\n",
-                fuchsia_device_manager_COMMAND_MAX, (int)length, command);
-        return -1;
-    }
-
-    zx_handle_t local, remote;
-    if (zx_socket_create(0, &remote, &local) != ZX_OK) {
-        zx_handle_close(dmctl);
-        return -1;
-    }
-
-    zx_status_t call_status;
-    status = fuchsia_device_manager_ExternalControllerExecuteCommand(dmctl, remote, command,
-                                                                     length, &call_status);
-    remote = ZX_HANDLE_INVALID;
-    zx_handle_close(dmctl);
-    if (status != ZX_OK || call_status != ZX_OK) {
-        zx_handle_close(local);
-        return -1;
-    }
-
-    for (;;) {
-        char buf[32768];
-        size_t actual;
-        if ((status = zx_socket_read(local, 0, buf, sizeof(buf), &actual)) < 0) {
-            if (status == ZX_ERR_SHOULD_WAIT) {
-                zx_object_wait_one(local, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED,
-                                   ZX_TIME_INFINITE, NULL);
-                continue;
-            }
-            break;
-        }
-        size_t written = 0;
-        while (written < actual) {
-            ssize_t count = write(1, buf + written, actual - written);
-            if (count < 0) {
-                break;
-            } else {
-                written += count;
-            }
-        }
-    }
-    zx_handle_close(local);
-
-    return 0;
-}
-
 static const uint32_t kVmoBufferSize = 512*1024;
 
 typedef struct {
@@ -763,12 +703,13 @@ int zxc_dm(int argc, char** argv) {
                command_cmp("shutdown", argv[1], &command_length)) {
         return send_suspend(DEVICE_SUSPEND_FLAG_POWEROFF);
 
+    } else {
+        printf("Unknown command '%s'\n\n", argv[1]);
+        printf("Valid commands:\n");
+        print_dm_help();
     }
 
-    // Fallback to dmctl.
-    // TODO(edcoyne): all dmctl commands will eventually be deprecated and this
-    // will be removed.
-    return send_dmctl(argv[1], strlen(argv[1]));
+    return -1;
 }
 
 static char* join(char* buffer, size_t buffer_length, int argc, char** argv) {