diff --git a/Marlin/src/sd/SdBaseFile.cpp b/Marlin/src/sd/SdBaseFile.cpp
index 1c1e0c7d145..e3f95623acb 100644
--- a/Marlin/src/sd/SdBaseFile.cpp
+++ b/Marlin/src/sd/SdBaseFile.cpp
@@ -1668,6 +1668,28 @@ bool SdBaseFile::remove(SdBaseFile *dirFile, const char *path) {
   return file.open(dirFile, path, O_WRITE) ? file.remove() : false;
 }
 
+bool SdBaseFile::hide(const bool hidden) {
+  if (ENABLED(SDCARD_READONLY)) return false;
+  // must be an open file or subdirectory
+  if (!(isFile() || isSubDir())) return false;
+  // sync() and cache directory entry
+  sync();
+  dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
+  if (!d) return false;
+  uint8_t a = d->attributes;
+  if (hidden)
+    a |= DIR_ATT_HIDDEN;
+  else
+    a &= ~DIR_ATT_HIDDEN;
+
+  if (a != d->attributes) {
+    d->attributes = a;
+    return vol_->cacheFlush();
+  }
+
+  return true;
+}
+
 /**
  * Rename a file or subdirectory.
  *
diff --git a/Marlin/src/sd/SdBaseFile.h b/Marlin/src/sd/SdBaseFile.h
index bda44c6bd5c..dd8e2aff4bd 100644
--- a/Marlin/src/sd/SdBaseFile.h
+++ b/Marlin/src/sd/SdBaseFile.h
@@ -310,6 +310,11 @@ class SdBaseFile {
   bool rmdir();
   bool rmRfStar();
 
+  /**
+   * Set or clear DIR_ATT_HIDDEN attribute for directory entry
+   */
+  bool hide(const bool hidden);
+
   /**
    * Set the files position to current position + \a pos. See seekSet().
    * \param[in] offset The new position in bytes from the current position.