<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>WordPress Security &amp; Maintenance Archives - WP-CLI Mastery</title>
	<atom:link href="https://wpclimastery.com/blog/category/wordpress-security-maintenance/feed/" rel="self" type="application/rss+xml" />
	<link>https://wpclimastery.com/blog/category/wordpress-security-maintenance/</link>
	<description>Automate WordPress Like a DevOps Pro.</description>
	<lastBuildDate>Mon, 24 Nov 2025 11:16:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wpclimastery.com/wp-content/uploads/2025/11/cropped-favicon-32x32.webp</url>
	<title>WordPress Security &amp; Maintenance Archives - WP-CLI Mastery</title>
	<link>https://wpclimastery.com/blog/category/wordpress-security-maintenance/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Automate WordPress Security Scanning and Monitoring with WP-CLI</title>
		<link>https://wpclimastery.com/blog/automate-wordpress-security-scanning-and-monitoring-with-wp-cli/</link>
		
		<dc:creator><![CDATA[Krasen]]></dc:creator>
		<pubDate>Sun, 15 Feb 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[WordPress Security & Maintenance]]></category>
		<category><![CDATA[automated security monitoring]]></category>
		<category><![CDATA[security scanning wordpress]]></category>
		<category><![CDATA[wordpress security automation]]></category>
		<category><![CDATA[wordpress vulnerability check]]></category>
		<category><![CDATA[wp-cli security]]></category>
		<guid isPermaLink="false">https://wpclimastery.com/?p=162</guid>

					<description><![CDATA[<p>WordPress security requires constant vigilance—manually checking for plugin vulnerabilities, monitoring file changes, detecting malware, verifying core integrity, and reviewing user permissions. Manual security audits happen infrequently and miss threats between...</p>
<p>The post <a href="https://wpclimastery.com/blog/automate-wordpress-security-scanning-and-monitoring-with-wp-cli/">Automate WordPress Security Scanning and Monitoring with WP-CLI</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>WordPress security requires constant vigilance—manually checking for plugin vulnerabilities, monitoring file changes, detecting malware, verifying core integrity, and reviewing user permissions. Manual security audits happen infrequently and miss threats between checks.</p>



<p>Automated WordPress security scanning with WP-CLI detects vulnerabilities continuously, monitors file integrity, checks for malware patterns, validates checksums, and alerts on suspicious changes. Run comprehensive security scans daily without manual intervention.</p>



<p>In this guide, you’ll build automated WordPress security monitoring systems using WP-CLI, from basic vulnerability checks to production-grade security automation that protects your sites 24/7.</p>



<h3 class="wp-block-heading" id="why-automate">Why Automate WordPress Security?</h3>



<p><a href="https://wordpress.org/support/article/hardening-wordpress/">Manual WordPress security checks</a> don’t provide continuous protection against evolving threats.</p>



<h4 class="wp-block-heading" id="manual-security-limitations">Manual Security Limitations</h4>



<p><strong>Infrequent checks</strong>: Manual audits happen weekly or monthly, leaving gaps.</p>



<p><strong>Human error</strong>: Manual reviews miss subtle security indicators.</p>



<p><strong>Time-consuming</strong>: Comprehensive security audits take hours per site.</p>



<p><strong>No real-time alerts</strong>: Breaches go undetected until the next manual check.</p>



<p><strong>Limited scope</strong>: Can’t check every file, user, and configuration regularly.</p>



<h4 class="wp-block-heading" id="automated-security-benefits">Automated Security Benefits</h4>



<p><strong>Continuous monitoring</strong>: Security checks run automatically every day.</p>



<p><strong>Instant alerts</strong>: Get notified immediately when threats are detected.</p>



<p><strong>Comprehensive coverage</strong>: Scan every file, plugin, theme, and configuration.</p>



<p><strong>Historical tracking</strong>: Log all security events for forensic analysis.</p>



<p><strong>Multi-site management</strong>: Monitor dozens of WordPress sites from one system.</p>



<p>According to <a href="https://sucuri.net/reports/2023-website-security-report/">Sucuri research</a>, automated security monitoring detects breaches 85% faster than manual audits.</p>



<h3 class="wp-block-heading" id="core-integrity">Core File Integrity Verification</h3>



<p>Detect unauthorized modifications to WordPress core files.</p>



<h4 class="wp-block-heading" id="checksum-verification">Checksum Verification</h4>



<div class="sourceCode" id="cb1">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a><span class="co"># verify-core-integrity.sh</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"WordPress Core Integrity Check"</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"==============================="</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a><span class="co"># Verify core file checksums</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a><span class="kw">if</span> <span class="ex">wp</span> core verify-checksums<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ Core files verified - no modifications detected"</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ ALERT: Core files modified or corrupted"</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Details:"</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true"></a>    <span class="ex">wp</span> core verify-checksums --format=json <span class="kw">|</span> <span class="ex">jq</span> -r <span class="st">'.[] | "  - \(.)"'</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true"></a>    <span class="co"># Send alert</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Core file integrity check failed on </span><span class="va">$(</span><span class="fu">hostname</span><span class="va">)</span><span class="st">"</span> <span class="kw">|</span> <span class="kw">\</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true"></a>        <span class="ex">mail</span> -s <span class="st">"WordPress Security Alert"</span> admin@example.com</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true"></a><span class="kw">fi</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="automated-daily-verification">Automated Daily Verification</h4>



<div class="sourceCode" id="cb2">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a><span class="co"># daily-integrity-check.sh</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a><span class="va">LOG_FILE=</span><span class="st">"/var/log/wp-security.log"</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true"></a><span class="fu">log()</span> <span class="kw">{</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"[</span><span class="va">$(</span><span class="fu">date</span> <span class="st">'+%Y-%m-%d %H:%M:%S'</span><span class="va">)</span><span class="st">] </span><span class="va">$@</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">tee</span> -a <span class="st">"</span><span class="va">$LOG_FILE</span><span class="st">"</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true"></a></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Starting core integrity check"</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true"></a></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true"></a><span class="co"># Check WordPress core</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true"></a><span class="kw">if</span> ! <span class="ex">wp</span> core verify-checksums <span class="op">2&gt;&amp;1</span> <span class="kw">|</span> <span class="fu">tee</span> -a <span class="st">"</span><span class="va">$LOG_FILE</span><span class="st">"</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"✗ Core integrity check FAILED"</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true"></a></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true"></a>    <span class="co"># Create detailed report</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true"></a>    <span class="kw">{</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"WordPress Core Integrity Failure"</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"================================="</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"Timestamp: </span><span class="va">$(</span><span class="fu">date</span><span class="va">)</span><span class="st">"</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"Server: </span><span class="va">$(</span><span class="fu">hostname</span><span class="va">)</span><span class="st">"</span></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"WordPress version: </span><span class="va">$(</span><span class="ex">wp</span> core version<span class="va">)</span><span class="st">"</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"Modified files:"</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true"></a>        <span class="ex">wp</span> core verify-checksums <span class="op">2&gt;&amp;1</span> <span class="kw">|</span> <span class="fu">grep</span> <span class="st">"^Error:"</span></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true"></a>    <span class="kw">}</span> <span class="kw">|</span> <span class="ex">mail</span> -s <span class="st">"URGENT: WordPress Core Modified"</span> security@example.com</span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true"></a></span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true"></a></span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"✓ Core integrity check passed"</span></span></code></pre>
</div>



<p>Learn about <a href="https://developer.wordpress.org/apis/wp-config-php/">WordPress file integrity</a>.</p>



<h3 class="wp-block-heading" id="vulnerability-detection">Plugin and Theme Vulnerability Detection</h3>



<p>Check for known security vulnerabilities in plugins and themes.</p>



<h4 class="wp-block-heading" id="wp-cli-vulnerability-scanner">WP-CLI Vulnerability Scanner</h4>



<div class="sourceCode" id="cb3">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a><span class="co"># scan-vulnerabilities.sh</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"WordPress Vulnerability Scan"</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"============================"</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true"></a><span class="co"># Check if WPScan CLI is available</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true"></a><span class="kw">if</span> ! <span class="bu">command</span> -v wpscan <span class="op">&amp;&gt;</span> /dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Installing WPScan..."</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true"></a>    <span class="ex">gem</span> install wpscan</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true"></a><span class="co"># Update WPScan database</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true"></a><span class="ex">wpscan</span> --update</span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true"></a></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true"></a><span class="co"># Scan WordPress installation</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true"></a><span class="va">SCAN_RESULTS=$(</span><span class="ex">wpscan</span> --url <span class="st">"</span><span class="va">$(</span><span class="ex">wp</span> option get siteurl<span class="va">)</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true"></a>    <span class="ex">--format</span> json <span class="kw">\</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true"></a>    <span class="ex">--random-user-agent</span> <span class="kw">\</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true"></a>    <span class="ex">--disable-tls-checks</span><span class="va">)</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true"></a></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true"></a><span class="co"># Parse vulnerabilities</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true"></a><span class="va">VULN_COUNT=$(</span><span class="bu">echo</span> <span class="st">"</span><span class="va">$SCAN_RESULTS</span><span class="st">"</span> <span class="kw">|</span> <span class="ex">jq</span> <span class="st">'.plugins | to_entries[] | select(.value.vulnerabilities | length &gt; 0) | .value.vulnerabilities | length'</span> <span class="kw">|</span> <span class="fu">awk</span> <span class="st">'{s+=$1} END {print s}'</span><span class="va">)</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true"></a></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$VULN_COUNT</span><span class="st">"</span> <span class="ot">-gt</span> 0<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ ALERT: </span><span class="va">$VULN_COUNT</span><span class="st"> vulnerabilities detected"</span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true"></a></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true"></a>    <span class="co"># Generate detailed report</span></span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"</span><span class="va">$SCAN_RESULTS</span><span class="st">"</span> <span class="kw">|</span> <span class="ex">jq</span> -r <span class="st">'.plugins | to_entries[] | select(.value.vulnerabilities | length &gt; 0) | "Plugin: \(.key)\nVulnerabilities:\n\(.value.vulnerabilities[] | "  - \(.title) (Severity: \(.vuln_type))\n    Fixed in: \(.fixed_in // "No fix available")\n")"'</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true"></a></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ No known vulnerabilities detected"</span></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true"></a><span class="kw">fi</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="check-plugin-updates-for-security-fixes">Check Plugin Updates for Security Fixes</h4>



<div class="sourceCode" id="cb4">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true"></a><span class="co"># check-security-updates.sh</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Checking for security updates..."</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true"></a><span class="co"># Get plugins with available updates</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true"></a><span class="va">UPDATES=$(</span><span class="ex">wp</span> plugin list --update=available --format=json<span class="va">)</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$UPDATES</span><span class="st">"</span> <span class="ot">!=</span> <span class="st">"[]"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Plugins with available updates:"</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"</span><span class="va">$UPDATES</span><span class="st">"</span> <span class="kw">|</span> <span class="ex">jq</span> -r <span class="st">'.[] | "- \(.name) (Current: \(.version), Available: \(.update_version))"'</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true"></a></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true"></a>    <span class="co"># Check update changelogs for security keywords</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Checking changelogs for security mentions..."</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true"></a></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"</span><span class="va">$UPDATES</span><span class="st">"</span> <span class="kw">|</span> <span class="ex">jq</span> -r <span class="st">'.[].name'</span> <span class="kw">|</span> <span class="kw">while</span> <span class="bu">read</span> <span class="va">PLUGIN</span>; <span class="kw">do</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true"></a>        <span class="va">CHANGELOG=$(</span><span class="ex">wp</span> plugin get <span class="st">"</span><span class="va">$PLUGIN</span><span class="st">"</span> --field=update_changelog <span class="op">2&gt;</span>/dev/null<span class="va">)</span></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true"></a></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true"></a>        <span class="kw">if</span> <span class="bu">echo</span> <span class="st">"</span><span class="va">$CHANGELOG</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">grep</span> -qi <span class="st">'security\|vulnerability\|xss\|sql injection\|exploit'</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true"></a>            <span class="bu">echo</span> <span class="st">"⚠ SECURITY UPDATE AVAILABLE: </span><span class="va">$PLUGIN</span><span class="st">"</span></span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true"></a>            <span class="bu">echo</span> <span class="st">"  Update immediately using: wp plugin update </span><span class="va">$PLUGIN</span><span class="st">"</span></span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true"></a>        <span class="kw">fi</span></span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true"></a>    <span class="kw">done</span></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ All plugins up to date"</span></span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true"></a><span class="kw">fi</span></span></code></pre>
</div>



<p>Learn about <a href="https://wordpress.org/support/article/hardening-wordpress/">WordPress security best practices</a>.</p>



<h3 class="wp-block-heading" id="file-monitoring">File Change Monitoring</h3>



<p>Detect unauthorized file modifications.</p>



<h4 class="wp-block-heading" id="file-integrity-database">File Integrity Database</h4>



<div class="sourceCode" id="cb5">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true"></a><span class="co"># create-file-baseline.sh - Create baseline of file checksums</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true"></a></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true"></a><span class="va">BASELINE_FILE=</span><span class="st">"/var/backups/wp-file-baseline.txt"</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true"></a><span class="va">WP_PATH=</span><span class="st">"/var/www/html"</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true"></a></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Creating file integrity baseline..."</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$WP_PATH</span><span class="st">"</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true"></a></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true"></a><span class="co"># Generate checksums for all WordPress files</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true"></a><span class="fu">find</span> . -type f <span class="kw">\</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true"></a>    <span class="ex">-not</span> -path <span class="st">"./wp-content/uploads/*"</span> <span class="kw">\</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true"></a>    <span class="ex">-not</span> -path <span class="st">"./wp-content/cache/*"</span> <span class="kw">\</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true"></a>    <span class="ex">-not</span> -path <span class="st">"./wp-content/backup/*"</span> <span class="kw">\</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true"></a>    <span class="ex">-exec</span> md5sum {} <span class="dt">\;</span> <span class="kw">|</span> <span class="fu">sort</span> <span class="op">&gt;</span> <span class="st">"</span><span class="va">$BASELINE_FILE</span><span class="st">"</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true"></a></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"✓ Baseline created: </span><span class="va">$BASELINE_FILE</span><span class="st">"</span></span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Total files: </span><span class="va">$(</span><span class="fu">wc</span> -l <span class="op">&lt;</span> <span class="va">$BASELINE_FILE)</span><span class="st">"</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="detect-file-changes">Detect File Changes</h4>



<div class="sourceCode" id="cb6">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true"></a><span class="co"># detect-file-changes.sh</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a><span class="va">BASELINE_FILE=</span><span class="st">"/var/backups/wp-file-baseline.txt"</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true"></a><span class="va">WP_PATH=</span><span class="st">"/var/www/html"</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true"></a><span class="va">REPORT_FILE=</span><span class="st">"/tmp/file-changes-</span><span class="va">$(</span><span class="fu">date</span> +%Y%m%d<span class="va">)</span><span class="st">.txt"</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true"></a></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="ot">!</span> <span class="ot">-f</span> <span class="st">"</span><span class="va">$BASELINE_FILE</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"ERROR: Baseline file not found. Run create-file-baseline.sh first."</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true"></a></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Scanning for file changes..."</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true"></a></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$WP_PATH</span><span class="st">"</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true"></a></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true"></a><span class="co"># Generate current checksums</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true"></a><span class="fu">find</span> . -type f <span class="kw">\</span></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true"></a>    <span class="ex">-not</span> -path <span class="st">"./wp-content/uploads/*"</span> <span class="kw">\</span></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true"></a>    <span class="ex">-not</span> -path <span class="st">"./wp-content/cache/*"</span> <span class="kw">\</span></span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true"></a>    <span class="ex">-not</span> -path <span class="st">"./wp-content/backup/*"</span> <span class="kw">\</span></span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true"></a>    <span class="ex">-exec</span> md5sum {} <span class="dt">\;</span> <span class="kw">|</span> <span class="fu">sort</span> <span class="op">&gt;</span> /tmp/current-checksums.txt</span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true"></a></span>
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true"></a><span class="co"># Compare with baseline</span></span>
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true"></a><span class="kw">{</span></span>
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"WordPress File Change Report"</span></span>
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"============================="</span></span>
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Date: </span><span class="va">$(</span><span class="fu">date</span><span class="va">)</span><span class="st">"</span></span>
<span id="cb6-29"><a href="#cb6-29" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb6-30"><a href="#cb6-30" aria-hidden="true"></a></span>
<span id="cb6-31"><a href="#cb6-31" aria-hidden="true"></a>    <span class="co"># Modified files</span></span>
<span id="cb6-32"><a href="#cb6-32" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Modified Files:"</span></span>
<span id="cb6-33"><a href="#cb6-33" aria-hidden="true"></a>    <span class="fu">comm</span> -13 <span class="st">"</span><span class="va">$BASELINE_FILE</span><span class="st">"</span> /tmp/current-checksums.txt <span class="kw">|</span> <span class="fu">awk</span> <span class="st">'{print $2}'</span> <span class="kw">|</span> <span class="kw">while</span> <span class="bu">read</span> <span class="va">file</span>; <span class="kw">do</span></span>
<span id="cb6-34"><a href="#cb6-34" aria-hidden="true"></a>        <span class="kw">if</span> <span class="fu">grep</span> -q <span class="st">"</span><span class="va">$file</span><span class="st">"</span> <span class="st">"</span><span class="va">$BASELINE_FILE</span><span class="st">"</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb6-35"><a href="#cb6-35" aria-hidden="true"></a>            <span class="bu">echo</span> <span class="st">"  MODIFIED: </span><span class="va">$file</span><span class="st">"</span></span>
<span id="cb6-36"><a href="#cb6-36" aria-hidden="true"></a>        <span class="kw">fi</span></span>
<span id="cb6-37"><a href="#cb6-37" aria-hidden="true"></a>    <span class="kw">done</span></span>
<span id="cb6-38"><a href="#cb6-38" aria-hidden="true"></a></span>
<span id="cb6-39"><a href="#cb6-39" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb6-40"><a href="#cb6-40" aria-hidden="true"></a></span>
<span id="cb6-41"><a href="#cb6-41" aria-hidden="true"></a>    <span class="co"># New files</span></span>
<span id="cb6-42"><a href="#cb6-42" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"New Files:"</span></span>
<span id="cb6-43"><a href="#cb6-43" aria-hidden="true"></a>    <span class="fu">comm</span> -13 <span class="st">"</span><span class="va">$BASELINE_FILE</span><span class="st">"</span> /tmp/current-checksums.txt <span class="kw">|</span> <span class="fu">awk</span> <span class="st">'{print $2}'</span> <span class="kw">|</span> <span class="kw">while</span> <span class="bu">read</span> <span class="va">file</span>; <span class="kw">do</span></span>
<span id="cb6-44"><a href="#cb6-44" aria-hidden="true"></a>        <span class="kw">if</span> ! <span class="fu">grep</span> -q <span class="st">"</span><span class="va">$file</span><span class="st">"</span> <span class="st">"</span><span class="va">$BASELINE_FILE</span><span class="st">"</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb6-45"><a href="#cb6-45" aria-hidden="true"></a>            <span class="bu">echo</span> <span class="st">"  ADDED: </span><span class="va">$file</span><span class="st">"</span></span>
<span id="cb6-46"><a href="#cb6-46" aria-hidden="true"></a>        <span class="kw">fi</span></span>
<span id="cb6-47"><a href="#cb6-47" aria-hidden="true"></a>    <span class="kw">done</span></span>
<span id="cb6-48"><a href="#cb6-48" aria-hidden="true"></a></span>
<span id="cb6-49"><a href="#cb6-49" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb6-50"><a href="#cb6-50" aria-hidden="true"></a></span>
<span id="cb6-51"><a href="#cb6-51" aria-hidden="true"></a>    <span class="co"># Deleted files</span></span>
<span id="cb6-52"><a href="#cb6-52" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Deleted Files:"</span></span>
<span id="cb6-53"><a href="#cb6-53" aria-hidden="true"></a>    <span class="fu">comm</span> -23 <span class="st">"</span><span class="va">$BASELINE_FILE</span><span class="st">"</span> /tmp/current-checksums.txt <span class="kw">|</span> <span class="fu">awk</span> <span class="st">'{print $2}'</span> <span class="kw">|</span> <span class="kw">while</span> <span class="bu">read</span> <span class="va">file</span>; <span class="kw">do</span></span>
<span id="cb6-54"><a href="#cb6-54" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"  DELETED: </span><span class="va">$file</span><span class="st">"</span></span>
<span id="cb6-55"><a href="#cb6-55" aria-hidden="true"></a>    <span class="kw">done</span></span>
<span id="cb6-56"><a href="#cb6-56" aria-hidden="true"></a></span>
<span id="cb6-57"><a href="#cb6-57" aria-hidden="true"></a><span class="kw">}</span> <span class="op">&gt;</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb6-58"><a href="#cb6-58" aria-hidden="true"></a></span>
<span id="cb6-59"><a href="#cb6-59" aria-hidden="true"></a><span class="co"># Check if changes detected</span></span>
<span id="cb6-60"><a href="#cb6-60" aria-hidden="true"></a><span class="va">CHANGE_COUNT=$(</span><span class="fu">cat</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">grep</span> -c <span class="st">"MODIFIED:\|ADDED:\|DELETED:"</span><span class="va">)</span></span>
<span id="cb6-61"><a href="#cb6-61" aria-hidden="true"></a></span>
<span id="cb6-62"><a href="#cb6-62" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$CHANGE_COUNT</span><span class="st">"</span> <span class="ot">-gt</span> 0<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb6-63"><a href="#cb6-63" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ ALERT: </span><span class="va">$CHANGE_COUNT</span><span class="st"> file changes detected"</span></span>
<span id="cb6-64"><a href="#cb6-64" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Report: </span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb6-65"><a href="#cb6-65" aria-hidden="true"></a></span>
<span id="cb6-66"><a href="#cb6-66" aria-hidden="true"></a>    <span class="co"># Email report</span></span>
<span id="cb6-67"><a href="#cb6-67" aria-hidden="true"></a>    <span class="ex">mail</span> -s <span class="st">"WordPress File Changes Detected"</span> admin@example.com <span class="op">&lt;</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb6-68"><a href="#cb6-68" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb6-69"><a href="#cb6-69" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ No file changes detected"</span></span>
<span id="cb6-70"><a href="#cb6-70" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb6-71"><a href="#cb6-71" aria-hidden="true"></a></span>
<span id="cb6-72"><a href="#cb6-72" aria-hidden="true"></a><span class="co"># Cleanup</span></span>
<span id="cb6-73"><a href="#cb6-73" aria-hidden="true"></a><span class="fu">rm</span> /tmp/current-checksums.txt</span></code></pre>
</div>



<h3 class="wp-block-heading" id="malware-scanning">Malware Pattern Scanning</h3>



<p>Detect common malware patterns in WordPress files.</p>



<h4 class="wp-block-heading" id="basic-malware-scanner">Basic Malware Scanner</h4>



<div class="sourceCode" id="cb7">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true"></a><span class="co"># scan-malware.sh - Detect common malware patterns</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true"></a><span class="va">WP_PATH=</span><span class="st">"/var/www/html"</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true"></a><span class="va">REPORT_FILE=</span><span class="st">"/tmp/malware-scan-</span><span class="va">$(</span><span class="fu">date</span> +%Y%m%d<span class="va">)</span><span class="st">.txt"</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"WordPress Malware Scan"</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"======================"</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true"></a><span class="co"># Suspicious patterns to check</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true"></a><span class="bu">declare</span> -a <span class="va">PATTERNS=(</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true"></a>    <span class="st">"eval(base64_decode"</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true"></a>    <span class="st">"eval(gzinflate"</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true"></a>    <span class="st">"eval(str_rot13"</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true"></a>    <span class="st">"system(</span><span class="dt">\$</span><span class="st">_"</span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true"></a>    <span class="st">"shell_exec"</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true"></a>    <span class="st">"passthru"</span></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true"></a>    <span class="st">"base64_decode.*eval"</span></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true"></a>    <span class="st">"FilesMan"</span></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true"></a>    <span class="st">"r57shell"</span></span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true"></a>    <span class="st">"c99shell"</span></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true"></a>    <span class="st">"WSO shell"</span></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true"></a>)</span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true"></a></span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true"></a><span class="kw">{</span></span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Malware Scan Report"</span></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"==================="</span></span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Date: </span><span class="va">$(</span><span class="fu">date</span><span class="va">)</span><span class="st">"</span></span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Path: </span><span class="va">$WP_PATH</span><span class="st">"</span></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true"></a></span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true"></a>    <span class="kw">for</span> <span class="ex">PATTERN</span> in <span class="st">"</span><span class="va">${PATTERNS[@]}</span><span class="st">"</span><span class="kw">;</span> <span class="kw">do</span></span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"Checking for: </span><span class="va">$PATTERN</span><span class="st">"</span></span>
<span id="cb7-34"><a href="#cb7-34" aria-hidden="true"></a></span>
<span id="cb7-35"><a href="#cb7-35" aria-hidden="true"></a>        <span class="va">MATCHES=$(</span><span class="fu">grep</span> -r -l -i <span class="st">"</span><span class="va">$PATTERN</span><span class="st">"</span> <span class="st">"</span><span class="va">$WP_PATH</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb7-36"><a href="#cb7-36" aria-hidden="true"></a>            <span class="ex">--exclude-dir</span>=wp-content/uploads <span class="kw">\</span></span>
<span id="cb7-37"><a href="#cb7-37" aria-hidden="true"></a>            <span class="ex">--exclude-dir</span>=wp-content/cache <span class="kw">\</span></span>
<span id="cb7-38"><a href="#cb7-38" aria-hidden="true"></a>            <span class="ex">--exclude-dir</span>=node_modules <span class="kw">\</span></span>
<span id="cb7-39"><a href="#cb7-39" aria-hidden="true"></a>            <span class="ex">--include</span>=<span class="st">"*.php"</span> <span class="op">2&gt;</span>/dev/null<span class="va">)</span></span>
<span id="cb7-40"><a href="#cb7-40" aria-hidden="true"></a></span>
<span id="cb7-41"><a href="#cb7-41" aria-hidden="true"></a>        <span class="kw">if</span><span class="bu"> [</span> <span class="ot">!</span> <span class="ot">-z</span> <span class="st">"</span><span class="va">$MATCHES</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb7-42"><a href="#cb7-42" aria-hidden="true"></a>            <span class="bu">echo</span> <span class="st">"✗ SUSPICIOUS: Files matching '</span><span class="va">$PATTERN</span><span class="st">':"</span></span>
<span id="cb7-43"><a href="#cb7-43" aria-hidden="true"></a>            <span class="bu">echo</span> <span class="st">"</span><span class="va">$MATCHES</span><span class="st">"</span> <span class="kw">|</span> <span class="kw">while</span> <span class="bu">read</span> <span class="va">file</span>; <span class="kw">do</span></span>
<span id="cb7-44"><a href="#cb7-44" aria-hidden="true"></a>                <span class="bu">echo</span> <span class="st">"  - </span><span class="va">$file</span><span class="st">"</span></span>
<span id="cb7-45"><a href="#cb7-45" aria-hidden="true"></a>            <span class="kw">done</span></span>
<span id="cb7-46"><a href="#cb7-46" aria-hidden="true"></a>            <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb7-47"><a href="#cb7-47" aria-hidden="true"></a>        <span class="kw">fi</span></span>
<span id="cb7-48"><a href="#cb7-48" aria-hidden="true"></a>    <span class="kw">done</span></span>
<span id="cb7-49"><a href="#cb7-49" aria-hidden="true"></a></span>
<span id="cb7-50"><a href="#cb7-50" aria-hidden="true"></a><span class="kw">}</span> <span class="op">&gt;</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb7-51"><a href="#cb7-51" aria-hidden="true"></a></span>
<span id="cb7-52"><a href="#cb7-52" aria-hidden="true"></a><span class="co"># Check if suspicious files found</span></span>
<span id="cb7-53"><a href="#cb7-53" aria-hidden="true"></a><span class="va">SUSPICIOUS_COUNT=$(</span><span class="fu">grep</span> -c <span class="st">"✗ SUSPICIOUS:"</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span> <span class="kw">||</span> <span class="bu">echo</span> 0<span class="va">)</span></span>
<span id="cb7-54"><a href="#cb7-54" aria-hidden="true"></a></span>
<span id="cb7-55"><a href="#cb7-55" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$SUSPICIOUS_COUNT</span><span class="st">"</span> <span class="ot">-gt</span> 0<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb7-56"><a href="#cb7-56" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ ALERT: Potential malware detected"</span></span>
<span id="cb7-57"><a href="#cb7-57" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Report: </span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb7-58"><a href="#cb7-58" aria-hidden="true"></a></span>
<span id="cb7-59"><a href="#cb7-59" aria-hidden="true"></a>    <span class="co"># Send alert</span></span>
<span id="cb7-60"><a href="#cb7-60" aria-hidden="true"></a>    <span class="ex">mail</span> -s <span class="st">"URGENT: Potential Malware Detected"</span> security@example.com <span class="op">&lt;</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb7-61"><a href="#cb7-61" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb7-62"><a href="#cb7-62" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ No malware patterns detected"</span></span>
<span id="cb7-63"><a href="#cb7-63" aria-hidden="true"></a><span class="kw">fi</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="check-for-suspicious-files">Check for Suspicious Files</h4>



<div class="sourceCode" id="cb8">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true"></a><span class="co"># check-suspicious-files.sh</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true"></a><span class="va">WP_PATH=</span><span class="st">"/var/www/html"</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Checking for suspicious files..."</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true"></a><span class="co"># Check for unusual file types in wp-content</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Checking for executable files in wp-content..."</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true"></a><span class="fu">find</span> <span class="st">"</span><span class="va">$WP_PATH</span><span class="st">/wp-content"</span> <span class="kw">\</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true"></a>    <span class="ex">-type</span> f <span class="kw">\</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true"></a>    <span class="dt">\(</span> <span class="ex">-name</span> <span class="st">"*.exe"</span> -o -name <span class="st">"*.sh"</span> -o -name <span class="st">"*.bat"</span> <span class="dt">\)</span> <span class="kw">\</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true"></a>    <span class="ex">-print</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true"></a></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true"></a><span class="co"># Check for PHP files in uploads directory</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Checking for PHP files in uploads..."</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true"></a><span class="fu">find</span> <span class="st">"</span><span class="va">$WP_PATH</span><span class="st">/wp-content/uploads"</span> -name <span class="st">"*.php"</span> -print</span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true"></a></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true"></a><span class="co"># Check for recently modified files (last 24 hours)</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Recently modified PHP files (last 24 hours)..."</span></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true"></a><span class="fu">find</span> <span class="st">"</span><span class="va">$WP_PATH</span><span class="st">"</span> -name <span class="st">"*.php"</span> -mtime -1 -type f -print</span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true"></a></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true"></a><span class="co"># Check for files with suspicious permissions</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Files with 777 permissions..."</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true"></a><span class="fu">find</span> <span class="st">"</span><span class="va">$WP_PATH</span><span class="st">"</span> -type f -perm 0777 -print</span></code></pre>
</div>



<p>Learn about <a href="https://blog.sucuri.net/2023/03/wordpress-malware-removal-guide.html">WordPress malware detection</a>.</p>



<h3 class="wp-block-heading" id="user-auditing">User Account Security Auditing</h3>



<p>Monitor user accounts for security issues.</p>



<h4 class="wp-block-heading" id="user-security-audit">User Security Audit</h4>



<div class="sourceCode" id="cb9">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true"></a><span class="co"># audit-users.sh</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true"></a></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"WordPress User Security Audit"</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"=============================="</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true"></a></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true"></a><span class="co"># Check for users with admin privileges</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Administrator Accounts:"</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true"></a><span class="ex">wp</span> user list --role=administrator --format=table --fields=ID,user_login,user_email,user_registered</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true"></a><span class="va">ADMIN_COUNT=$(</span><span class="ex">wp</span> user list --role=administrator --format=count<span class="va">)</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$ADMIN_COUNT</span><span class="st">"</span> <span class="ot">-gt</span> 3<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"⚠ WARNING: </span><span class="va">$ADMIN_COUNT</span><span class="st"> administrator accounts (recommended: 1-2)"</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true"></a></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true"></a></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true"></a><span class="co"># Check for weak usernames</span></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Checking for common/weak usernames..."</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true"></a><span class="va">WEAK_USERS=(</span><span class="st">"admin"</span> <span class="st">"administrator"</span> <span class="st">"root"</span> <span class="st">"test"</span> <span class="st">"demo"</span><span class="va">)</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true"></a></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true"></a><span class="kw">for</span> <span class="ex">USERNAME</span> in <span class="st">"</span><span class="va">${WEAK_USERS[@]}</span><span class="st">"</span><span class="kw">;</span> <span class="kw">do</span></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ex">wp</span> user get <span class="st">"</span><span class="va">$USERNAME</span><span class="st">"</span> <span class="op">&amp;&gt;</span>/dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✗ WARNING: Common username detected: </span><span class="va">$USERNAME</span><span class="st">"</span></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"  Recommended: Delete or rename this account"</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true"></a><span class="kw">done</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true"></a></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true"></a></span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true"></a><span class="co"># Check for inactive admin accounts</span></span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Inactive Administrator Accounts (no posts/pages):"</span></span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true"></a><span class="ex">wp</span> user list --role=administrator --format=json <span class="kw">|</span> <span class="kw">\</span></span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true"></a>    <span class="ex">jq</span> -r <span class="st">'.[] | select(.posts == "0") | "- \(.user_login) (registered: \(.user_registered))"'</span></span>
<span id="cb9-35"><a href="#cb9-35" aria-hidden="true"></a></span>
<span id="cb9-36"><a href="#cb9-36" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true"></a></span>
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true"></a><span class="co"># Check user capabilities</span></span>
<span id="cb9-39"><a href="#cb9-39" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Users with 'delete_users' capability:"</span></span>
<span id="cb9-40"><a href="#cb9-40" aria-hidden="true"></a><span class="ex">wp</span> user list --format=json <span class="kw">|</span> <span class="kw">\</span></span>
<span id="cb9-41"><a href="#cb9-41" aria-hidden="true"></a>    <span class="ex">jq</span> -r <span class="st">'.[] | select(.roles[] | contains("administrator")) | .user_login'</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="password-policy-check">Password Policy Check</h4>



<div class="sourceCode" id="cb10">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true"></a><span class="co"># check-password-policy.sh</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Password Policy Check"</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"===================="</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true"></a><span class="co"># This requires custom code to check password strength</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true"></a><span class="co"># WordPress doesn't expose password hashes via WP-CLI for security</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true"></a></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true"></a><span class="co"># Check for recent password changes</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Users who haven't changed password recently:"</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true"></a><span class="co"># This would require custom user meta tracking</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true"></a></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true"></a><span class="co"># Check for 2FA status (if plugin installed)</span></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true"></a><span class="kw">if</span> <span class="ex">wp</span> plugin is-installed two-factor<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"2FA Status:"</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true"></a>    <span class="ex">wp</span> user list --format=json <span class="kw">|</span> <span class="kw">\</span></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true"></a>        <span class="ex">jq</span> -r <span class="st">'.[] | "\(.user_login): \(if .two_factor_enabled then "Enabled" else "DISABLED" end)"'</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true"></a></span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true"></a><span class="co"># List users who can install plugins/themes</span></span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Users with plugin/theme installation privileges:"</span></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true"></a><span class="ex">wp</span> user list --role=administrator,editor --format=csv --fields=user_login,roles</span></code></pre>
</div>



<h3 class="wp-block-heading" id="security-report">Comprehensive Security Report</h3>



<p>Generate complete security assessment reports.</p>



<h4 class="wp-block-heading" id="master-security-script">Master Security Script</h4>



<div class="sourceCode" id="cb11">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true"></a><span class="co"># comprehensive-security-check.sh</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true"></a></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true"></a><span class="va">REPORT_FILE=</span><span class="st">"/tmp/wordpress-security-report-</span><span class="va">$(</span><span class="fu">date</span> +%Y%m%d<span class="va">)</span><span class="st">.txt"</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true"></a><span class="va">LOG_FILE=</span><span class="st">"/var/log/wp-security.log"</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true"></a></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true"></a><span class="fu">log()</span> <span class="kw">{</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"[</span><span class="va">$(</span><span class="fu">date</span> <span class="st">'+%Y-%m-%d %H:%M:%S'</span><span class="va">)</span><span class="st">] </span><span class="va">$@</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">tee</span> -a <span class="st">"</span><span class="va">$LOG_FILE</span><span class="st">"</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true"></a></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true"></a><span class="kw">{</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"WordPress Comprehensive Security Report"</span></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"========================================"</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Generated: </span><span class="va">$(</span><span class="fu">date</span><span class="va">)</span><span class="st">"</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Server: </span><span class="va">$(</span><span class="fu">hostname</span><span class="va">)</span><span class="st">"</span></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true"></a></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true"></a>    <span class="co"># Core integrity</span></span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"1. Core File Integrity"</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"----------------------"</span></span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ex">wp</span> core verify-checksums<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✓ PASS: Core files verified"</span></span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✗ FAIL: Core file modifications detected"</span></span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true"></a></span>
<span id="cb11-28"><a href="#cb11-28" aria-hidden="true"></a>    <span class="co"># Plugin security</span></span>
<span id="cb11-29"><a href="#cb11-29" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"2. Plugin Security"</span></span>
<span id="cb11-30"><a href="#cb11-30" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"------------------"</span></span>
<span id="cb11-31"><a href="#cb11-31" aria-hidden="true"></a>    <span class="va">PLUGIN_UPDATES=$(</span><span class="ex">wp</span> plugin list --update=available --format=count<span class="va">)</span></span>
<span id="cb11-32"><a href="#cb11-32" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Plugins needing updates: </span><span class="va">$PLUGIN_UPDATES</span><span class="st">"</span></span>
<span id="cb11-33"><a href="#cb11-33" aria-hidden="true"></a></span>
<span id="cb11-34"><a href="#cb11-34" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$PLUGIN_UPDATES</span><span class="st">"</span> <span class="ot">-eq</span> 0<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb11-35"><a href="#cb11-35" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✓ PASS: All plugins up to date"</span></span>
<span id="cb11-36"><a href="#cb11-36" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-37"><a href="#cb11-37" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"⚠ WARNING: Plugin updates available"</span></span>
<span id="cb11-38"><a href="#cb11-38" aria-hidden="true"></a>        <span class="ex">wp</span> plugin list --update=available --format=table --fields=name,version,update_version</span>
<span id="cb11-39"><a href="#cb11-39" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-40"><a href="#cb11-40" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb11-41"><a href="#cb11-41" aria-hidden="true"></a></span>
<span id="cb11-42"><a href="#cb11-42" aria-hidden="true"></a>    <span class="co"># Theme security</span></span>
<span id="cb11-43"><a href="#cb11-43" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"3. Theme Security"</span></span>
<span id="cb11-44"><a href="#cb11-44" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"-----------------"</span></span>
<span id="cb11-45"><a href="#cb11-45" aria-hidden="true"></a>    <span class="va">THEME_UPDATES=$(</span><span class="ex">wp</span> theme list --update=available --format=count<span class="va">)</span></span>
<span id="cb11-46"><a href="#cb11-46" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Themes needing updates: </span><span class="va">$THEME_UPDATES</span><span class="st">"</span></span>
<span id="cb11-47"><a href="#cb11-47" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb11-48"><a href="#cb11-48" aria-hidden="true"></a></span>
<span id="cb11-49"><a href="#cb11-49" aria-hidden="true"></a>    <span class="co"># User accounts</span></span>
<span id="cb11-50"><a href="#cb11-50" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"4. User Account Security"</span></span>
<span id="cb11-51"><a href="#cb11-51" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"------------------------"</span></span>
<span id="cb11-52"><a href="#cb11-52" aria-hidden="true"></a>    <span class="va">ADMIN_COUNT=$(</span><span class="ex">wp</span> user list --role=administrator --format=count<span class="va">)</span></span>
<span id="cb11-53"><a href="#cb11-53" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Administrator accounts: </span><span class="va">$ADMIN_COUNT</span><span class="st">"</span></span>
<span id="cb11-54"><a href="#cb11-54" aria-hidden="true"></a></span>
<span id="cb11-55"><a href="#cb11-55" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$ADMIN_COUNT</span><span class="st">"</span> <span class="ot">-gt</span> 3<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb11-56"><a href="#cb11-56" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"⚠ WARNING: Too many administrator accounts"</span></span>
<span id="cb11-57"><a href="#cb11-57" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-58"><a href="#cb11-58" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✓ PASS: Administrator count acceptable"</span></span>
<span id="cb11-59"><a href="#cb11-59" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-60"><a href="#cb11-60" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb11-61"><a href="#cb11-61" aria-hidden="true"></a></span>
<span id="cb11-62"><a href="#cb11-62" aria-hidden="true"></a>    <span class="co"># SSL/HTTPS check</span></span>
<span id="cb11-63"><a href="#cb11-63" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"5. SSL/HTTPS Configuration"</span></span>
<span id="cb11-64"><a href="#cb11-64" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"--------------------------"</span></span>
<span id="cb11-65"><a href="#cb11-65" aria-hidden="true"></a>    <span class="va">SITE_URL=$(</span><span class="ex">wp</span> option get siteurl<span class="va">)</span></span>
<span id="cb11-66"><a href="#cb11-66" aria-hidden="true"></a>    <span class="kw">if [[</span> <span class="st">"</span><span class="va">$SITE_URL</span><span class="st">"</span> <span class="ot">==</span> https://*<span class="kw"> ]]</span>; <span class="kw">then</span></span>
<span id="cb11-67"><a href="#cb11-67" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✓ PASS: HTTPS enabled"</span></span>
<span id="cb11-68"><a href="#cb11-68" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-69"><a href="#cb11-69" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✗ FAIL: Site not using HTTPS"</span></span>
<span id="cb11-70"><a href="#cb11-70" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-71"><a href="#cb11-71" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb11-72"><a href="#cb11-72" aria-hidden="true"></a></span>
<span id="cb11-73"><a href="#cb11-73" aria-hidden="true"></a>    <span class="co"># File permissions</span></span>
<span id="cb11-74"><a href="#cb11-74" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"6. File Permissions"</span></span>
<span id="cb11-75"><a href="#cb11-75" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"-------------------"</span></span>
<span id="cb11-76"><a href="#cb11-76" aria-hidden="true"></a>    <span class="va">INSECURE_FILES=$(</span><span class="fu">find</span> . -type f -perm 0777 <span class="kw">|</span> <span class="fu">wc</span> -l<span class="va">)</span></span>
<span id="cb11-77"><a href="#cb11-77" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Files with 777 permissions: </span><span class="va">$INSECURE_FILES</span><span class="st">"</span></span>
<span id="cb11-78"><a href="#cb11-78" aria-hidden="true"></a></span>
<span id="cb11-79"><a href="#cb11-79" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$INSECURE_FILES</span><span class="st">"</span> <span class="ot">-eq</span> 0<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb11-80"><a href="#cb11-80" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✓ PASS: No files with overly permissive permissions"</span></span>
<span id="cb11-81"><a href="#cb11-81" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-82"><a href="#cb11-82" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"⚠ WARNING: Insecure file permissions detected"</span></span>
<span id="cb11-83"><a href="#cb11-83" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-84"><a href="#cb11-84" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb11-85"><a href="#cb11-85" aria-hidden="true"></a></span>
<span id="cb11-86"><a href="#cb11-86" aria-hidden="true"></a>    <span class="co"># WordPress version</span></span>
<span id="cb11-87"><a href="#cb11-87" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"7. WordPress Version"</span></span>
<span id="cb11-88"><a href="#cb11-88" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"--------------------"</span></span>
<span id="cb11-89"><a href="#cb11-89" aria-hidden="true"></a>    <span class="va">CURRENT_VERSION=$(</span><span class="ex">wp</span> core version<span class="va">)</span></span>
<span id="cb11-90"><a href="#cb11-90" aria-hidden="true"></a>    <span class="va">LATEST_VERSION=$(</span><span class="ex">wp</span> core check-update --format=json <span class="kw">|</span> <span class="ex">jq</span> -r <span class="st">'.[0].version // empty'</span><span class="va">)</span></span>
<span id="cb11-91"><a href="#cb11-91" aria-hidden="true"></a></span>
<span id="cb11-92"><a href="#cb11-92" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Current version: </span><span class="va">$CURRENT_VERSION</span><span class="st">"</span></span>
<span id="cb11-93"><a href="#cb11-93" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Latest version: </span><span class="va">${LATEST_VERSION:-$CURRENT_VERSION}</span><span class="st">"</span></span>
<span id="cb11-94"><a href="#cb11-94" aria-hidden="true"></a></span>
<span id="cb11-95"><a href="#cb11-95" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="ot">-z</span> <span class="st">"</span><span class="va">$LATEST_VERSION</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb11-96"><a href="#cb11-96" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✓ PASS: WordPress is up to date"</span></span>
<span id="cb11-97"><a href="#cb11-97" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-98"><a href="#cb11-98" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"⚠ WARNING: WordPress update available"</span></span>
<span id="cb11-99"><a href="#cb11-99" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-100"><a href="#cb11-100" aria-hidden="true"></a></span>
<span id="cb11-101"><a href="#cb11-101" aria-hidden="true"></a><span class="kw">}</span> <span class="op">&gt;</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb11-102"><a href="#cb11-102" aria-hidden="true"></a></span>
<span id="cb11-103"><a href="#cb11-103" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Security report generated: </span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb11-104"><a href="#cb11-104" aria-hidden="true"></a></span>
<span id="cb11-105"><a href="#cb11-105" aria-hidden="true"></a><span class="co"># Email report</span></span>
<span id="cb11-106"><a href="#cb11-106" aria-hidden="true"></a><span class="ex">mail</span> -s <span class="st">"WordPress Security Report - </span><span class="va">$(</span><span class="fu">hostname</span><span class="va">)</span><span class="st">"</span> admin@example.com <span class="op">&lt;</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb11-107"><a href="#cb11-107" aria-hidden="true"></a></span>
<span id="cb11-108"><a href="#cb11-108" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"✓ Security report complete: </span><span class="va">$REPORT_FILE</span><span class="st">"</span></span></code></pre>
</div>



<h3 class="wp-block-heading" id="automated-scheduling">Automated Scheduling</h3>



<p>Run security scans automatically with cron.</p>



<h4 class="wp-block-heading" id="cron-configuration">Cron Configuration</h4>



<div class="sourceCode" id="cb12">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true"></a><span class="co"># Add to crontab: crontab -e</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true"></a><span class="co"># Daily core integrity check at 2 AM</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true"></a><span class="ex">0</span> 2 * * * /usr/local/bin/verify-core-integrity.sh <span class="op">&gt;&gt;</span> /var/log/wp-security.log <span class="op">2&gt;&amp;1</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true"></a><span class="co"># Daily vulnerability scan at 3 AM</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true"></a><span class="ex">0</span> 3 * * * /usr/local/bin/scan-vulnerabilities.sh <span class="op">&gt;&gt;</span> /var/log/wp-security.log <span class="op">2&gt;&amp;1</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true"></a></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true"></a><span class="co"># Daily file change detection at 4 AM</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true"></a><span class="ex">0</span> 4 * * * /usr/local/bin/detect-file-changes.sh <span class="op">&gt;&gt;</span> /var/log/wp-security.log <span class="op">2&gt;&amp;1</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true"></a></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true"></a><span class="co"># Weekly comprehensive security report (Mondays at 8 AM)</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true"></a><span class="ex">0</span> 8 * * 1 /usr/local/bin/comprehensive-security-check.sh</span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true"></a></span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true"></a><span class="co"># Monthly user audit (first day of month)</span></span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true"></a><span class="ex">0</span> 9 1 * * /usr/local/bin/audit-users.sh <span class="kw">|</span> <span class="ex">mail</span> -s <span class="st">"Monthly User Audit"</span> admin@example.com</span></code></pre>
</div>



<p>Learn about <a href="https://www.wordfence.com/learn/wordpress-security-best-practices/">WordPress security monitoring</a>.</p>



<h3 class="wp-block-heading" id="next-steps">Next Steps</h3>



<p>You now have automated WordPress security scanning and monitoring capabilities with WP-CLI.</p>



<h4 class="wp-block-heading" id="recommended-learning-path">Recommended Learning Path</h4>



<p><strong>Week 1</strong>: Core security</p>



<ul class="wp-block-list">
<li>Implement core integrity checks</li>



<li>Set up vulnerability scanning</li>



<li>Test alerting systems</li>
</ul>



<p><strong>Week 2</strong>: File monitoring</p>



<ul class="wp-block-list">
<li>Create file baselines</li>



<li>Configure change detection</li>



<li>Add malware scanning</li>
</ul>



<p><strong>Week 3</strong>: User security</p>



<ul class="wp-block-list">
<li>Audit user accounts</li>



<li>Check permissions</li>



<li>Implement password policies</li>
</ul>



<p><strong>Week 4</strong>: Automation</p>



<ul class="wp-block-list">
<li>Schedule all security checks</li>



<li>Configure comprehensive reports</li>



<li>Integrate with monitoring tools</li>
</ul>



<h4 class="wp-block-heading" id="advanced-topics">Advanced Topics</h4>



<ol class="wp-block-list">
<li><strong><a href="#">Intrusion Detection Systems</a></strong> &#8211; Advanced threat detection</li>



<li><strong><a href="#">Security Information and Event Management (SIEM)</a></strong> &#8211; Centralized security monitoring</li>



<li><strong><a href="#">Automated Incident Response</a></strong> &#8211; Automatic threat mitigation</li>
</ol>



<h4 class="wp-block-heading" id="get-more-resources">Get More Resources</h4>



<p><strong><a href="#">Download security scripts</a></strong> including:</p>



<ul class="wp-block-list">
<li>Complete scanning system</li>



<li>Monitoring tools</li>



<li>Report templates</li>
</ul>



<p><strong><a href="/#get-started">Join our email course</a></strong> for:</p>



<ul class="wp-block-list">
<li>Weekly WP-CLI tutorials</li>



<li>Security best practices</li>



<li>Threat response strategies</li>
</ul>



<h3 class="wp-block-heading" id="conclusion">Conclusion</h3>



<p>Automated WordPress security scanning with WP-CLI provides continuous protection against vulnerabilities, malware, and unauthorized changes—detecting threats before they compromise your sites.</p>



<p>What we covered:</p>



<p>✅ Core file integrity verification <br>✅ Plugin and theme vulnerability detection <br>✅ File change monitoring and alerting <br>✅ Malware pattern scanning <br>✅ User account security auditing <br>✅ Comprehensive automated security reports</p>



<p>Implement these security automation systems, and you’ll detect threats immediately—protecting WordPress sites 24/7 without constant manual monitoring.</p>



<p><strong>Ready for more?</strong> Learn <a href="#">incident response</a> or <a href="#">WordPress hardening</a>.</p>



<p><strong>Questions about WordPress security automation?</strong> Drop a comment below!</p>



<p><strong>Found this helpful?</strong> Share with other WordPress administrators.</p>
<p>The post <a href="https://wpclimastery.com/blog/automate-wordpress-security-scanning-and-monitoring-with-wp-cli/">Automate WordPress Security Scanning and Monitoring with WP-CLI</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Safe WordPress Update Automation with WP-CLI: Testing and Rollback</title>
		<link>https://wpclimastery.com/blog/safe-wordpress-update-automation-with-wp-cli-testing-and-rollback/</link>
		
		<dc:creator><![CDATA[Krasen]]></dc:creator>
		<pubDate>Mon, 05 Jan 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[WordPress Security & Maintenance]]></category>
		<category><![CDATA[automated wordpress maintenance]]></category>
		<category><![CDATA[safe wordpress updates]]></category>
		<category><![CDATA[update rollback wordpress]]></category>
		<category><![CDATA[wordpress update automation]]></category>
		<category><![CDATA[wp-cli updates]]></category>
		<guid isPermaLink="false">https://wpclimastery.com/?p=142</guid>

					<description><![CDATA[<p>Manually updating WordPress sites is tedious, but blindly automating updates without safety checks destroys sites when incompatible plugins break, themes conflict, or updates corrupt databases. One bad update at 3...</p>
<p>The post <a href="https://wpclimastery.com/blog/safe-wordpress-update-automation-with-wp-cli-testing-and-rollback/">Safe WordPress Update Automation with WP-CLI: Testing and Rollback</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Manually updating WordPress sites is tedious, but blindly automating updates without safety checks destroys sites when incompatible plugins break, themes conflict, or updates corrupt databases. One bad update at 3 AM can take your production site offline for hours.</p>



<p>WP-CLI enables safe update automation with pre-update backups, staged testing, automatic rollback on failure, and comprehensive monitoring. Build production-ready update workflows that protect your sites while keeping them secure and current.</p>



<p>In this guide, you’ll learn professional WordPress update automation techniques with safety mechanisms, testing procedures, and rollback strategies used by enterprises managing hundreds of WordPress installations.</p>



<h3 class="wp-block-heading" id="why-safe-updates">Why Safe Update Automation Matters</h3>



<p><a href="https://wordpress.org/support/article/updating-wordpress/">WordPress updates</a> are critical for security, but unsafe automation causes more problems than it solves.</p>



<h4 class="wp-block-heading" id="dangers-of-unsafe-update-automation">Dangers of Unsafe Update Automation</h4>



<p><strong>Site breakage</strong>: Incompatible plugin updates break functionality without warning.</p>



<p><strong>Data loss</strong>: Database updates without backups cause irrecoverable data corruption.</p>



<p><strong>Downtime</strong>: Failed updates leave sites inaccessible during business hours.</p>



<p><strong>Security vulnerabilities</strong>: Partial updates create new attack vectors.</p>



<p><strong>No recovery</strong>: Without rollback procedures, fixing failed updates takes hours.</p>



<h4 class="wp-block-heading" id="safe-update-automation-principles">Safe Update Automation Principles</h4>



<p><strong>Test first</strong>: Validate updates on staging before touching production.</p>



<p><strong>Backup always</strong>: Never update without verified, restorable backups.</p>



<p><strong>Rollback ready</strong>: Automated failure detection and instant recovery.</p>



<p><strong>Monitor constantly</strong>: Track update success and site health post-update.</p>



<p><strong>Staged rollouts</strong>: Update test environments, then production incrementally.</p>



<p>According to <a href="https://wpengine.com/resources/">WordPress maintenance studies</a>, 25% of automated updates fail without proper safety mechanisms, causing site outages.</p>



<h3 class="wp-block-heading" id="pre-update-checks">Pre-Update Safety Checks</h3>



<p>Validate environment before executing updates.</p>



<h4 class="wp-block-heading" id="system-requirements-verification">System Requirements Verification</h4>



<div class="sourceCode" id="cb1">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a><span class="co"># pre-update-checks.sh - Validate system before updates</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Running pre-update checks..."</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a><span class="co"># Check WordPress is installed</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a><span class="kw">if</span> ! <span class="ex">wp</span> core is-installed <span class="op">2&gt;</span>/dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ WordPress not installed"</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true"></a></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true"></a><span class="co"># Check database connection</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true"></a><span class="kw">if</span> ! <span class="ex">wp</span> db check <span class="op">2&gt;</span>/dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Database connection failed"</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true"></a></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true"></a><span class="co"># Check disk space (need at least 500MB)</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true"></a><span class="va">AVAILABLE=$(</span><span class="fu">df</span> /var/www <span class="kw">|</span> <span class="fu">tail</span> -1 <span class="kw">|</span> <span class="fu">awk</span> <span class="st">'{print $4}'</span><span class="va">)</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$AVAILABLE</span><span class="st">"</span> <span class="ot">-lt</span> 500000<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Insufficient disk space: </span><span class="va">${AVAILABLE}</span><span class="st">KB available"</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true"></a></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true"></a><span class="co"># Check WP-CLI version</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true"></a><span class="va">WP_CLI_VERSION=$(</span><span class="ex">wp</span> cli version --allow-root <span class="op">2&gt;</span>/dev/null <span class="kw">|</span> <span class="fu">grep</span> -oP <span class="st">'\d+\.\d+\.\d+'</span><span class="va">)</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"WP-CLI version: </span><span class="va">$WP_CLI_VERSION</span><span class="st">"</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true"></a></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true"></a><span class="co"># Check for maintenance mode</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="ot">-f</span> <span class="st">".maintenance"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Site already in maintenance mode"</span></span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true"></a></span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"✓ All pre-update checks passed"</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="check-for-available-updates">Check for Available Updates</h4>



<div class="sourceCode" id="cb2">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a><span class="co"># Check WordPress core updates</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a><span class="va">CORE_UPDATE=$(</span><span class="ex">wp</span> core check-update --format=count<span class="va">)</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Core updates available: </span><span class="va">$CORE_UPDATE</span><span class="st">"</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true"></a><span class="co"># Check plugin updates</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true"></a><span class="va">PLUGIN_UPDATES=$(</span><span class="ex">wp</span> plugin list --update=available --format=count<span class="va">)</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Plugin updates available: </span><span class="va">$PLUGIN_UPDATES</span><span class="st">"</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true"></a><span class="co"># Check theme updates</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true"></a><span class="va">THEME_UPDATES=$(</span><span class="ex">wp</span> theme list --update=available --format=count<span class="va">)</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Theme updates available: </span><span class="va">$THEME_UPDATES</span><span class="st">"</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true"></a></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true"></a><span class="co"># List specific updates</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$PLUGIN_UPDATES</span><span class="st">"</span> <span class="ot">-gt</span> 0<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Plugins requiring updates:"</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true"></a>    <span class="ex">wp</span> plugin list --update=available --fields=name,version,update_version</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true"></a><span class="kw">fi</span></span></code></pre>
</div>



<p>Learn about <a href="https://wordpress.org/support/article/updating-wordpress/">WordPress update best practices</a>.</p>



<h3 class="wp-block-heading" id="automated-backup">Automated Backup Before Updates</h3>



<p>Never update without verified backups and rollback capability.</p>



<h4 class="wp-block-heading" id="complete-backup-script">Complete Backup Script</h4>



<div class="sourceCode" id="cb3">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a><span class="co"># backup-before-update.sh</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a><span class="kw">set</span> <span class="ex">-euo</span> pipefail</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a><span class="va">SITE_PATH=</span><span class="st">"/var/www/html"</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true"></a><span class="va">BACKUP_DIR=</span><span class="st">"/backups/pre-update"</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true"></a><span class="va">DATE=$(</span><span class="fu">date</span> +%Y%m%d_%H%M%S<span class="va">)</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true"></a><span class="va">BACKUP_NAME=</span><span class="st">"backup-</span><span class="va">$DATE</span><span class="st">"</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true"></a></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true"></a><span class="fu">mkdir</span> -p <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">"</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$SITE_PATH</span><span class="st">"</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true"></a></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Creating pre-update backup..."</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true"></a></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true"></a><span class="co"># Export database</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Backing up database..."</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true"></a><span class="ex">wp</span> db export <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">.sql.gz"</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true"></a></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true"></a><span class="co"># Verify database backup</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true"></a><span class="va">DB_SIZE=$(</span><span class="fu">stat</span> -c%s <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">.sql.gz"</span><span class="va">)</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$DB_SIZE</span><span class="st">"</span> <span class="ot">-lt</span> 1000<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Database backup too small, aborting"</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true"></a></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true"></a><span class="co"># Backup critical files</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Backing up files..."</span></span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true"></a><span class="fu">tar</span> -czf <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">-files.tar.gz"</span> <span class="kw">\</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true"></a>    <span class="ex">wp-content/plugins</span> <span class="kw">\</span></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true"></a>    <span class="ex">wp-content/themes</span> <span class="kw">\</span></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true"></a>    <span class="ex">wp-content/uploads</span> <span class="kw">\</span></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true"></a>    <span class="ex">wp-config.php</span></span>
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true"></a></span>
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true"></a><span class="co"># Verify file backup</span></span>
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true"></a><span class="va">FILE_SIZE=$(</span><span class="fu">stat</span> -c%s <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">-files.tar.gz"</span><span class="va">)</span></span>
<span id="cb3-37"><a href="#cb3-37" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$FILE_SIZE</span><span class="st">"</span> <span class="ot">-lt</span> 10000<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb3-38"><a href="#cb3-38" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ File backup too small, aborting"</span></span>
<span id="cb3-39"><a href="#cb3-39" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb3-40"><a href="#cb3-40" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb3-41"><a href="#cb3-41" aria-hidden="true"></a></span>
<span id="cb3-42"><a href="#cb3-42" aria-hidden="true"></a><span class="co"># Create backup manifest</span></span>
<span id="cb3-43"><a href="#cb3-43" aria-hidden="true"></a><span class="fu">cat</span> <span class="op">&gt;</span> <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">-manifest.txt"</span> <span class="op">&lt;&lt;EOF</span></span>
<span id="cb3-44"><a href="#cb3-44" aria-hidden="true"></a>Backup Created: <span class="va">$(</span><span class="fu">date</span><span class="va">)</span></span>
<span id="cb3-45"><a href="#cb3-45" aria-hidden="true"></a>WordPress Version: <span class="va">$(</span><span class="ex">wp</span> core version<span class="va">)</span></span>
<span id="cb3-46"><a href="#cb3-46" aria-hidden="true"></a>Database Size: <span class="va">$(</span><span class="fu">du</span> -h <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">.sql.gz"</span> <span class="kw">|</span> <span class="fu">cut</span> -f1<span class="va">)</span></span>
<span id="cb3-47"><a href="#cb3-47" aria-hidden="true"></a>Files Size: <span class="va">$(</span><span class="fu">du</span> -h <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">-files.tar.gz"</span> <span class="kw">|</span> <span class="fu">cut</span> -f1<span class="va">)</span></span>
<span id="cb3-48"><a href="#cb3-48" aria-hidden="true"></a>Site URL: <span class="va">$(</span><span class="ex">wp</span> option get siteurl<span class="va">)</span></span>
<span id="cb3-49"><a href="#cb3-49" aria-hidden="true"></a>EOF</span>
<span id="cb3-50"><a href="#cb3-50" aria-hidden="true"></a></span>
<span id="cb3-51"><a href="#cb3-51" aria-hidden="true"></a>echo "✓ Backup complete: <span class="va">$BACKUP_NAME</span>"</span>
<span id="cb3-52"><a href="#cb3-52" aria-hidden="true"></a>echo "<span class="va">$BACKUP_NAME</span>" &gt; /tmp/last-backup-name.txt</span></code></pre>
</div>



<h4 class="wp-block-heading" id="verify-backup-integrity">Verify Backup Integrity</h4>



<div class="sourceCode" id="cb4">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true"></a><span class="co"># verify-backup.sh</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true"></a><span class="va">BACKUP_NAME=$(</span><span class="fu">cat</span> /tmp/last-backup-name.txt<span class="va">)</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true"></a><span class="va">BACKUP_DIR=</span><span class="st">"/backups/pre-update"</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Verifying backup: </span><span class="va">$BACKUP_NAME</span><span class="st">"</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true"></a><span class="co"># Test database file integrity</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true"></a><span class="kw">if</span> <span class="fu">gunzip</span> -t <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">.sql.gz"</span> <span class="op">2&gt;</span>/dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ Database backup integrity OK"</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Database backup corrupted"</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true"></a></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true"></a><span class="co"># Test tarball integrity</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true"></a><span class="kw">if</span> <span class="fu">tar</span> -tzf <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">-files.tar.gz"</span> <span class="op">&gt;</span>/dev/null <span class="op">2&gt;&amp;1</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ File backup integrity OK"</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ File backup corrupted"</span></span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true"></a></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"✓ Backup verification complete"</span></span></code></pre>
</div>



<h3 class="wp-block-heading" id="safe-update-execution">Safe Update Execution</h3>



<p>Execute updates with safety mechanisms and monitoring.</p>



<h4 class="wp-block-heading" id="update-with-automatic-rollback">Update with Automatic Rollback</h4>



<div class="sourceCode" id="cb5">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true"></a><span class="co"># safe-update.sh - Update with automatic rollback on failure</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true"></a></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true"></a><span class="kw">set</span> <span class="ex">-e</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true"></a><span class="va">SITE_PATH=</span><span class="st">"/var/www/html"</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true"></a><span class="va">LOG_FILE=</span><span class="st">"/var/log/wp-updates.log"</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true"></a><span class="fu">log()</span> <span class="kw">{</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"[</span><span class="va">$(</span><span class="fu">date</span> <span class="st">'+%Y-%m-%d %H:%M:%S'</span><span class="va">)</span><span class="st">] </span><span class="va">$@</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">tee</span> -a <span class="st">"</span><span class="va">$LOG_FILE</span><span class="st">"</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true"></a></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true"></a><span class="fu">rollback()</span> <span class="kw">{</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"ERROR: Update failed, initiating rollback..."</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true"></a></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true"></a>    <span class="va">BACKUP_NAME=$(</span><span class="fu">cat</span> /tmp/last-backup-name.txt<span class="va">)</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true"></a>    <span class="va">BACKUP_DIR=</span><span class="st">"/backups/pre-update"</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true"></a></span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true"></a>    <span class="co"># Restore database</span></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true"></a>    <span class="bu">cd</span> <span class="st">"</span><span class="va">$SITE_PATH</span><span class="st">"</span></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true"></a>    <span class="ex">wp</span> db import <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">.sql.gz"</span></span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true"></a></span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true"></a>    <span class="co"># Restore files</span></span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true"></a>    <span class="fu">tar</span> -xzf <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/</span><span class="va">$BACKUP_NAME</span><span class="st">-files.tar.gz"</span> -C <span class="st">"</span><span class="va">$SITE_PATH</span><span class="st">"</span></span>
<span id="cb5-25"><a href="#cb5-25" aria-hidden="true"></a></span>
<span id="cb5-26"><a href="#cb5-26" aria-hidden="true"></a>    <span class="co"># Clear caches</span></span>
<span id="cb5-27"><a href="#cb5-27" aria-hidden="true"></a>    <span class="ex">wp</span> cache flush</span>
<span id="cb5-28"><a href="#cb5-28" aria-hidden="true"></a>    <span class="ex">wp</span> rewrite flush</span>
<span id="cb5-29"><a href="#cb5-29" aria-hidden="true"></a></span>
<span id="cb5-30"><a href="#cb5-30" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"✓ Rollback complete, site restored"</span></span>
<span id="cb5-31"><a href="#cb5-31" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb5-32"><a href="#cb5-32" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb5-33"><a href="#cb5-33" aria-hidden="true"></a></span>
<span id="cb5-34"><a href="#cb5-34" aria-hidden="true"></a><span class="co"># Register rollback on error</span></span>
<span id="cb5-35"><a href="#cb5-35" aria-hidden="true"></a><span class="bu">trap</span> rollback ERR</span>
<span id="cb5-36"><a href="#cb5-36" aria-hidden="true"></a></span>
<span id="cb5-37"><a href="#cb5-37" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$SITE_PATH</span><span class="st">"</span></span>
<span id="cb5-38"><a href="#cb5-38" aria-hidden="true"></a></span>
<span id="cb5-39"><a href="#cb5-39" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"=== WordPress Update Started ==="</span></span>
<span id="cb5-40"><a href="#cb5-40" aria-hidden="true"></a></span>
<span id="cb5-41"><a href="#cb5-41" aria-hidden="true"></a><span class="co"># Pre-update checks</span></span>
<span id="cb5-42"><a href="#cb5-42" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/pre-update-checks.sh</span>
<span id="cb5-43"><a href="#cb5-43" aria-hidden="true"></a></span>
<span id="cb5-44"><a href="#cb5-44" aria-hidden="true"></a><span class="co"># Create backup</span></span>
<span id="cb5-45"><a href="#cb5-45" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/backup-before-update.sh</span>
<span id="cb5-46"><a href="#cb5-46" aria-hidden="true"></a></span>
<span id="cb5-47"><a href="#cb5-47" aria-hidden="true"></a><span class="co"># Verify backup</span></span>
<span id="cb5-48"><a href="#cb5-48" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/verify-backup.sh</span>
<span id="cb5-49"><a href="#cb5-49" aria-hidden="true"></a></span>
<span id="cb5-50"><a href="#cb5-50" aria-hidden="true"></a><span class="co"># Enable maintenance mode</span></span>
<span id="cb5-51"><a href="#cb5-51" aria-hidden="true"></a><span class="ex">wp</span> maintenance-mode activate</span>
<span id="cb5-52"><a href="#cb5-52" aria-hidden="true"></a></span>
<span id="cb5-53"><a href="#cb5-53" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Updating WordPress core..."</span></span>
<span id="cb5-54"><a href="#cb5-54" aria-hidden="true"></a><span class="ex">wp</span> core update</span>
<span id="cb5-55"><a href="#cb5-55" aria-hidden="true"></a></span>
<span id="cb5-56"><a href="#cb5-56" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Updating plugins..."</span></span>
<span id="cb5-57"><a href="#cb5-57" aria-hidden="true"></a><span class="ex">wp</span> plugin update --all</span>
<span id="cb5-58"><a href="#cb5-58" aria-hidden="true"></a></span>
<span id="cb5-59"><a href="#cb5-59" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Updating themes..."</span></span>
<span id="cb5-60"><a href="#cb5-60" aria-hidden="true"></a><span class="ex">wp</span> theme update --all</span>
<span id="cb5-61"><a href="#cb5-61" aria-hidden="true"></a></span>
<span id="cb5-62"><a href="#cb5-62" aria-hidden="true"></a><span class="co"># Verify WordPress still works</span></span>
<span id="cb5-63"><a href="#cb5-63" aria-hidden="true"></a><span class="kw">if</span> ! <span class="ex">wp</span> core is-installed<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb5-64"><a href="#cb5-64" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"✗ WordPress verification failed"</span></span>
<span id="cb5-65"><a href="#cb5-65" aria-hidden="true"></a>    <span class="ex">rollback</span></span>
<span id="cb5-66"><a href="#cb5-66" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb5-67"><a href="#cb5-67" aria-hidden="true"></a></span>
<span id="cb5-68"><a href="#cb5-68" aria-hidden="true"></a><span class="co"># Test database</span></span>
<span id="cb5-69"><a href="#cb5-69" aria-hidden="true"></a><span class="kw">if</span> ! <span class="ex">wp</span> db check<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb5-70"><a href="#cb5-70" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"✗ Database check failed"</span></span>
<span id="cb5-71"><a href="#cb5-71" aria-hidden="true"></a>    <span class="ex">rollback</span></span>
<span id="cb5-72"><a href="#cb5-72" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb5-73"><a href="#cb5-73" aria-hidden="true"></a></span>
<span id="cb5-74"><a href="#cb5-74" aria-hidden="true"></a><span class="co"># Disable maintenance mode</span></span>
<span id="cb5-75"><a href="#cb5-75" aria-hidden="true"></a><span class="ex">wp</span> maintenance-mode deactivate</span>
<span id="cb5-76"><a href="#cb5-76" aria-hidden="true"></a></span>
<span id="cb5-77"><a href="#cb5-77" aria-hidden="true"></a><span class="co"># Clear caches</span></span>
<span id="cb5-78"><a href="#cb5-78" aria-hidden="true"></a><span class="ex">wp</span> cache flush</span>
<span id="cb5-79"><a href="#cb5-79" aria-hidden="true"></a><span class="ex">wp</span> rewrite flush</span>
<span id="cb5-80"><a href="#cb5-80" aria-hidden="true"></a></span>
<span id="cb5-81"><a href="#cb5-81" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"=== Update Complete Successfully ==="</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="staged-update-strategy">Staged Update Strategy</h4>



<div class="sourceCode" id="cb6">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true"></a><span class="co"># staged-update.sh - Update staging first, then production</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a><span class="va">STAGING_PATH=</span><span class="st">"/var/www/staging"</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true"></a><span class="va">PROD_PATH=</span><span class="st">"/var/www/production"</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Stage 1: Updating staging environment..."</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$STAGING_PATH</span><span class="st">"</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/safe-update.sh</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true"></a></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true"></a><span class="co"># Wait for manual verification</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Staging updated. Please verify functionality."</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true"></a><span class="bu">read</span> -p <span class="st">"Proceed with production update? (y/n) "</span> -n 1 -r</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true"></a><span class="bu">echo</span></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true"></a></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true"></a><span class="kw">if [[</span> <span class="ot">!</span> <span class="va">$REPLY</span> =~ ^[Yy]$<span class="kw"> ]]</span>; <span class="kw">then</span></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Production update cancelled"</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true"></a>    <span class="bu">exit</span> 0</span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true"></a></span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Stage 2: Updating production..."</span></span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$PROD_PATH</span><span class="st">"</span></span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/safe-update.sh</span>
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true"></a></span>
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"✓ Staged rollout complete"</span></span></code></pre>
</div>



<h3 class="wp-block-heading" id="post-update-validation">Post-Update Validation</h3>



<p>Verify site health after updates.</p>



<h4 class="wp-block-heading" id="comprehensive-health-check">Comprehensive Health Check</h4>



<div class="sourceCode" id="cb7">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true"></a><span class="co"># post-update-validation.sh</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true"></a><span class="va">SITE_URL=$(</span><span class="ex">wp</span> option get siteurl<span class="va">)</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true"></a></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Running post-update validation..."</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true"></a></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true"></a><span class="co"># Check WordPress core</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true"></a><span class="kw">if</span> <span class="ex">wp</span> core verify-checksums <span class="op">2&gt;</span>/dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ WordPress core files intact"</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Core file verification failed"</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true"></a></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true"></a><span class="co"># Check database</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true"></a><span class="kw">if</span> <span class="ex">wp</span> db check <span class="op">2&gt;</span>/dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ Database healthy"</span></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Database issues detected"</span></span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true"></a></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true"></a><span class="co"># Test site accessibility</span></span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true"></a><span class="va">HTTP_CODE=$(</span><span class="ex">curl</span> -s -o /dev/null -w <span class="st">"%{http_code}"</span> <span class="st">"</span><span class="va">$SITE_URL</span><span class="st">"</span><span class="va">)</span></span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$HTTP_CODE</span><span class="st">"</span> <span class="ot">-eq</span> 200<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ Site accessible (HTTP </span><span class="va">$HTTP_CODE</span><span class="st">)"</span></span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Site not accessible (HTTP </span><span class="va">$HTTP_CODE</span><span class="st">)"</span></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true"></a></span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true"></a><span class="co"># Check admin panel</span></span>
<span id="cb7-34"><a href="#cb7-34" aria-hidden="true"></a><span class="va">ADMIN_URL=</span><span class="st">"</span><span class="va">${SITE_URL}</span><span class="st">/wp-admin/"</span></span>
<span id="cb7-35"><a href="#cb7-35" aria-hidden="true"></a><span class="va">ADMIN_CODE=$(</span><span class="ex">curl</span> -s -o /dev/null -w <span class="st">"%{http_code}"</span> <span class="st">"</span><span class="va">$ADMIN_URL</span><span class="st">"</span><span class="va">)</span></span>
<span id="cb7-36"><a href="#cb7-36" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$ADMIN_CODE</span><span class="st">"</span> <span class="ot">-eq</span> 200<span class="bu"> ]</span> <span class="kw">||</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$ADMIN_CODE</span><span class="st">"</span> <span class="ot">-eq</span> 302<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb7-37"><a href="#cb7-37" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ Admin panel accessible"</span></span>
<span id="cb7-38"><a href="#cb7-38" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb7-39"><a href="#cb7-39" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Admin panel issues (HTTP </span><span class="va">$ADMIN_CODE</span><span class="st">)"</span></span>
<span id="cb7-40"><a href="#cb7-40" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb7-41"><a href="#cb7-41" aria-hidden="true"></a></span>
<span id="cb7-42"><a href="#cb7-42" aria-hidden="true"></a><span class="co"># Check critical pages</span></span>
<span id="cb7-43"><a href="#cb7-43" aria-hidden="true"></a><span class="va">CRITICAL_PAGES=(</span><span class="st">"/"</span> <span class="st">"/about"</span> <span class="st">"/contact"</span><span class="va">)</span></span>
<span id="cb7-44"><a href="#cb7-44" aria-hidden="true"></a><span class="kw">for</span> <span class="ex">PAGE</span> in <span class="st">"</span><span class="va">${CRITICAL_PAGES[@]}</span><span class="st">"</span><span class="kw">;</span> <span class="kw">do</span></span>
<span id="cb7-45"><a href="#cb7-45" aria-hidden="true"></a>    <span class="va">URL=</span><span class="st">"</span><span class="va">${SITE_URL}${PAGE}</span><span class="st">"</span></span>
<span id="cb7-46"><a href="#cb7-46" aria-hidden="true"></a>    <span class="va">CODE=$(</span><span class="ex">curl</span> -s -o /dev/null -w <span class="st">"%{http_code}"</span> <span class="st">"</span><span class="va">$URL</span><span class="st">"</span><span class="va">)</span></span>
<span id="cb7-47"><a href="#cb7-47" aria-hidden="true"></a></span>
<span id="cb7-48"><a href="#cb7-48" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$CODE</span><span class="st">"</span> <span class="ot">-eq</span> 200<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb7-49"><a href="#cb7-49" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✓ </span><span class="va">$PAGE</span><span class="st"> accessible"</span></span>
<span id="cb7-50"><a href="#cb7-50" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb7-51"><a href="#cb7-51" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✗ </span><span class="va">$PAGE</span><span class="st"> failed (HTTP </span><span class="va">$CODE</span><span class="st">)"</span></span>
<span id="cb7-52"><a href="#cb7-52" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb7-53"><a href="#cb7-53" aria-hidden="true"></a><span class="kw">done</span></span>
<span id="cb7-54"><a href="#cb7-54" aria-hidden="true"></a></span>
<span id="cb7-55"><a href="#cb7-55" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"✓ Post-update validation complete"</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="automated-testing">Automated Testing</h4>



<div class="sourceCode" id="cb8">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true"></a><span class="co"># test-critical-functionality.sh</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true"></a><span class="bu">cd</span> /var/www/html</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Testing critical WordPress functionality..."</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true"></a><span class="co"># Test plugin activation</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true"></a><span class="va">TEST_PLUGIN=</span><span class="st">"hello-dolly"</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true"></a><span class="kw">if</span> <span class="ex">wp</span> plugin is-installed <span class="va">$TEST_PLUGIN</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ex">wp</span> plugin activate <span class="va">$TEST_PLUGIN</span> <span class="op">2&gt;</span>/dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✓ Plugin activation works"</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true"></a>        <span class="ex">wp</span> plugin deactivate <span class="va">$TEST_PLUGIN</span> <span class="op">2&gt;</span>/dev/null</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"✗ Plugin activation failed"</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true"></a>        <span class="bu">exit</span> 1</span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true"></a></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true"></a><span class="co"># Test post creation</span></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true"></a><span class="va">TEST_POST=$(</span><span class="ex">wp</span> post create <span class="kw">\</span></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true"></a>    <span class="ex">--post_title</span>=<span class="st">"Test Post"</span> <span class="kw">\</span></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true"></a>    <span class="ex">--post_content</span>=<span class="st">"Testing functionality"</span> <span class="kw">\</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true"></a>    <span class="ex">--post_status</span>=draft <span class="kw">\</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true"></a>    <span class="ex">--porcelain</span> <span class="op">2&gt;</span>/dev/null<span class="va">)</span></span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true"></a></span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="ot">-n</span> <span class="st">"</span><span class="va">$TEST_POST</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ Post creation works"</span></span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true"></a>    <span class="ex">wp</span> post delete <span class="va">$TEST_POST</span> --force</span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Post creation failed"</span></span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb8-33"><a href="#cb8-33" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true"></a></span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true"></a><span class="co"># Test cache flush</span></span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true"></a><span class="kw">if</span> <span class="ex">wp</span> cache flush <span class="op">2&gt;</span>/dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb8-37"><a href="#cb8-37" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✓ Cache operations work"</span></span>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"✗ Cache operations failed"</span></span>
<span id="cb8-40"><a href="#cb8-40" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb8-41"><a href="#cb8-41" aria-hidden="true"></a></span>
<span id="cb8-42"><a href="#cb8-42" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"✓ Functionality tests passed"</span></span></code></pre>
</div>



<p>Learn about <a href="https://wordpress.org/support/article/wordpress-maintenance-mode/">WordPress maintenance mode</a>.</p>



<h3 class="wp-block-heading" id="monitoring-alerts">Update Monitoring and Alerts</h3>



<p>Track update success and detect issues.</p>



<h4 class="wp-block-heading" id="update-status-reporting">Update Status Reporting</h4>



<div class="sourceCode" id="cb9">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true"></a><span class="co"># update-report.sh - Generate update status report</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true"></a></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true"></a><span class="va">REPORT_FILE=</span><span class="st">"/tmp/update-report-</span><span class="va">$(</span><span class="fu">date</span> +%Y%m%d<span class="va">)</span><span class="st">.txt"</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true"></a><span class="va">ADMIN_EMAIL=</span><span class="st">"admin@example.com"</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true"></a></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true"></a><span class="kw">{</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"WordPress Update Report"</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Generated: </span><span class="va">$(</span><span class="fu">date</span><span class="va">)</span><span class="st">"</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"========================"</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true"></a></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"WordPress Version:"</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true"></a>    <span class="ex">wp</span> core version --extra</span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true"></a></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Plugin Status:"</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true"></a>    <span class="ex">wp</span> plugin list --format=table</span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true"></a></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Theme Status:"</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true"></a>    <span class="ex">wp</span> theme list --format=table</span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true"></a></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Update Check:"</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true"></a>    <span class="va">CORE_UPDATES=$(</span><span class="ex">wp</span> core check-update --format=count<span class="va">)</span></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true"></a>    <span class="va">PLUGIN_UPDATES=$(</span><span class="ex">wp</span> plugin list --update=available --format=count<span class="va">)</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true"></a>    <span class="va">THEME_UPDATES=$(</span><span class="ex">wp</span> theme list --update=available --format=count<span class="va">)</span></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true"></a></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Core updates available: </span><span class="va">$CORE_UPDATES</span><span class="st">"</span></span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Plugin updates available: </span><span class="va">$PLUGIN_UPDATES</span><span class="st">"</span></span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Theme updates available: </span><span class="va">$THEME_UPDATES</span><span class="st">"</span></span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true"></a></span>
<span id="cb9-35"><a href="#cb9-35" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$PLUGIN_UPDATES</span><span class="st">"</span> <span class="ot">-gt</span> 0<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb9-36"><a href="#cb9-36" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"Plugins Needing Updates:"</span></span>
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true"></a>        <span class="ex">wp</span> plugin list --update=available --fields=name,version,update_version</span>
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">""</span></span>
<span id="cb9-39"><a href="#cb9-39" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb9-40"><a href="#cb9-40" aria-hidden="true"></a></span>
<span id="cb9-41"><a href="#cb9-41" aria-hidden="true"></a><span class="kw">}</span> <span class="op">&gt;</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb9-42"><a href="#cb9-42" aria-hidden="true"></a></span>
<span id="cb9-43"><a href="#cb9-43" aria-hidden="true"></a><span class="co"># Email report</span></span>
<span id="cb9-44"><a href="#cb9-44" aria-hidden="true"></a><span class="ex">mail</span> -s <span class="st">"WordPress Update Report"</span> <span class="st">"</span><span class="va">$ADMIN_EMAIL</span><span class="st">"</span> <span class="op">&lt;</span> <span class="st">"</span><span class="va">$REPORT_FILE</span><span class="st">"</span></span>
<span id="cb9-45"><a href="#cb9-45" aria-hidden="true"></a></span>
<span id="cb9-46"><a href="#cb9-46" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"✓ Update report sent to </span><span class="va">$ADMIN_EMAIL</span><span class="st">"</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="failure-notifications">Failure Notifications</h4>



<div class="sourceCode" id="cb10">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true"></a><span class="co"># notify-update-failure.sh</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true"></a><span class="va">ADMIN_EMAIL=</span><span class="st">"admin@example.com"</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true"></a><span class="va">SITE_NAME=$(</span><span class="ex">wp</span> option get blogname<span class="va">)</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true"></a><span class="va">SITE_URL=$(</span><span class="ex">wp</span> option get siteurl<span class="va">)</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true"></a></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true"></a><span class="va">ERROR_MSG=</span><span class="st">"WordPress Update Failure Alert</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true"></a></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true"></a><span class="st">Site: </span><span class="va">$SITE_NAME</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true"></a><span class="st">URL: </span><span class="va">$SITE_URL</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true"></a><span class="st">Time: </span><span class="va">$(</span><span class="fu">date</span><span class="va">)</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true"></a><span class="st">Server: </span><span class="va">$(</span><span class="fu">hostname</span><span class="va">)</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true"></a></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true"></a><span class="st">A WordPress update has failed and the site has been rolled back to the previous state.</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true"></a></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true"></a><span class="st">Please investigate immediately and review the update logs.</span></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true"></a></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true"></a><span class="st">Log file: /var/log/wp-updates.log"</span></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true"></a></span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"</span><span class="va">$ERROR_MSG</span><span class="st">"</span> <span class="kw">|</span> <span class="ex">mail</span> -s <span class="st">"URGENT: WordPress Update Failed on </span><span class="va">$SITE_NAME</span><span class="st">"</span> <span class="st">"</span><span class="va">$ADMIN_EMAIL</span><span class="st">"</span></span></code></pre>
</div>



<h3 class="wp-block-heading" id="production-automation">Production-Ready Update Automation</h3>



<p>Complete automated update system for production environments.</p>



<h4 class="wp-block-heading" id="master-update-script">Master Update Script</h4>



<div class="sourceCode" id="cb11">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true"></a><span class="co"># master-update-automation.sh</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true"></a></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true"></a><span class="kw">set</span> <span class="ex">-euo</span> pipefail</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true"></a><span class="va">SITE_PATH=</span><span class="st">"/var/www/html"</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true"></a><span class="va">BACKUP_DIR=</span><span class="st">"/backups/pre-update"</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true"></a><span class="va">LOG_FILE=</span><span class="st">"/var/log/wp-updates.log"</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true"></a><span class="va">ADMIN_EMAIL=</span><span class="st">"admin@example.com"</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true"></a></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true"></a><span class="fu">log()</span> <span class="kw">{</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"[</span><span class="va">$(</span><span class="fu">date</span> <span class="st">'+%Y-%m-%d %H:%M:%S'</span><span class="va">)</span><span class="st">] </span><span class="va">$@</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">tee</span> -a <span class="st">"</span><span class="va">$LOG_FILE</span><span class="st">"</span></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true"></a></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true"></a><span class="fu">send_failure_alert()</span> <span class="kw">{</span></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"WordPress update failed on </span><span class="va">$(</span><span class="fu">hostname</span><span class="va">)</span><span class="st"> at </span><span class="va">$(</span><span class="fu">date</span><span class="va">)</span><span class="st">"</span> <span class="kw">|</span> <span class="kw">\</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true"></a>        <span class="ex">mail</span> -s <span class="st">"WordPress Update Failure"</span> <span class="st">"</span><span class="va">$ADMIN_EMAIL</span><span class="st">"</span></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true"></a></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true"></a><span class="co"># Error handler</span></span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true"></a><span class="fu">error_handler()</span> <span class="kw">{</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"ERROR: Update failed at line </span><span class="va">$1</span><span class="st">"</span></span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true"></a>    <span class="ex">send_failure_alert</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true"></a></span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true"></a><span class="bu">trap</span> <span class="st">'error_handler ${LINENO}'</span> ERR</span>
<span id="cb11-28"><a href="#cb11-28" aria-hidden="true"></a></span>
<span id="cb11-29"><a href="#cb11-29" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$SITE_PATH</span><span class="st">"</span></span>
<span id="cb11-30"><a href="#cb11-30" aria-hidden="true"></a></span>
<span id="cb11-31"><a href="#cb11-31" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"=== Automated WordPress Update Started ==="</span></span>
<span id="cb11-32"><a href="#cb11-32" aria-hidden="true"></a></span>
<span id="cb11-33"><a href="#cb11-33" aria-hidden="true"></a><span class="co"># Pre-update checks</span></span>
<span id="cb11-34"><a href="#cb11-34" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Running pre-update checks..."</span></span>
<span id="cb11-35"><a href="#cb11-35" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/pre-update-checks.sh</span>
<span id="cb11-36"><a href="#cb11-36" aria-hidden="true"></a></span>
<span id="cb11-37"><a href="#cb11-37" aria-hidden="true"></a><span class="co"># Create backup</span></span>
<span id="cb11-38"><a href="#cb11-38" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Creating backup..."</span></span>
<span id="cb11-39"><a href="#cb11-39" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/backup-before-update.sh</span>
<span id="cb11-40"><a href="#cb11-40" aria-hidden="true"></a></span>
<span id="cb11-41"><a href="#cb11-41" aria-hidden="true"></a><span class="co"># Verify backup</span></span>
<span id="cb11-42"><a href="#cb11-42" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Verifying backup..."</span></span>
<span id="cb11-43"><a href="#cb11-43" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/verify-backup.sh</span>
<span id="cb11-44"><a href="#cb11-44" aria-hidden="true"></a></span>
<span id="cb11-45"><a href="#cb11-45" aria-hidden="true"></a><span class="co"># Enable maintenance mode</span></span>
<span id="cb11-46"><a href="#cb11-46" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Enabling maintenance mode..."</span></span>
<span id="cb11-47"><a href="#cb11-47" aria-hidden="true"></a><span class="ex">wp</span> maintenance-mode activate</span>
<span id="cb11-48"><a href="#cb11-48" aria-hidden="true"></a></span>
<span id="cb11-49"><a href="#cb11-49" aria-hidden="true"></a><span class="co"># Update WordPress</span></span>
<span id="cb11-50"><a href="#cb11-50" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Updating WordPress core..."</span></span>
<span id="cb11-51"><a href="#cb11-51" aria-hidden="true"></a><span class="kw">if</span> <span class="ex">wp</span> core check-update --format=count <span class="kw">|</span> <span class="fu">grep</span> -q <span class="st">"^0<pre wp-pre-tag-10=""></pre>quot;</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb11-52"><a href="#cb11-52" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"WordPress core already up to date"</span></span>
<span id="cb11-53"><a href="#cb11-53" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb11-54"><a href="#cb11-54" aria-hidden="true"></a>    <span class="ex">wp</span> core update</span>
<span id="cb11-55"><a href="#cb11-55" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb11-56"><a href="#cb11-56" aria-hidden="true"></a></span>
<span id="cb11-57"><a href="#cb11-57" aria-hidden="true"></a><span class="co"># Update plugins (exclude problematic ones)</span></span>
<span id="cb11-58"><a href="#cb11-58" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Updating plugins..."</span></span>
<span id="cb11-59"><a href="#cb11-59" aria-hidden="true"></a><span class="va">EXCLUDE=</span><span class="st">"woocommerce,elementor"</span>  # <span class="ex">Plugins</span> to update manually</span>
<span id="cb11-60"><a href="#cb11-60" aria-hidden="true"></a><span class="ex">wp</span> plugin update --all --exclude=<span class="st">"</span><span class="va">$EXCLUDE</span><span class="st">"</span></span>
<span id="cb11-61"><a href="#cb11-61" aria-hidden="true"></a></span>
<span id="cb11-62"><a href="#cb11-62" aria-hidden="true"></a><span class="co"># Update themes</span></span>
<span id="cb11-63"><a href="#cb11-63" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Updating themes..."</span></span>
<span id="cb11-64"><a href="#cb11-64" aria-hidden="true"></a><span class="ex">wp</span> theme update --all</span>
<span id="cb11-65"><a href="#cb11-65" aria-hidden="true"></a></span>
<span id="cb11-66"><a href="#cb11-66" aria-hidden="true"></a><span class="co"># Post-update validation</span></span>
<span id="cb11-67"><a href="#cb11-67" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Running post-update validation..."</span></span>
<span id="cb11-68"><a href="#cb11-68" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/post-update-validation.sh</span>
<span id="cb11-69"><a href="#cb11-69" aria-hidden="true"></a></span>
<span id="cb11-70"><a href="#cb11-70" aria-hidden="true"></a><span class="co"># Disable maintenance mode</span></span>
<span id="cb11-71"><a href="#cb11-71" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Disabling maintenance mode..."</span></span>
<span id="cb11-72"><a href="#cb11-72" aria-hidden="true"></a><span class="ex">wp</span> maintenance-mode deactivate</span>
<span id="cb11-73"><a href="#cb11-73" aria-hidden="true"></a></span>
<span id="cb11-74"><a href="#cb11-74" aria-hidden="true"></a><span class="co"># Clear all caches</span></span>
<span id="cb11-75"><a href="#cb11-75" aria-hidden="true"></a><span class="ex">wp</span> cache flush</span>
<span id="cb11-76"><a href="#cb11-76" aria-hidden="true"></a><span class="ex">wp</span> rewrite flush</span>
<span id="cb11-77"><a href="#cb11-77" aria-hidden="true"></a></span>
<span id="cb11-78"><a href="#cb11-78" aria-hidden="true"></a><span class="co"># Cleanup old backups (keep last 7)</span></span>
<span id="cb11-79"><a href="#cb11-79" aria-hidden="true"></a><span class="fu">find</span> <span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">"</span> -name <span class="st">"backup-*"</span> -mtime +7 -delete</span>
<span id="cb11-80"><a href="#cb11-80" aria-hidden="true"></a></span>
<span id="cb11-81"><a href="#cb11-81" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"=== Update Complete Successfully ==="</span></span>
<span id="cb11-82"><a href="#cb11-82" aria-hidden="true"></a></span>
<span id="cb11-83"><a href="#cb11-83" aria-hidden="true"></a><span class="co"># Send success report</span></span>
<span id="cb11-84"><a href="#cb11-84" aria-hidden="true"></a><span class="fu">bash</span> /usr/local/bin/update-report.sh</span></code></pre>
</div>



<p>Schedule with cron:</p>



<div class="sourceCode" id="cb12">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true"></a><span class="co"># Run updates Sunday 3 AM</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true"></a><span class="ex">0</span> 3 * * 0 /usr/local/bin/master-update-automation.sh</span></code></pre>
</div>



<h3 class="wp-block-heading" id="next-steps">Next Steps</h3>



<p>You now have production-ready WordPress update automation with comprehensive safety mechanisms.</p>



<h4 class="wp-block-heading" id="recommended-learning-path">Recommended Learning Path</h4>



<p><strong>Week 1</strong>: Safety fundamentals</p>



<ul class="wp-block-list">
<li>Implement pre-update checks</li>



<li>Create backup workflows</li>



<li>Build rollback procedures</li>
</ul>



<p><strong>Week 2</strong>: Testing workflows</p>



<ul class="wp-block-list">
<li>Set up staging environments</li>



<li>Automate post-update validation</li>



<li>Test critical functionality</li>
</ul>



<p><strong>Week 3</strong>: Monitoring</p>



<ul class="wp-block-list">
<li>Build update reporting</li>



<li>Set up failure alerts</li>



<li>Track update history</li>
</ul>



<p><strong>Week 4</strong>: Production deployment</p>



<ul class="wp-block-list">
<li>Automate complete workflows</li>



<li>Schedule updates</li>



<li>Document procedures</li>
</ul>



<h4 class="wp-block-heading" id="advanced-topics">Advanced Topics</h4>



<ol class="wp-block-list">
<li><strong><a href="#">Blue-Green Deployments</a></strong> &#8211; Zero-downtime updates</li>



<li><strong><a href="#">Canary Releases</a></strong> &#8211; Gradual rollout strategies</li>



<li><strong><a href="#">Continuous Integration</a></strong> &#8211; Automated testing pipelines</li>
</ol>



<h4 class="wp-block-heading" id="get-more-resources">Get More Resources</h4>



<p><strong><a href="#">Download update automation scripts</a></strong> including:</p>



<ul class="wp-block-list">
<li>Complete safety system</li>



<li>Testing frameworks</li>



<li>Monitoring tools</li>
</ul>



<p><strong><a href="/#get-started">Join our email course</a></strong> for:</p>



<ul class="wp-block-list">
<li>Weekly WP-CLI tutorials</li>



<li>Update automation strategies</li>



<li>DevOps best practices</li>
</ul>



<h3 class="wp-block-heading" id="conclusion">Conclusion</h3>



<p>Safe WordPress update automation with WP-CLI transforms risky manual updates into reliable, automated workflows that protect your sites while keeping them secure.</p>



<p>What we covered:</p>



<p>✅ Pre-update safety checks and validation <br>✅ Automated backup with verification <br>✅ Update execution with automatic rollback <br>✅ Post-update validation and testing <br>✅ Monitoring, alerts, and reporting <br>✅ Production-ready automation workflows</p>



<p>Master these techniques, and you’ll confidently automate WordPress updates knowing your sites are protected by multiple safety layers and instant recovery capabilities.</p>



<p><strong>Ready for more?</strong> Learn <a href="#">WordPress deployment automation</a> or <a href="#">infrastructure as code</a>.</p>



<p><strong>Questions about safe WordPress update automation?</strong> Drop a comment below!</p>



<p><strong>Found this helpful?</strong> Share with other WordPress administrators.</p>
<p>The post <a href="https://wpclimastery.com/blog/safe-wordpress-update-automation-with-wp-cli-testing-and-rollback/">Safe WordPress Update Automation with WP-CLI: Testing and Rollback</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>WordPress Malware Detection and Cleanup Using WP-CLI</title>
		<link>https://wpclimastery.com/blog/wordpress-malware-detection-and-cleanup-using-wp-cli/</link>
		
		<dc:creator><![CDATA[Krasen]]></dc:creator>
		<pubDate>Mon, 24 Nov 2025 11:16:24 +0000</pubDate>
				<category><![CDATA[WordPress Security & Maintenance]]></category>
		<category><![CDATA[malware detection wordpress]]></category>
		<category><![CDATA[wordpress hack cleanup]]></category>
		<category><![CDATA[wordpress malware cleanup]]></category>
		<category><![CDATA[wordpress security tools]]></category>
		<category><![CDATA[wp-cli security]]></category>
		<guid isPermaLink="false">https://wpclimastery.com/?p=217</guid>

					<description><![CDATA[<p>WordPress malware infections compromise site security, steal sensitive data, and damage reputation. WP-CLI provides powerful command-line tools for detecting, analyzing, and removing malware efficiently, often faster and more thoroughly than...</p>
<p>The post <a href="https://wpclimastery.com/blog/wordpress-malware-detection-and-cleanup-using-wp-cli/">WordPress Malware Detection and Cleanup Using WP-CLI</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>WordPress malware infections compromise site security, steal sensitive data, and damage reputation. WP-CLI provides powerful command-line tools for detecting, analyzing, and removing malware efficiently, often faster and more thoroughly than manual cleanup or GUI-based security plugins.</p>



<h2 class="wp-block-heading" id="understanding-wordpress-malware">Understanding WordPress Malware</h2>



<p>Malware manifests in various forms: backdoors granting unauthorized access, spam injection contaminating content, redirect scripts hijacking visitors, cryptominers consuming server resources, and data exfiltration code stealing information. Understanding these patterns helps identify and remove infections effectively.</p>



<p>Common infection vectors include vulnerable plugins or themes, weak passwords, compromised hosting environments, and outdated WordPress core. WP-CLI enables systematic scanning and cleanup across all potential infection points.</p>



<h2 class="wp-block-heading" id="initial-assessment-and-backup">Initial Assessment and Backup</h2>



<p>Before attempting cleanup, assess the infection scope and create comprehensive backups. This ensures you can recover if cleanup causes issues.</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># pre-cleanup-assessment.sh - Initial malware assessment</em>

WP_PATH="/var/www/html"
BACKUP_DIR="/backups/malware-cleanup"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)

mkdir -p "$BACKUP_DIR"

echo "=== Pre-Cleanup Assessment ==="

<em># Create complete backup</em>
echo "Creating backup..."
wp --path="$WP_PATH" db export "$BACKUP_DIR/database-$TIMESTAMP.sql"
tar -czf "$BACKUP_DIR/files-$TIMESTAMP.tar.gz" -C "$(dirname $WP_PATH)" "$(basename $WP_PATH)"

<em># Get WordPress version</em>
WP_VERSION=$(wp --path="$WP_PATH" core version)
echo "WordPress Version: $WP_VERSION"

<em># Check for core file modifications</em>
echo "Checking core file integrity..."
wp --path="$WP_PATH" core verify-checksums

<em># List all users (especially admins)</em>
echo "Admin users:"
wp --path="$WP_PATH" user list --role=administrator --fields=ID,user_login,user_email

<em># Check for suspicious users</em>
echo "Recently created users:"
wp --path="$WP_PATH" user list --format=json | \
    jq -r '.&#91;] | select(.roles | contains(&#91;"administrator"])) | "\(.ID)\t\(.user_login)\t\(.user_registered)"'

<em># List active plugins</em>
echo "Active plugins:"
wp --path="$WP_PATH" plugin list --status=active --fields=name,version,update

<em># Check for suspicious scheduled tasks</em>
echo "Scheduled cron events:"
wp --path="$WP_PATH" cron event list --format=table

echo "Assessment completed. Backup saved to: $BACKUP_DIR"
</code></pre>



<h2 class="wp-block-heading" id="core-file-integrity-verification">Core File Integrity Verification</h2>



<p>WordPress core files rarely need modification. Any changes often indicate compromise.</p>



<pre class="wp-block-code"><code><em># Verify core file checksums</em>
wp core verify-checksums

<em># Get detailed output of modified files</em>
wp core verify-checksums --format=json | jq -r '.&#91;] | select(.status == "modified") | .file'

<em># Reinstall WordPress core (preserves wp-content and wp-config.php)</em>
wp core download --force --skip-content

<em># Verify specific file</em>
wp core verify-checksums wp-admin/index.php
</code></pre>



<p>Automated core file restoration:</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># restore-core-files.sh - Restore modified core files</em>

WP_PATH="/var/www/html"

echo "Checking for modified core files..."

<em># Get list of modified files</em>
MODIFIED_FILES=$(wp --path="$WP_PATH" core verify-checksums --format=csv | grep -v "^file,status$" | grep "should_not_exist\|not_found\|modified" | cut -d',' -f1)

if &#91; -z "$MODIFIED_FILES" ]; then
    echo "No modified core files found"
    exit 0
fi

echo "Modified files found:"
echo "$MODIFIED_FILES"

<em># Backup modified files before restoration</em>
BACKUP_DIR="/backups/core-files-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"

echo "$MODIFIED_FILES" | while read -r file; do
    if &#91; -f "$WP_PATH/$file" ]; then
        BACKUP_PATH="$BACKUP_DIR/$(dirname $file)"
        mkdir -p "$BACKUP_PATH"
        cp "$WP_PATH/$file" "$BACKUP_PATH/"
        echo "Backed up: $file"
    fi
done

<em># Reinstall core</em>
echo "Reinstalling WordPress core..."
wp --path="$WP_PATH" core download --force --skip-content

<em># Verify restoration</em>
if wp --path="$WP_PATH" core verify-checksums; then
    echo "Core files successfully restored"
else
    echo "Warning: Some core files still show modifications"
fi
</code></pre>



<h2 class="wp-block-heading" id="database-scanning-and-cleanup">Database Scanning and Cleanup</h2>



<p>Malware often injects malicious code into the database, particularly in posts, options, and user metadata.</p>



<pre class="wp-block-code"><code><em># Search database for common malware patterns</em>
wp db query "SELECT * FROM wp_posts WHERE post_content LIKE '%base64_decode%' OR post_content LIKE '%eval(%' OR post_content LIKE '%gzinflate%'"

<em># Search options table</em>
wp db query "SELECT * FROM wp_options WHERE option_value LIKE '%eval(%' OR option_value LIKE '%base64_decode%'"

<em># Find suspicious JavaScript injections</em>
wp db query "SELECT post_id, post_title FROM wp_posts WHERE post_content LIKE '%&lt;script%' AND post_type='post'"

<em># Check for malicious admin users</em>
wp db query "SELECT * FROM wp_users WHERE user_login LIKE '%admin%' OR user_login REGEXP '^&#91;0-9]+$'"

<em># Find posts with suspicious meta data</em>
wp db query "SELECT meta_id, post_id, meta_key, meta_value FROM wp_postmeta WHERE meta_value LIKE '%&lt;script%' OR meta_value LIKE '%eval(%'"
</code></pre>



<p>Comprehensive database scanning script:</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># scan-database.sh - Scan database for malware patterns</em>

WP_PATH="/var/www/html"
REPORT_FILE="/var/log/malware-scan-$(date +%Y%m%d-%H%M%S).txt"

echo "=== WordPress Database Malware Scan ===" | tee "$REPORT_FILE"
echo "Date: $(date)" | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"

<em># Malware patterns to search for</em>
PATTERNS=(
    "base64_decode"
    "eval("
    "gzinflate"
    "str_rot13"
    "preg_replace.*\/e"
    "assert("
    "stripslashes"
    "iframe src"
    "script src=.*http"
    "document.write"
)

<em># Tables to scan</em>
TABLES=(
    "wp_posts"
    "wp_options"
    "wp_postmeta"
    "wp_usermeta"
    "wp_comments"
)

for pattern in "${PATTERNS&#91;@]}"; do
    echo "Searching for pattern: $pattern" | tee -a "$REPORT_FILE"

    for table in "${TABLES&#91;@]}"; do
        COUNT=$(wp --path="$WP_PATH" db query "SELECT COUNT(*) as count FROM $table" --skip-column-names 2&gt;/dev/null)

        if &#91; "$COUNT" -gt 0 ]; then
            <em># Get column names for table</em>
            COLUMNS=$(wp --path="$WP_PATH" db query "SHOW COLUMNS FROM $table" --skip-column-names | awk '{print $1}' | grep -E 'content|value|text')

            for column in $COLUMNS; do
                MATCHES=$(wp --path="$WP_PATH" db query "
                    SELECT COUNT(*) FROM $table
                    WHERE $column LIKE '%$pattern%'
                " --skip-column-names 2&gt;/dev/null || echo "0")

                if &#91; "$MATCHES" -gt 0 ]; then
                    echo "  Found $MATCHES matches in $table.$column" | tee -a "$REPORT_FILE"

                    <em># Get sample matches</em>
                    wp --path="$WP_PATH" db query "
                        SELECT * FROM $table
                        WHERE $column LIKE '%$pattern%'
                        LIMIT 3
                    " &gt;&gt; "$REPORT_FILE"
                fi
            done
        fi
    done
    echo "" | tee -a "$REPORT_FILE"
done

echo "Scan completed. Report saved to: $REPORT_FILE"
</code></pre>



<h2 class="wp-block-heading" id="plugin-and-theme-scanning">Plugin and Theme Scanning</h2>



<p>Compromised or nulled plugins/themes are common infection sources.</p>



<pre class="wp-block-code"><code><em># List all plugins</em>
wp plugin list --fields=name,status,version,update

<em># Check for plugins from suspicious sources</em>
wp plugin list --status=active --format=json | jq -r '.&#91;] | select(.update == "available") | .name'

<em># Deactivate all plugins (for diagnosis)</em>
wp plugin deactivate --all

<em># Reactivate plugins one by one</em>
wp plugin activate plugin-name

<em># Delete inactive plugins</em>
wp plugin delete $(wp plugin list --status=inactive --field=name)

<em># Check theme integrity</em>
wp theme list --fields=name,status,version,update

<em># Switch to default theme</em>
wp theme activate twentytwentyfour

<em># Delete unused themes</em>
wp theme delete $(wp theme list --status=inactive --field=name)
</code></pre>



<p>Scan for malicious code in plugins and themes:</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># scan-plugins-themes.sh - Scan for malware in plugins and themes</em>

WP_PATH="/var/www/html"
SCAN_LOG="/var/log/plugin-theme-scan-$(date +%Y%m%d).txt"

echo "=== Scanning Plugins and Themes for Malware ===" | tee "$SCAN_LOG"

<em># Malicious code patterns</em>
PATTERNS=(
    "eval\s*\("
    "base64_decode"
    "gzinflate"
    "str_rot13"
    "system\s*\("
    "exec\s*\("
    "shell_exec"
    "passthru"
    "preg_replace.*\/e"
    "\$_GET\&#91;.*\]\(.*\)"
    "\$_POST\&#91;.*\]\(.*\)"
)

<em># Scan plugins</em>
echo "Scanning plugins..." | tee -a "$SCAN_LOG"
for plugin_dir in "$WP_PATH/wp-content/plugins/"*/; do
    PLUGIN_NAME=$(basename "$plugin_dir")
    echo "Checking: $PLUGIN_NAME" | tee -a "$SCAN_LOG"

    for pattern in "${PATTERNS&#91;@]}"; do
        MATCHES=$(grep -r -i -E "$pattern" "$plugin_dir" 2&gt;/dev/null | wc -l)

        if &#91; "$MATCHES" -gt 0 ]; then
            echo "  WARNING: Found $MATCHES matches for '$pattern'" | tee -a "$SCAN_LOG"
            grep -r -i -n -E "$pattern" "$plugin_dir" | head -5 &gt;&gt; "$SCAN_LOG"
        fi
    done
done

<em># Scan themes</em>
echo "Scanning themes..." | tee -a "$SCAN_LOG"
for theme_dir in "$WP_PATH/wp-content/themes/"*/; do
    THEME_NAME=$(basename "$theme_dir")
    echo "Checking: $THEME_NAME" | tee -a "$SCAN_LOG"

    for pattern in "${PATTERNS&#91;@]}"; do
        MATCHES=$(grep -r -i -E "$pattern" "$theme_dir" 2&gt;/dev/null | wc -l)

        if &#91; "$MATCHES" -gt 0 ]; then
            echo "  WARNING: Found $MATCHES matches for '$pattern'" | tee -a "$SCAN_LOG"
            grep -r -i -n -E "$pattern" "$theme_dir" | head -5 &gt;&gt; "$SCAN_LOG"
        fi
    done
done

echo "Scan completed. Results in: $SCAN_LOG"
</code></pre>



<h2 class="wp-block-heading" id="removing-malicious-users-and-content">Removing Malicious Users and Content</h2>



<p>Delete unauthorized admin accounts and clean infected content.</p>



<pre class="wp-block-code"><code><em># List all administrators</em>
wp user list --role=administrator --format=table

<em># Delete suspicious user</em>
wp user delete 999 --yes --reassign=1

<em># Remove spam posts</em>
wp post delete $(wp post list --post_status=spam --format=ids) --force

<em># Clean spam comments</em>
wp comment delete $(wp comment list --status=spam --format=ids) --force

<em># Remove posts with malicious content</em>
wp db query "DELETE FROM wp_posts WHERE post_content LIKE '%malicious-pattern%'"

<em># Clean options table</em>
wp option delete suspicious_option_name

<em># Remove malicious scheduled tasks</em>
wp cron event delete suspicious_hook
</code></pre>



<p>Automated malicious user cleanup:</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># cleanup-users.sh - Remove suspicious WordPress users</em>

WP_PATH="/var/www/html"

echo "Scanning for suspicious users..."

<em># Get all admin users</em>
ADMIN_USERS=$(wp --path="$WP_PATH" user list --role=administrator --format=json)

<em># Check for users with suspicious characteristics</em>
echo "$ADMIN_USERS" | jq -r '.&#91;] | select(
    .user_login | test("^&#91;0-9]+$|admin&#91;0-9]+|wp&#91;-_]admin|support&#91;0-9]+")
) | .ID' | while read -r user_id; do
    USER_LOGIN=$(wp --path="$WP_PATH" user get $user_id --field=user_login)
    USER_EMAIL=$(wp --path="$WP_PATH" user get $user_id --field=user_email)
    USER_REGISTERED=$(wp --path="$WP_PATH" user get $user_id --field=user_registered)

    echo "Suspicious user found:"
    echo "  ID: $user_id"
    echo "  Login: $USER_LOGIN"
    echo "  Email: $USER_EMAIL"
    echo "  Registered: $USER_REGISTERED"

    <em># Uncomment to actually delete</em>
    <em># wp --path="$WP_PATH" user delete $user_id --yes --reassign=1</em>
    <em># echo "  Deleted"</em>
done

<em># Check for users with no posts and recently created</em>
echo "Checking for recently created users with no activity..."
wp --path="$WP_PATH" user list --format=json | jq -r '.&#91;] |
    select(.roles | contains(&#91;"administrator"])) |
    "\(.ID)\t\(.user_login)\t\(.user_registered)"'
</code></pre>



<h2 class="wp-block-heading" id="file-system-cleanup">File System Cleanup</h2>



<p>Search for and remove malicious files in the WordPress installation.</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># filesystem-scan.sh - Scan for suspicious files</em>

WP_PATH="/var/www/html"
SCAN_LOG="/var/log/filesystem-scan-$(date +%Y%m%d).txt"

echo "=== File System Malware Scan ===" | tee "$SCAN_LOG"

<em># Find recently modified files (last 7 days)</em>
echo "Recently modified files:" | tee -a "$SCAN_LOG"
find "$WP_PATH" -type f -mtime -7 -not -path "*/cache/*" -not -path "*/uploads/*" | tee -a "$SCAN_LOG"

<em># Find PHP files with suspicious names</em>
echo "Suspicious PHP files:" | tee -a "$SCAN_LOG"
find "$WP_PATH" -type f \( \
    -name "*.php.*" -o \
    -name "*.suspected" -o \
    -name "*.bak.php" -o \
    -name "*eval*.php" -o \
    -name "*base64*.php" -o \
    -iname "wp-config.php.bak" \
\) | tee -a "$SCAN_LOG"

<em># Find files with suspicious permissions (world-writable)</em>
echo "World-writable files:" | tee -a "$SCAN_LOG"
find "$WP_PATH" -type f -perm -0002 | tee -a "$SCAN_LOG"

<em># Find hidden PHP files</em>
echo "Hidden PHP files:" | tee -a "$SCAN_LOG"
find "$WP_PATH" -type f -name ".*\.php" | tee -a "$SCAN_LOG"

<em># Find files owned by wrong user (should be www-data or similar)</em>
echo "Files with incorrect ownership:" | tee -a "$SCAN_LOG"
find "$WP_PATH" -type f ! -user www-data ! -user root | head -20 | tee -a "$SCAN_LOG"

<em># Search for base64 encoded strings in PHP files</em>
echo "Files containing base64 encoding:" | tee -a "$SCAN_LOG"
grep -r -l "base64_decode" "$WP_PATH"/*.php "$WP_PATH"/wp-includes/*.php "$WP_PATH"/wp-admin/*.php 2&gt;/dev/null | tee -a "$SCAN_LOG"

echo "Scan completed: $SCAN_LOG"
</code></pre>



<h2 class="wp-block-heading" id="security-hardening-post-cleanup">Security Hardening Post-Cleanup</h2>



<p>After malware removal, implement security measures to prevent reinfection.</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># security-hardening.sh - Harden WordPress after cleanup</em>

WP_PATH="/var/www/html"

echo "Applying security hardening..."

<em># Update all components</em>
wp --path="$WP_PATH" core update
wp --path="$WP_PATH" plugin update --all
wp --path="$WP_PATH" theme update --all

<em># Set secure file permissions</em>
find "$WP_PATH" -type d -exec chmod 755 {} \;
find "$WP_PATH" -type f -exec chmod 644 {} \;
chmod 600 "$WP_PATH/wp-config.php"

<em># Disable file editing</em>
wp --path="$WP_PATH" config set DISALLOW_FILE_EDIT true --raw --type=constant

<em># Force SSL for admin</em>
wp --path="$WP_PATH" config set FORCE_SSL_ADMIN true --raw --type=constant

<em># Set security keys</em>
wp --path="$WP_PATH" config shuffle-salts

<em># Remove inactive plugins and themes</em>
wp --path="$WP_PATH" plugin delete $(wp --path="$WP_PATH" plugin list --status=inactive --field=name)
wp --path="$WP_PATH" theme delete $(wp --path="$WP_PATH" theme list --status=inactive --field=name)

<em># Disable XML-RPC if not needed</em>
cat &gt;&gt; "$WP_PATH/wp-config.php" &lt;&lt; 'EOF'
add_filter('xmlrpc_enabled', '__return_false');
EOF

<em># Install and configure security plugin</em>
wp --path="$WP_PATH" plugin install wordfence --activate
wp --path="$WP_PATH" option update wordfence_scan_enabled 1

<em># Change all user passwords</em>
echo "Resetting all user passwords..."
for user_id in $(wp --path="$WP_PATH" user list --field=ID); do
    NEW_PASS=$(openssl rand -base64 16)
    wp --path="$WP_PATH" user update $user_id --user_pass="$NEW_PASS"
    echo "User ID $user_id password reset"
done

<em># Clean and optimize database</em>
wp --path="$WP_PATH" db optimize

echo "Security hardening completed"
</code></pre>



<h2 class="wp-block-heading" id="monitoring-and-prevention">Monitoring and Prevention</h2>



<p>Set up monitoring to detect future compromises early.</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em># monitor-integrity.sh - Monitor WordPress for changes</em>

WP_PATH="/var/www/html"
HASH_FILE="/var/backups/wp-hashes.txt"
ALERT_EMAIL="admin@example.com"

<em># Create hash database if it doesn't exist</em>
if &#91; ! -f "$HASH_FILE" ]; then
    echo "Creating initial hash database..."
    find "$WP_PATH" -type f ! -path "*/uploads/*" ! -path "*/cache/*" -exec md5sum {} + &gt; "$HASH_FILE"
    echo "Hash database created"
    exit 0
fi

<em># Check for changes</em>
TEMP_HASH="/tmp/wp-hashes-temp.txt"
find "$WP_PATH" -type f ! -path "*/uploads/*" ! -path "*/cache/*" -exec md5sum {} + &gt; "$TEMP_HASH"

<em># Compare hashes</em>
CHANGES=$(diff "$HASH_FILE" "$TEMP_HASH" | grep "^&#91;&lt;&gt;]" | wc -l)

if &#91; "$CHANGES" -gt 0 ]; then
    echo "WARNING: $CHANGES files have changed"

    <em># Send alert</em>
    diff "$HASH_FILE" "$TEMP_HASH" | mail -s "WordPress File Changes Detected" "$ALERT_EMAIL"

    <em># Update hash database</em>
    mv "$TEMP_HASH" "$HASH_FILE"
else
    echo "No changes detected"
    rm "$TEMP_HASH"
fi
</code></pre>



<h2 class="wp-block-heading" id="related-links">Related Links</h2>



<ul class="wp-block-list">
<li><a href="https://wordpress.org/support/article/hardening-wordpress/">WordPress Security Documentation</a></li>



<li><a href="https://developer.wordpress.org/cli/commands/">WP-CLI Security Commands</a></li>



<li><a href="https://sucuri.net/guides/what-is-website-malware/">Sucuri Security Guide</a></li>



<li><a href="https://www.wordfence.com/blog/">Wordfence Security Blog</a></li>



<li><a href="https://owasp.org/www-community/vulnerabilities/">OWASP WordPress Security</a></li>
</ul>
<p>The post <a href="https://wpclimastery.com/blog/wordpress-malware-detection-and-cleanup-using-wp-cli/">WordPress Malware Detection and Cleanup Using WP-CLI</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
