diff --git a/cambridge_migration_config/config/install/migrate_plus.migration.upgrade_d7_paragraphs_link_block.yml b/cambridge_migration_config/config/install/migrate_plus.migration.upgrade_d7_paragraphs_link_block.yml
index 6dbaab36d1cefefdc007063405d1a6b8e216d4f8..016817eefc769bc5d63b70ec8027a9201f890105 100644
--- a/cambridge_migration_config/config/install/migrate_plus.migration.upgrade_d7_paragraphs_link_block.yml
+++ b/cambridge_migration_config/config/install/migrate_plus.migration.upgrade_d7_paragraphs_link_block.yml
@@ -1,5 +1,5 @@
 langcode: en
-status: true
+status: false
 dependencies: {  }
 id: upgrade_d7_paragraphs_link_block
 class: Drupal\migrate\Plugin\Migration
diff --git a/cambridge_migrations.services.yml b/cambridge_migrations.services.yml
index 991996955d1ebf0285221db2ea9c36dd242ec1d0..cc08c86b99fb407177091e91235d3bd0c1ea1962 100644
--- a/cambridge_migrations.services.yml
+++ b/cambridge_migrations.services.yml
@@ -1,6 +1,12 @@
 services:
-  cambridge_migrations.commands:
-    class: \Drupal\cambridge_migrations\Drush\Commands\MigrateTextBlocksCommand
+  cambridge_migrations.text_blocks_command:
+    class: Drupal\cambridge_migrations\Drush\Commands\MigrateTextBlocksCommand
+    arguments: ['@entity_type.manager', '@file_system', '@database']
+    tags:
+      - { name: drush.command }
+  
+  cambridge_migrations.link_blocks_command:
+    class: Drupal\cambridge_migrations\Drush\Commands\MigrateLinkBlocksCommand
     arguments: ['@entity_type.manager', '@file_system', '@database']
     tags:
       - { name: drush.command }
diff --git a/drush.services.yml b/drush.services.yml
index a810dea355dfcc6912aa798aaec203ff5c5801c6..cc08c86b99fb407177091e91235d3bd0c1ea1962 100644
--- a/drush.services.yml
+++ b/drush.services.yml
@@ -1,6 +1,12 @@
 services:
-  cambridge_migrations.commands:
+  cambridge_migrations.text_blocks_command:
     class: Drupal\cambridge_migrations\Drush\Commands\MigrateTextBlocksCommand
     arguments: ['@entity_type.manager', '@file_system', '@database']
     tags:
       - { name: drush.command }
+  
+  cambridge_migrations.link_blocks_command:
+    class: Drupal\cambridge_migrations\Drush\Commands\MigrateLinkBlocksCommand
+    arguments: ['@entity_type.manager', '@file_system', '@database']
+    tags:
+      - { name: drush.command }
diff --git a/src/Drush/Commands/MigrateLinkBlocksCommand.php b/src/Drush/Commands/MigrateLinkBlocksCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..432789657115d7240a75785ca75fbe0f7ddd0883
--- /dev/null
+++ b/src/Drush/Commands/MigrateLinkBlocksCommand.php
@@ -0,0 +1,267 @@
+<?php
+
+namespace Drupal\cambridge_migrations\Drush\Commands;
+
+use Drush\Commands\DrushCommands;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\File\FileSystemInterface;
+use Drupal\Core\Database\Connection;
+use Drupal\paragraphs\Entity\Paragraph;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Drush command for migrating D7 Link block paragraphs to D10 Text paragraphs.
+ *
+ * Each D7 Link block paragraph has:
+ *   - field_paragraph_heading (plain text, single entry)
+ *   - field_paragraph_links (link field, unlimited entries)
+ *
+ * This command converts each D7 Link block into a D10 Text paragraph.
+ * The resulting content is structured as:
+ *   - If present, the heading is output as an <h2> element.
+ *   - Below the heading, the links are rendered as an unordered list.
+ *
+ * To run:
+ *   ddev drush cambridge:migrate-link-blocks
+ */
+class MigrateLinkBlocksCommand extends DrushCommands {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The file system service.
+   *
+   * @var \Drupal\Core\File\FileSystemInterface
+   */
+  protected $fileSystem;
+
+  /**
+   * Old (source) DB connection.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $sourceDb;
+
+  /**
+   * New (target) DB connection.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $targetDb;
+
+  /**
+   * Constructs a new MigrateLinkBlocksCommand object.
+   */
+  public function __construct(
+    EntityTypeManagerInterface $entity_type_manager,
+    FileSystemInterface $file_system,
+    Connection $database
+  ) {
+    parent::__construct();
+    $this->entityTypeManager = $entity_type_manager;
+    $this->fileSystem = $file_system;
+    // Assumes your D7 database connection is configured under the key 'migrate'.
+    $this->sourceDb = \Drupal\Core\Database\Database::getConnection('default', 'migrate');
+    $this->targetDb = \Drupal\Core\Database\Database::getConnection('default', 'default');
+  }
+
+  /**
+   * Clean up HTML content.
+   *
+   * @param string $content
+   *   The raw content.
+   *
+   * @return string
+   *   The cleaned content.
+   */
+  protected function cleanContent($content) {
+    if (empty($content)) {
+      return $content;
+    }
+    // Remove empty <p> tags.
+    $content = preg_replace('/<p>\s*<\/p>/', '', $content);
+    // Collapse multiple blank lines.
+    $content = preg_replace('/(\r?\n){2,}/', "\n\n", $content);
+    return trim($content);
+  }
+
+  /**
+   * Remove content teaser paragraphs from a node.
+   *
+   * This is used to clear out any existing content teasers from a node
+   * before adding new paragraph items.
+   *
+   * @param \Drupal\node\NodeInterface $node
+   *   The node from which to remove content teaser paragraphs.
+   */
+  protected function removeContentTeasers($node) {
+    if (!$node->hasField('field_paragraph')) {
+      return;
+    }
+    $paragraphs = $node->get('field_paragraph')->referencedEntities();
+    $updated_paragraphs = [];
+    $removed_count = 0;
+    foreach ($paragraphs as $paragraph) {
+      if ($paragraph->getType() !== 'content_teaser') {
+        $updated_paragraphs[] = [
+          'target_id' => $paragraph->id(),
+          'target_revision_id' => $paragraph->getRevisionId(),
+        ];
+      }
+      else {
+        $paragraph->delete();
+        $removed_count++;
+      }
+    }
+    if ($removed_count > 0) {
+      $node->set('field_paragraph', $updated_paragraphs);
+      $node->save();
+      $this->logger()->notice(dt('Removed @count content teaser paragraph(s) from node @nid', [
+        '@count' => $removed_count,
+        '@nid' => $node->id(),
+      ]));
+    }
+  }
+
+  /**
+   * Migrate D7 Link block paragraphs to D10 Text paragraphs.
+   *
+   * @command cambridge:migrate-link-blocks
+   * @aliases cm-link-blocks
+   */
+  public function migrateLinkBlocks() {
+    try {
+      // Query the D7 database for Link block paragraphs.
+      $query = $this->sourceDb->select('paragraphs_item', 'p')
+        ->fields('p', ['item_id', 'bundle', 'field_name'])
+        ->condition('p.bundle', 'link_block');
+
+      // Join with the heading field.
+      $query->leftJoin('field_data_field_paragraph_heading', 'h',
+        'p.item_id = h.entity_id AND h.entity_type = :entity_type',
+        [':entity_type' => 'paragraphs_item']
+      );
+      $query->fields('h', ['field_paragraph_heading_value']);
+
+      // Join with the node reference field to get the parent node ID.
+      $query->leftJoin('field_data_field_content_items', 'n',
+        'p.item_id = n.field_content_items_value'
+      );
+      $query->fields('n', ['entity_id']);
+
+      $link_blocks = $query->execute()->fetchAll();
+      if (empty($link_blocks)) {
+        $this->logger()->warning(dt('No link blocks found to migrate.'));
+        return;
+      }
+
+      $success_count = 0;
+      $error_count = 0;
+
+      foreach ($link_blocks as $block) {
+        try {
+          // Skip if no node reference.
+          if (empty($block->entity_id)) {
+            $this->logger()->warning(dt('Skipping link block @id - no node reference found', [
+              '@id' => $block->item_id,
+            ]));
+            continue;
+          }
+
+          // Start building the content.
+          $content = '';
+          if (!empty($block->field_paragraph_heading_value)) {
+            $content .= '<h2>' . $block->field_paragraph_heading_value . '</h2>';
+          }
+
+          // Query for all links associated with this D7 Link block.
+          $links_query = $this->sourceDb->select('field_data_field_paragraph_links', 'l')
+            ->fields('l', ['field_paragraph_links_url', 'field_paragraph_links_title'])
+            ->condition('l.entity_id', $block->item_id)
+            ->orderBy('l.delta', 'ASC');
+          $links = $links_query->execute()->fetchAll();
+
+          if (!empty($links)) {
+            // Render each link as an unordered list.
+            $links_output = '<ul>';
+            foreach ($links as $link) {
+              $url = $link->field_paragraph_links_url;
+              $title = !empty($link->field_paragraph_links_title) ? $link->field_paragraph_links_title : $url;
+              $links_output .= '<li><a href="' . $url . '">' . $title . '</a></li>';
+            }
+            $links_output .= '</ul>';
+            $content .= $links_output;
+          }
+
+          // Clean up the final content.
+          $content = $this->cleanContent($content);
+
+          // Load the corresponding D10 node.
+          $node = $this->entityTypeManager->getStorage('node')->load($block->entity_id);
+          if (!$node) {
+            throw new \Exception("Node {$block->entity_id} not found in D10.");
+          }
+
+          // Remove content teasers before adding the new paragraph.
+          $this->removeContentTeasers($node);
+
+          // Create a new paragraph of type 'text' with the generated content.
+          $paragraph = Paragraph::create([
+            'type' => 'text',
+            'field_text' => [
+              'value' => $content,
+              'format' => 'filtered_html'
+            ],
+          ]);
+          $paragraph->save();
+
+          // Attach the new paragraph to the node’s field_paragraph.
+          $node->field_paragraph[] = [
+            'target_id' => $paragraph->id(),
+            'target_revision_id' => $paragraph->getRevisionId(),
+          ];
+          $node->save();
+
+          $success_count++;
+          $this->logger()->notice(dt('Successfully migrated link block @id to node @nid', [
+            '@id' => $block->item_id,
+            '@nid' => $block->entity_id,
+          ]));
+        }
+        catch (\Exception $e) {
+          $error_count++;
+          $this->logger()->error(dt('Error migrating link block @id: @message', [
+            '@id' => $block->item_id,
+            '@message' => $e->getMessage(),
+          ]));
+        }
+      }
+
+      $this->logger()->notice(dt('Migration complete. Successes: @success, Errors: @errors', [
+        '@success' => $success_count,
+        '@errors' => $error_count,
+      ]));
+    }
+    catch (\Exception $e) {
+      $this->logger()->error(dt('Migration failed: @message', [
+        '@message' => $e->getMessage(),
+      ]));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('entity_type_manager'),
+      $container->get('file_system'),
+      $container->get('database')
+    );
+  }
+}