Skip to main content

Media Upload & Attachments

Overview

wp media import lets you upload files to the Media Library from the command line, attach them to posts, set metadata, and automate high-volume media workflows without wp-admin.

Understanding Media Import Workflows

With WP-CLI, you can:

  • Import local files from your server
  • Import remote assets directly from URLs
  • Bulk upload entire folders with globs
  • Attach files to posts/pages during import
  • Set SEO metadata (title, alt, caption, desc) at upload time
  • Return IDs for scripts using --porcelain

Importing Media Files

Import a Single Local File

# Import one file
wp media import ./images/logo.png

Example output:

Imported file './images/logo.png' as attachment ID 345.
Success: Imported 1 of 1 items.

Import from a Remote URL

# Import remote file directly
wp media import https://example.com/banner.jpg

# Import and attach to a post
wp media import https://cdn.example.com/hero.jpg --post_id=77
Remote Import Safety

Only import from trusted sources. Remote URLs can fail, redirect, or serve unexpected file types.

Bulk Import Multiple Files

# Import all JPG files from a folder
wp media import ./images/*.jpg

# Import mixed file types
wp media import ./assets/*.{jpg,png,webp,pdf}

Use case: Content migrations and product catalog uploads.

Import with Metadata

# Set metadata on import
wp media import ./images/team.jpg \
--title="Team Photo" \
--alt="Our team standing in office" \
--caption="Company team photo" \
--desc="About page team image"

Why this matters: Improves accessibility and keeps media records clean.

# Attach to a post and set as featured image
wp media import ./images/post-thumb.jpg --post_id=77 --featured_image

Common workflow: Pair with wp post create in publication scripts.

Output and Scripting Modes

Return Attachment IDs Only

# Prints attachment ID only (ideal for scripts)
wp media import ./images/logo.png --porcelain

You can capture the ID for downstream commands:

ATTACHMENT_ID=$(wp media import ./images/logo.png --porcelain)
wp post meta add 77 _thumbnail_id "$ATTACHMENT_ID"

Keep Original File and Timestamp Behavior

# Skip file copy into uploads directory
wp media import ./images/large-export.jpg --skip-copy

# Preserve original file modified time
wp media import ./images/legacy-photo.jpg --preserve-filetime

Use these options carefully and only when the storage strategy requires them.

Working with Attachments

List Existing Media Items

# List recent media with key fields
wp post list --post_type=attachment --posts_per_page=10 --fields=ID,post_title,post_mime_type,post_date

# Count total attachments
wp post list --post_type=attachment --format=count

Get Attachment Details

# Get attachment metadata
wp post get 345 --field=post_title
wp post meta get 345 _wp_attachment_image_alt
wp post meta get 345 _wp_attached_file

Attach Existing Media to a Different Post

# Re-attach media by updating parent
wp post update 345 --post_parent=120

This is useful when imported files were not attached during migration.

Real-World Scenarios

Scenario 1: Migrate Local Media Folder

#!/bin/bash
# import-media-batch.sh

wp media import ./migration-images/*.{jpg,png,webp} --porcelain > imported-ids.txt
echo "Imported $(wc -l < imported-ids.txt) files"

Scenario 2: Import and Attach Product Images

#!/bin/bash
# attach-product-images.sh

PRODUCT_ID=245

wp media import ./products/sku-245-main.jpg --post_id=$PRODUCT_ID --featured_image
wp media import ./products/sku-245-gallery-*.jpg --post_id=$PRODUCT_ID

Scenario 3: Remote CDN Pull During Content Creation

# Create draft post
POST_ID=$(wp post create --post_type=post --post_title="Launch Update" --post_status=draft --porcelain)

# Import remote hero image and set featured image
wp media import https://cdn.example.com/launch-hero.jpg --post_id=$POST_ID --featured_image

Best Practices

1. Add Alt Text During Import

wp media import ./images/product.jpg --alt="Blue ceramic coffee mug"

2. Use --porcelain for Automation

ID=$(wp media import ./images/header.jpg --porcelain)
echo "Imported attachment ID: $ID"

3. Run Large Imports in screen or tmux

screen -S media-import
wp media import ./bulk/*.jpg

4. Validate File Paths Before Import

ls -lah ./images/
wp media import ./images/*.png

5. Batch During Low-Traffic Windows

Large imports can increase disk I/O and background image processing load.

Troubleshooting

Import Fails with File/Permission Errors

# Verify file exists
ls -lah ./images/logo.png

# Check uploads path permissions
ls -lah wp-content/uploads/

Remote URL Import Fails

# Check URL accessibility first
curl -I https://example.com/banner.jpg

# Retry import
wp media import https://example.com/banner.jpg

Imported but Not Attached to Post

# Re-attach imported media
wp post update 345 --post_parent=77

Quick Reference

Essential Commands

# Basic imports
wp media import <file>
wp media import <url>
wp media import ./images/*.jpg

# Metadata and attachment
wp media import <file> --title="Title" --alt="Alt text"
wp media import <file> --post_id=77
wp media import <file> --post_id=77 --featured_image

# Scripting options
wp media import <file> --porcelain
wp media import <file> --skip-copy
wp media import <file> --preserve-filetime

Comparison: WP-CLI vs wp-admin

TaskWP-CLIwp-admin
Bulk Upload 500 Images✅ Fast via glob/script⚠️ Manual batches
Attach During Import✅ Native flags⚠️ Manual assignment
Automation Ready✅ Fully scriptable❌ Manual workflow
Remote URL Import✅ Native⚠️ Requires custom steps
Visual Browsing❌ Terminal only✅ Best for review
Key Takeaway

Use WP-CLI for speed, scale, and automation. Use wp-admin when you need visual inspection and manual editorial review.

Next Steps