In order to prevent the cloud drive from scanning my files, I need to encrypt all the content I upload. I use 7z software to encrypt individually. My requirements:
- Encrypt all files and folders in the entire directory individually and export them to another directory
- Preserve the original directory structure for all files and folders
- Store without compression (so that 7z can encrypt quickly)
This is a test folder
D:.
│ beach-dominican-republic-dominican-caribbean-thumb.jpg
│ 砂浜の上.jpg
│
├───3人z#@@%R@$%T434b4y
│ autumn-forest-woods-nature-thumb.jpg
│ D'accord.jpg
│ Жаалгада.jpg
│ Хорошо.jpg
│ 梦幻手绘绿色风景桌面壁纸.jpg
│
├───dfわかったght3%^&&$&%%
│ │ Hoy.jpg
│ │ No, ¿verdad.jpg
│ │ ¿Quién eres.jpg
│ │
│ └───Está bien, no se puede
│ cars-old-vintage-automobiles-classic-preview.jpg
│ casserole-seafood-paella-food-preview.jpg
│ 新しく来てください.jpg
│ 明日にしましょう.jpg
│
└───حسنًاreq!!f fgr
│ Neu hier.jpg
│ ربما غدًا.jpg
│ لا بالتأكيد.jpg
│ لا يمكن.jpg
│
└───二哥!!#¥#
burger-cheese-vegetarian-halloumi-preview.jpg
cake-cafeteria-desserts-dessert-preview.jpg
I had AI write a PowerShell script test.ps1:
# Configuration Parameters
$sourceDir = "D:\test\private thing" # Source directory to be encrypted
$targetDir = "D:\test\private thing - Encryption" # Target root directory for storing encrypted files
$password = "123" # password
$sevenZipPath = "C:\Program Files\7-Zip\7z.exe" # 7z path
# Check if 7z exists
if (-not (Test-Path $sevenZipPath)) {
Write-Error "Cannot find 7z.exe, please check the path"
exit 1
}
# Get all files (recursive)
Get-ChildItem -Path $sourceDir -File -Recurse | ForEach-Object {
$file = $_
# Calculate relative path
$relativePath = $file.Directory.FullName.Substring($sourceDir.Length).TrimStart('\')
# Construct target directory path
if ($relativePath) {
$targetFilePath = Join-Path $targetDir $relativePath
} else {
$targetFilePath = $targetDir
}
# Create the target directory (if it does not exist)
if (-not (Test-Path $targetFilePath)) {
New-Item -ItemType Directory -Path $targetFilePath -Force | Out-Null
}
# Construct 7z file path
$archiveName = $file.Name + ".7z"
$archivePath = Join-Path $targetFilePath $archiveName
# Compress and encrypt using 7z
& "$sevenZipPath" a -mx0 "-p$password" -mhe=on "$archivePath" "$($file.FullName)" -y
if ($LASTEXITCODE -eq 0) {
Write-Host "Encrypted: $($file.FullName) -> $archivePath" -ForegroundColor Green
} else {
Write-Host "Encryption failed: $($file.FullName)" -ForegroundColor Red
}
}
Write-Host "`nAll file processing is complete!" -ForegroundColor Green
Among them, $sourceDir, $targetDir, $password, and $sevenZipPath are variables that need to be modified according to your own needs.
Run a script using PowerShell
powershell -ExecutionPolicy Bypass -File .\test.ps1
After the script execution is complete, this is the output folder structure
D:.
│ beach-dominican-republic-dominican-caribbean-thumb.jpg.7z
│ 砂浜の上.jpg.7z
│
├─3人z#@@%R@$%T434b4y
│ autumn-forest-woods-nature-thumb.jpg.7z
│ D'accord.jpg.7z
│ Жаалгада.jpg.7z
│ Хорошо.jpg.7z
│ 梦幻手绘绿色风景桌面壁纸.jpg.7z
│
├─dfわかったght3%^&&$&%%
│ │ Hoy.jpg.7z
│ │ No, ¿verdad.jpg.7z
│ │ ¿Quién eres.jpg.7z
│ │
│ └─Está bien, no se puede
│ cars-old-vintage-automobiles-classic-preview.jpg.7z
│ casserole-seafood-paella-food-preview.jpg.7z
│ 新しく来てください.jpg.7z
│ 明日にしましょう.jpg.7z
│
└─حسنًاreq!!f fgr
│ Neu hier.jpg.7z
│ ربما غدًا.jpg.7z
│ لا بالتأكيد.jpg.7z
│ لا يمكن.jpg.7z
│
└─二哥!!#¥#
burger-cheese-vegetarian-halloumi-preview.jpg.7z
cake-cafeteria-desserts-dessert-preview.jpg.7z
This script can complete the task.
If you don't want the names to be known either, you can directly convert all paths into MD5 encoding.
# Configuration Parameters
$sourceDir = "D:\test\private thing" # Source directory to be encrypted
$targetDir = "D:\test\private thing - Encryption" # Target root directory for storing encrypted files
$password = "123" # password
$sevenZipPath = "C:\Program Files\7-Zip\7z.exe" # 7z path
# Create MD5 hash function
function Get-MD5Hash {
param([string]$InputString)
$md5 = [System.Security.Cryptography.MD5]::Create()
$bytes = [System.Text.Encoding]::UTF8.GetBytes($InputString)
$hash = $md5.ComputeHash($bytes)
# Convert to lowercase hexadecimal string
return ($hash | ForEach-Object { $_.ToString("x2") }) -join ''
}
# Check if 7z exists
if (-not (Test-Path $sevenZipPath)) {
Write-Error "Cannot find 7z.exe, please check the path"
exit 1
}
# Get all files (recursive)
Get-ChildItem -Path $sourceDir -File -Recurse | ForEach-Object {
$file = $_
# Calculate relative path
$relativePath = $file.Directory.FullName.Substring($sourceDir.Length).TrimStart('\')
# Split the path and hash each folder separately
if ($relativePath) {
$pathParts = $relativePath.Split('\')
$hashedPathParts = @()
foreach ($part in $pathParts) {
# Perform MD5 hashing on each folder name
$hashedPart = Get-MD5Hash -InputString $part
$hashedPathParts += $hashedPart
}
# Recombining the hashed path
$hashedPath = $hashedPathParts -join '\'
$targetFilePath = Join-Path $targetDir $hashedPath
} else {
$targetFilePath = $targetDir
}
# Create the target directory (if it does not exist)
if (-not (Test-Path $targetFilePath)) {
New-Item -ItemType Directory -Path $targetFilePath -Force | Out-Null
}
# Perform MD5 hashing on the entire file name (including the extension)
$fullFileName = $file.Name
$hashedFileName = Get-MD5Hash -InputString $fullFileName
# Construct 7z file path
$archiveName = $hashedFileName + ".7z"
$archivePath = Join-Path $targetFilePath $archiveName
# Compress and encrypt using 7z
& "$sevenZipPath" a -mx0 "-p$password" -mhe=on "$archivePath" "$($file.FullName)" -y
if ($LASTEXITCODE -eq 0) {
Write-Host "Encrypted: $($file.FullName) -> $archivePath" -ForegroundColor Green
} else {
Write-Host "Encryption failed: $($file.FullName)" -ForegroundColor Red
}
}
Write-Host "`nAll file processing is complete!" -ForegroundColor Green
After this, the encrypted folder:
D:.
│ 43794276ebe0b4a5c9ac57c9f3d22898.7z
│ 6c5aa696b01f76db7ef074536b03ed9a.7z
│
├─0eb68956079d3cb6962dc2dc49f01be4
│ │ 2763897780a0e2e645ec4d2e41556306.7z
│ │ 430890ddd152b3c455a1478279e47a7b.7z
│ │ c430b7629217efeea6badf39a65cc058.7z
│ │
│ └─21e933b76e03210646eede333e76b4dd
│ 42bde53eaf003f3dc4f3738294ae1464.7z
│ 612faac79f62c16eaeacc2f75fbe19c8.7z
│ 841d69a443b3701e7e9f55c511c58892.7z
│ e80cd4e138ecfae6846fd301b3f1a902.7z
│
├─2864dfea338f51a4579757ef81773061
│ 456532e2f62fc75477bd0f1e1476a13b.7z
│ 5ea01eb5a08b21d42e2f209a3fa713bf.7z
│ 735dbc38b8fb2b016c660cdfb2b242df.7z
│ c47fcce46e5e29e8f039acbeecf85647.7z
│ cb3af4320d1388fa6cfbe98a6dae91f5.7z
│
└─fe9e0e69fda49d513796cd5fdca66f24
│ 1b719344629ccf638066ecd2781cdd5d.7z
│ 635164eead60d30732f45a464811333a.7z
│ b9d1f953b32f034acda5b049ee6797f8.7z
│ e8f3dc25e3e56ce0d8bdc560dd267f76.7z
│
└─42fb902ad1ed5cee820e4b314324e29a
4f82a3dde34e3eb1c9e42e610882001e.7z
f19a29f5e526cf04369ea2a3ddd67c55.7z
But in this way, I won't be able to know which encrypted file path corresponds to the original file. I need to output an encrypted txt file to store these mappings. So the script later became like this.
# Configuration Parameters
$sourceDir = "D:\test\private thing" # Source directory to be encrypted
$targetDir = "D:\test\private thing - Encryption" # Target root directory for storing encrypted files
$password = "123" # password
$sevenZipPath = "C:\Program Files\7-Zip\7z.exe" # 7z path
$mapFileName = "encryption_map.txt" # Mapping file name
$mapFile = Join-Path $targetDir $mapFileName # Full path to mapping file
# Create MD5 hash function
function Get-MD5Hash {
param([string]$InputString)
$md5 = [System.Security.Cryptography.MD5]::Create()
$bytes = [System.Text.Encoding]::UTF8.GetBytes($InputString)
$hash = $md5.ComputeHash($bytes)
# Convert to lowercase hexadecimal string
return ($hash | ForEach-Object { $_.ToString("x2") }) -join ''
}
# Initialize mapping content
$mappingContent = @"
ENCRYPTION MAPPING FILE
===============================================
Generated on: $(Get-Date)
Original Path -> Encrypted Path
===============================================
"@
# Check if 7z exists
if (-not (Test-Path $sevenZipPath)) {
Write-Error "Cannot find 7z.exe, please check the path"
exit 1
}
# Create target directory if it doesn't exist
if (-not (Test-Path $targetDir)) {
New-Item -ItemType Directory -Path $targetDir -Force | Out-Null
}
# Get all files (recursive)
Get-ChildItem -Path $sourceDir -File -Recurse | ForEach-Object {
$file = $_
# Calculate relative path
$relativePath = $file.Directory.FullName.Substring($sourceDir.Length).TrimStart('\')
# Split the path and hash each folder separately
if ($relativePath) {
$pathParts = $relativePath.Split('\')
$hashedPathParts = @()
$originalPathParts = @()
foreach ($part in $pathParts) {
# Store original folder name for mapping
$originalPathParts += $part
# Perform MD5 hashing on each folder name
$hashedPart = Get-MD5Hash -InputString $part
$hashedPathParts += $hashedPart
}
# Recombining the hashed path
$hashedPath = $hashedPathParts -join '\'
$targetFilePath = Join-Path $targetDir $hashedPath
# Store original folder path for mapping
$originalFolderPath = $originalPathParts -join '\'
} else {
$targetFilePath = $targetDir
$originalFolderPath = ""
}
# Create the target directory (if it does not exist)
if (-not (Test-Path $targetFilePath)) {
New-Item -ItemType Directory -Path $targetFilePath -Force | Out-Null
}
# Perform MD5 hashing on the entire file name (including the extension)
$fullFileName = $file.Name
$hashedFileName = Get-MD5Hash -InputString $fullFileName
# Construct 7z file path
$archiveName = $hashedFileName + ".7z"
$archivePath = Join-Path $targetFilePath $archiveName
# Compress and encrypt using 7z
& "$sevenZipPath" a -mx0 "-p$password" -mhe=on "$archivePath" "$($file.FullName)" -y
if ($LASTEXITCODE -eq 0) {
Write-Host "Encrypted: $($file.FullName) -> $archivePath" -ForegroundColor Green
# Prepare mapping entry
if ($originalFolderPath) {
$originalRelativePath = "\$originalFolderPath\$fullFileName"
$encryptedRelativePath = "\$hashedPath\$archiveName"
} else {
$originalRelativePath = "\$fullFileName"
$encryptedRelativePath = "\$archiveName"
}
# Add to mapping content
$mappingContent += "ORIGINAL: $originalRelativePath`r`n"
$mappingContent += "ENCRYPTED: $encryptedRelativePath`r`n"
$mappingContent += "-" * 60 + "`r`n"
Write-Host " Mapping: $originalRelativePath --> $encryptedRelativePath" -ForegroundColor Yellow
} else {
Write-Host "Encryption failed: $($file.FullName)" -ForegroundColor Red
}
}
# Add footer to mapping content
$mappingContent += "`r`n"
$mappingContent += "===============================================`r`n"
$mappingContent += "Total files processed: $($mappingContent.Split('ORIGINAL:').Count - 1)`r`n"
$mappingContent += "End of mapping file`r`n"
$mappingContent += "===============================================`r`n"
# Save the mapping file temporarily as unencrypted
$tempMapFile = $mapFile
Set-Content -Path $tempMapFile -Value $mappingContent -Encoding UTF8
Write-Host "`nCreating encrypted mapping file..." -ForegroundColor Cyan
# Encrypt the mapping file with the same password
$encryptedMapFile = $mapFile + ".7z"
& "$sevenZipPath" a -mx0 "-p$password" -mhe=on "$encryptedMapFile" "$tempMapFile" -y
if ($LASTEXITCODE -eq 0) {
# Remove the temporary unencrypted file
Remove-Item $tempMapFile -Force
Write-Host "Mapping file created and encrypted: $encryptedMapFile" -ForegroundColor Green
Write-Host "" -ForegroundColor Green
Write-Host "IMPORTANT NOTES:" -ForegroundColor Yellow
Write-Host "1. The mapping file is encrypted with the same password: $password" -ForegroundColor Yellow
Write-Host "2. To view the mapping file, use: 7z e $encryptedMapFile -p$password" -ForegroundColor Yellow
Write-Host "3. Keep this password safe - without it you cannot recover the original file names!" -ForegroundColor Red
} else {
Write-Host "Failed to encrypt mapping file!" -ForegroundColor Red
Write-Host "Unencrypted mapping file is saved as: $tempMapFile" -ForegroundColor Yellow
}
Write-Host "`nAll file processing is complete!" -ForegroundColor Green
It will eventually output an encryption_map.txt.7z file in the root path of the target directory, using the same encryption password. After decryption, you can see the mapping of file paths before and after encryption. This file can be used to find the original file locations:
ENCRYPTION MAPPING FILE
===============================================
Generated on: 03/02/2026 20:36:47
Original Path -> Encrypted Path
===============================================
ORIGINAL: \beach-dominican-republic-dominican-caribbean-thumb.jpg
ENCRYPTED: \6c5aa696b01f76db7ef074536b03ed9a.7z
------------------------------------------------------------
ORIGINAL: \砂浜の上.jpg
ENCRYPTED: \43794276ebe0b4a5c9ac57c9f3d22898.7z
------------------------------------------------------------
ORIGINAL: \3人z#@@%R@$%T434b4y\autumn-forest-woods-nature-thumb.jpg
ENCRYPTED: \2864dfea338f51a4579757ef81773061\c47fcce46e5e29e8f039acbeecf85647.7z
------------------------------------------------------------
ORIGINAL: \3人z#@@%R@$%T434b4y\D'accord.jpg
ENCRYPTED: \2864dfea338f51a4579757ef81773061\456532e2f62fc75477bd0f1e1476a13b.7z
------------------------------------------------------------
ORIGINAL: \3人z#@@%R@$%T434b4y\Жаалгада.jpg
ENCRYPTED: \2864dfea338f51a4579757ef81773061\cb3af4320d1388fa6cfbe98a6dae91f5.7z
------------------------------------------------------------
ORIGINAL: \3人z#@@%R@$%T434b4y\Хорошо.jpg
ENCRYPTED: \2864dfea338f51a4579757ef81773061\5ea01eb5a08b21d42e2f209a3fa713bf.7z
------------------------------------------------------------
ORIGINAL: \3人z#@@%R@$%T434b4y\梦幻手绘绿色风景桌面壁纸.jpg
ENCRYPTED: \2864dfea338f51a4579757ef81773061\735dbc38b8fb2b016c660cdfb2b242df.7z
------------------------------------------------------------
ORIGINAL: \dfわかったght3%^&&$&%%\Hoy.jpg
ENCRYPTED: \0eb68956079d3cb6962dc2dc49f01be4\2763897780a0e2e645ec4d2e41556306.7z
------------------------------------------------------------
ORIGINAL: \dfわかったght3%^&&$&%%\No, ¿verdad.jpg
ENCRYPTED: \0eb68956079d3cb6962dc2dc49f01be4\c430b7629217efeea6badf39a65cc058.7z
------------------------------------------------------------
ORIGINAL: \dfわかったght3%^&&$&%%\¿Quién eres.jpg
ENCRYPTED: \0eb68956079d3cb6962dc2dc49f01be4\430890ddd152b3c455a1478279e47a7b.7z
------------------------------------------------------------
ORIGINAL: \dfわかったght3%^&&$&%%\Está bien, no se puede\cars-old-vintage-automobiles-classic-preview.jpg
ENCRYPTED: \0eb68956079d3cb6962dc2dc49f01be4\21e933b76e03210646eede333e76b4dd\841d69a443b3701e7e9f55c511c58892.7z
------------------------------------------------------------
ORIGINAL: \dfわかったght3%^&&$&%%\Está bien, no se puede\casserole-seafood-paella-food-preview.jpg
ENCRYPTED: \0eb68956079d3cb6962dc2dc49f01be4\21e933b76e03210646eede333e76b4dd\e80cd4e138ecfae6846fd301b3f1a902.7z
------------------------------------------------------------
ORIGINAL: \dfわかったght3%^&&$&%%\Está bien, no se puede\新しく来てください.jpg
ENCRYPTED: \0eb68956079d3cb6962dc2dc49f01be4\21e933b76e03210646eede333e76b4dd\612faac79f62c16eaeacc2f75fbe19c8.7z
------------------------------------------------------------
ORIGINAL: \dfわかったght3%^&&$&%%\Está bien, no se puede\明日にしましょう.jpg
ENCRYPTED: \0eb68956079d3cb6962dc2dc49f01be4\21e933b76e03210646eede333e76b4dd\42bde53eaf003f3dc4f3738294ae1464.7z
------------------------------------------------------------
ORIGINAL: \حسنًاreq!!f fgr\Neu hier.jpg
ENCRYPTED: \fe9e0e69fda49d513796cd5fdca66f24\e8f3dc25e3e56ce0d8bdc560dd267f76.7z
------------------------------------------------------------
ORIGINAL: \حسنًاreq!!f fgr\ربما غدًا.jpg
ENCRYPTED: \fe9e0e69fda49d513796cd5fdca66f24\1b719344629ccf638066ecd2781cdd5d.7z
------------------------------------------------------------
ORIGINAL: \حسنًاreq!!f fgr\لا بالتأكيد.jpg
ENCRYPTED: \fe9e0e69fda49d513796cd5fdca66f24\635164eead60d30732f45a464811333a.7z
------------------------------------------------------------
ORIGINAL: \حسنًاreq!!f fgr\لا يمكن.jpg
ENCRYPTED: \fe9e0e69fda49d513796cd5fdca66f24\b9d1f953b32f034acda5b049ee6797f8.7z
------------------------------------------------------------
ORIGINAL: \حسنًاreq!!f fgr\二哥!!#¥#\burger-cheese-vegetarian-halloumi-preview.jpg
ENCRYPTED: \fe9e0e69fda49d513796cd5fdca66f24\42fb902ad1ed5cee820e4b314324e29a\f19a29f5e526cf04369ea2a3ddd67c55.7z
------------------------------------------------------------
ORIGINAL: \حسنًاreq!!f fgr\二哥!!#¥#\cake-cafeteria-desserts-dessert-preview.jpg
ENCRYPTED: \fe9e0e69fda49d513796cd5fdca66f24\42fb902ad1ed5cee820e4b314324e29a\4f82a3dde34e3eb1c9e42e610882001e.7z
------------------------------------------------------------
===============================================
Total files processed: 263
End of mapping file
===============================================
At this stage, you can avoid your files being scanned by certain cloud drive services. They cannot know the file names, cannot unzip compressed files, and cannot view the list of files inside the compressed files. For yourself, the most important thing is to properly save the encryption_map.txt.7z file and the password.
If you need to specify the input and output directories in the parameters, rather than hardcoding them in the script, you can modify it like this directly.
Delete
$sourceDir = "D:\test\private thing"
$targetDir = "D:\test\private thing - Encryption"
Replace with
param(
[Parameter(Mandatory=$true)]
[string]$sourceDir,
[Parameter(Mandatory=$true)]
[string]$targetDir
)
This way, when executing the script, it can be
.\test.ps1 -sourceDir "D:\test\private thing" -targetDir "D:\test\private thing - Encryption"
Or use positional arguments
.\test.ps1 "D:\test\private thing" "D:\test\private thing - Encryption"
The execution policy of PowerShell may restrict scripts from running directly, showing the prompt:
test.ps1 cannot be loaded because running scripts is disabled on this system.
You can execute the script using this command
powershell -ExecutionPolicy Bypass -File .\test.ps1
If you want to run the script directly, you need to enter the following command in the PowerShell window first
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
Then enter y
Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic at
https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): y
After that, you can directly execute the script.
.\test.ps1
Some cloud storage services limit file size. If you need to split large files for compression, for example, a maximum of 3900MB, you can modify some code.
# Check file size (convert to MB)
$fileSizeMB = $file.Length / 1MB
# Compress and encrypt using 7z
if ($fileSizeMB -gt 3900) {
& "$sevenZipPath" a -mx0 "-p$password" -mhe=on -v3900m "$archivePath" "$($file.FullName)" -y
} else {
& "$sevenZipPath" a -mx0 "-p$password" -mhe=on "$archivePath" "$($file.FullName)" -y
}