If it is about wallpapers, then symbolic links are more plausible option, like a single folder contains links to the images of a folder and subfolders inside it. which can be done via PowerShell script with admin privilege. This will create link of images from source folder to destination folder while iterating subfolders. This is a one time setup and to constantly waching for new image added you can add schedular for it. and you can choose this destination folder for wallpaper shuffling.
$Source = "C:/User/<your user name>/Downloads"
$Destination = "C:/User/<your user name>/Images"
$Extensions = @(
".jpg",
".jpeg",
".png",
".gif",
".webp",
".bmp",
".tif",
".tiff",
".ico",
".svg"
)
# Create destination folder
New-Item -ItemType Directory -Path $Destination -Force | Out-Null
function Get-UniqueName {
param (
[string]$Directory,
[string]$FileName
)
$base = [System.IO.Path]::GetFileNameWithoutExtension($FileName)
$ext = [System.IO.Path]::GetExtension($FileName)
$candidate = Join-Path $Directory $FileName
$counter = 1
while (Test-Path $candidate) {
$newName = "$base ($counter)$ext"
$candidate = Join-Path $Directory $newName
$counter++
}
return $candidate
}
function Sync-Images {
Write-Host "Syncing images..."
$files = Get-ChildItem `
-Path $Source `
-File `
-Recurse `
-ErrorAction SilentlyContinue |
Where-Object {
$Extensions -contains $_.Extension.ToLower()
}
# Track original files
$existingTargets = @{}
foreach ($file in $files) {
$existingLink = Get-ChildItem $Destination -File |
Where-Object {
$_.LinkType -eq "SymbolicLink" -and
$_.Target -eq $file.FullName
} |
Select-Object -First 1
if ($existingLink) {
$existingTargets[$existingLink.FullName] = $true
continue
}
$targetPath = Get-UniqueName `
-Directory $Destination `
-FileName $file.Name
try {
New-Item `
-ItemType SymbolicLink `
-Path $targetPath `
-Target $file.FullName `
-ErrorAction Stop | Out-Null
$existingTargets[$targetPath] = $true
Write-Host "Added: $($file.Name)"
}
catch {
Write-Host "Could not create link: $($file.Name)"
}
}
# Remove broken / obsolete symbolic links
Get-ChildItem $Destination -File -ErrorAction SilentlyContinue |
Where-Object {
$_.LinkType -eq "SymbolicLink"
} |
ForEach-Object {
if (-not (Test-Path $_.Target)) {
Write-Host "Removing: $($_.Name)"
Remove-Item $_.FullName -Force
}
}
Write-Host "Sync complete."
}
# Initial synchronization
Sync-Images
# Watch Downloads
$Watcher = New-Object System.IO.FileSystemWatcher
$Watcher.Path = $Source
$Watcher.IncludeSubdirectories = $true
$Watcher.NotifyFilter = `
[System.IO.NotifyFilters]'FileName, LastWrite, DirectoryName'
$Watcher.EnableRaisingEvents = $true
# Prevent multiple simultaneous syncs
$Global:SyncRunning = $false
function Trigger-Sync {
if ($Global:SyncRunning) {
return
}
$Global:SyncRunning = $true
Start-Sleep -Seconds 2
Sync-Images
$Global:SyncRunning = $false
}
Register-ObjectEvent `
-InputObject $Watcher `
-EventName Created `
-Action { Trigger-Sync } | Out-Null
Register-ObjectEvent `
-InputObject $Watcher `
-EventName Deleted `
-Action { Trigger-Sync } | Out-Null
Register-ObjectEvent `
-InputObject $Watcher `
-EventName Changed `
-Action { Trigger-Sync } | Out-Null
Register-ObjectEvent `
-InputObject $Watcher `
-EventName Renamed `
-Action { Trigger-Sync } | Out-Null
Write-Host ""
Write-Host "===================================="
Write-Host " Download Image Sync is running"
Write-Host "===================================="
Write-Host ""
Write-Host "Source: $Source"
Write-Host "Destination: $Destination"
Write-Host ""
Write-Host "Press Ctrl+C to stop."
Write-Host ""
while ($true) {
Wait-Event -Timeout 10 | Out-Null
}