diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1311,6 +1311,7 @@
     'HarbormasterManagementRestartWorkflow' => 'applications/harbormaster/management/HarbormasterManagementRestartWorkflow.php',
     'HarbormasterManagementUpdateWorkflow' => 'applications/harbormaster/management/HarbormasterManagementUpdateWorkflow.php',
     'HarbormasterManagementWorkflow' => 'applications/harbormaster/management/HarbormasterManagementWorkflow.php',
+    'HarbormasterManagementWriteLogWorkflow' => 'applications/harbormaster/management/HarbormasterManagementWriteLogWorkflow.php',
     'HarbormasterMessageType' => 'applications/harbormaster/engine/HarbormasterMessageType.php',
     'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php',
     'HarbormasterOtherBuildStepGroup' => 'applications/harbormaster/stepgroup/HarbormasterOtherBuildStepGroup.php',
@@ -6614,6 +6615,7 @@
     'HarbormasterManagementRestartWorkflow' => 'HarbormasterManagementWorkflow',
     'HarbormasterManagementUpdateWorkflow' => 'HarbormasterManagementWorkflow',
     'HarbormasterManagementWorkflow' => 'PhabricatorManagementWorkflow',
+    'HarbormasterManagementWriteLogWorkflow' => 'HarbormasterManagementWorkflow',
     'HarbormasterMessageType' => 'Phobject',
     'HarbormasterObject' => 'HarbormasterDAO',
     'HarbormasterOtherBuildStepGroup' => 'HarbormasterBuildStepGroup',
diff --git a/src/applications/harbormaster/management/HarbormasterManagementWriteLogWorkflow.php b/src/applications/harbormaster/management/HarbormasterManagementWriteLogWorkflow.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/management/HarbormasterManagementWriteLogWorkflow.php
@@ -0,0 +1,62 @@
+<?php
+
+final class HarbormasterManagementWriteLogWorkflow
+  extends HarbormasterManagementWorkflow {
+
+  protected function didConstruct() {
+    $this
+      ->setName('write-log')
+      ->setExamples('**write-log** --target __id__ [__options__]')
+      ->setSynopsis(pht('Write a new Harbormaster build log.'))
+      ->setArguments(
+        array(
+          array(
+            'name' => 'target',
+            'param' => 'id',
+            'help' => pht(
+              'Build Target ID to attach the log to.'),
+          ),
+        ));
+  }
+
+  public function execute(PhutilArgumentParser $args) {
+    $viewer = $this->getViewer();
+
+    $target_id = $args->getArg('target');
+    if (!$target_id) {
+      throw new PhutilArgumentUsageException(
+        pht('Choose a build target to attach the log to with "--target".'));
+    }
+
+    $target = id(new HarbormasterBuildTargetQuery())
+      ->setViewer($viewer)
+      ->withIDs(array($target_id))
+      ->executeOne();
+    if (!$target) {
+      throw new PhutilArgumentUsageException(
+        pht(
+          'Unable to load build target "%s".',
+          $target_id));
+    }
+
+
+    $log = HarbormasterBuildLog::initializeNewBuildLog($target);
+    $log->openBuildLog();
+
+    echo tsprintf(
+      "%s\n",
+      pht('Reading log from stdin...'));
+
+    $content = file_get_contents('php://stdin');
+    $log->append($content);
+
+    $log->closeBuildLog();
+
+    echo tsprintf(
+      "%s\n",
+      pht('Done.'));
+
+    return 0;
+  }
+
+}