diff --git a/zircon/system/uapp/BUILD.gn b/zircon/system/uapp/BUILD.gn
index 201716f53c1eeee7c3cbaf6d589ad2afc21d5f3c..6d0771b26f4af7f0ed931460dba1c927d72b58a2 100644
--- a/zircon/system/uapp/BUILD.gn
+++ b/zircon/system/uapp/BUILD.gn
@@ -20,6 +20,7 @@ group("uapp") {
     "crasher",
     "dd",
     "df",
+    "disk-inspect",
     "disk-pave",
     "display-test",
     "dlog",
diff --git a/zircon/system/uapp/disk-inspect/BUILD.gn b/zircon/system/uapp/disk-inspect/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..a63d2cdb1870bb92ee864426acfcb8b6e5f13dd7
--- /dev/null
+++ b/zircon/system/uapp/disk-inspect/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+executable("disk-inspect") {
+  sources = [
+    "main.cpp",
+  ]
+  deps = [
+    "$zx/system/ulib/disk-inspector",
+    "$zx/system/ulib/minfs",
+  ]
+}
diff --git a/zircon/system/uapp/disk-inspect/main.cpp b/zircon/system/uapp/disk-inspect/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b92daf2e7511d2a313a16d836de346648417f978
--- /dev/null
+++ b/zircon/system/uapp/disk-inspect/main.cpp
@@ -0,0 +1,98 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fcntl.h>
+#include <stdio.h>
+
+#include <fbl/unique_fd.h>
+#include <lib/disk-inspector/disk-inspector.h>
+#include <minfs/inspector.h>
+#include <zircon/status.h>
+
+namespace {
+
+// Processes various disk objects recursively starting from root object
+// and prints values/elements of the objects.
+void ProcessDiskObjects(std::unique_ptr<disk_inspector::DiskObject> obj, uint32_t num_tabs) {
+    if (obj == nullptr) return;
+
+    printf("\n");
+    for (uint32_t i = 0; i < num_tabs; i++) {
+        printf("\t");
+    }
+
+    printf("Name: %s", obj->GetName());
+    size_t num_elements = obj->GetNumElements();
+
+    // Non scalar types.
+    if (num_elements != 0) {
+        for (uint32_t i = 0; i < num_elements; i++) {
+            std::unique_ptr<disk_inspector::DiskObject> element = obj->GetElementAt(i);
+            ProcessDiskObjects(std::move(element), num_tabs + 1);
+        }
+        return;
+    }
+
+    const void* buffer;
+    size_t size;
+    obj->GetValue(&buffer,&size);
+
+    switch (size) {
+        case sizeof(uint64_t): {
+            const uint64_t *val = reinterpret_cast <const uint64_t*> (buffer);
+            printf(" Value:0x%lx\n", *val);
+        }
+        break;
+
+        case sizeof(uint32_t): {
+            const uint32_t *val = reinterpret_cast <const uint32_t*> (buffer);
+            printf(" Value:0x%x\n", *val);
+        }
+        break;
+
+        case sizeof(uint16_t): {
+            const uint16_t *val = reinterpret_cast <const uint16_t*> (buffer);
+            printf(" Value:0x%x\n", *val);
+        }
+        break;
+
+        case sizeof(uint8_t): {
+            const char *val = reinterpret_cast <const char*> (buffer);
+            printf(" Value:%c\n", *val);
+        }
+        break;
+
+        default:
+            ZX_ASSERT_MSG(false, "Unknown object size: %lu", size);
+    }
+}
+
+int Inspect(fbl::unique_fd fd) {
+    minfs::Inspector inspector = minfs::Inspector(std::move(fd));
+    std::unique_ptr<disk_inspector::DiskObject> root;
+
+    if (inspector.GetRoot(&root) == ZX_OK) {
+         ProcessDiskObjects(std::move(root), 0);
+         printf("\n");
+         return 0;
+    }
+    fprintf(stderr, "ERROR: GetRoot failed\n");
+    return -1;
+}
+
+}  // namespace
+
+int main(int argc, char** argv) {
+    if (argc < 2) {
+        fprintf(stderr, "usage: %s <device path>\n", argv[0]);
+        return -1;
+    }
+
+    fbl::unique_fd fd(open(argv[1], O_RDONLY));
+     if (fd.get() < 0) {
+        fprintf(stderr, "ERROR: Failed to open device: %d\n", fd.get());
+        return -1;
+    }
+    return Inspect(std::move(fd));
+}