⚠️ Advertencia crítica antes de correr cualquier script
No ejecutes este tipo de script en un ambiente de producción, carpeta real, servidor compartido, unidad de red o sistema institucional sin autorización formal.
PowerShell es una herramienta poderosa: un comando de renombrado masivo puede modificar cientos o miles de archivos en segundos. En una carpeta equivocada, eso puede causar pérdida de trazabilidad, fallos en procesos automáticos, interrupciones operativas o incidentes de ciberseguridad.
Regla obligatoria del training: primero se trabaja con data sintética, luego se valida con una muestra pequeña, después se prueba con -WhatIf cuando aplique, y solo entonces se considera ejecutar en datos reales siguiendo los protocolos de la organización.
- Permisos: usa solamente carpetas donde tengas autorización explícita.
- Backups: confirma que exista copia de seguridad o posibilidad real de recuperación.
- Cybersecurity: cumple las políticas internas, controles de acceso, change management y principios de menor privilegio.
- Producción: nunca ejecutes scripts masivos directamente sobre producción sin revisión, aprobación y plan de reversa.
⚠️ Critical warning before running any script
Do not run this type of script in a production environment, real folder, shared server, network drive, or institutional system without formal authorization.
PowerShell is a powerful tool: a bulk command can modify hundreds or thousands of files in seconds. In the wrong folder, it can break traceability, disrupt automated processes, create operational issues, or trigger cybersecurity incidents.
Mandatory training rule: start with synthetic data, validate with a small sample, test with -WhatIf when applicable, and only then consider real data while following your organization’s protocols.
- Permissions: use only folders where you have explicit authorization.
- Backups: confirm that a backup or real recovery option exists.
- Cybersecurity: follow internal policies, access controls, change management, and least-privilege principles.
- Production: never run bulk scripts directly on production without review, approval, and rollback planning.
Objetivo del Topic 6
El objetivo es detectar duplicados usando el contenido del archivo, no solamente el nombre. Para eso usamos Get-FileHash, que genera una huella digital del archivo. Si dos archivos tienen el mismo hash, su contenido es igual.
Topic 6 Objective
The goal is to detect duplicates using the file content, not just the file name. For that we use Get-FileHash, which creates a digital fingerprint of the file. If two files have the same hash, their content is identical.
Ruta de trabajo
Todo se ejecuta dentro de una carpeta controlada:
Working folder
Everything runs inside a controlled folder:
$BasePath = "$env:USERPROFILE\Documents\AI Practical Training\PowerShell\Topic 6"
Qué vamos a aprender
- Crear archivos con el mismo contenido y nombres diferentes.
- Calcular hash con Get-FileHash.
- Agrupar archivos por hash con Group-Object.
- Detectar grupos donde el conteo sea mayor que 1.
- Exportar un reporte de duplicados por contenido.
What you will learn
- Create files with the same content and different names.
- Calculate hashes with Get-FileHash.
- Group files by hash with Group-Object.
- Detect groups where the count is greater than 1.
- Export a content-based duplicate report.
Script 1 — Crear data sintética con duplicados reales
Este script crea archivos de práctica. Algunos tienen nombres diferentes, pero exactamente el mismo contenido. Eso permite probar duplicados por hash.
Script 1 — Create synthetic data with real duplicates
This script creates practice files. Some have different names but exactly the same content. This allows us to test hash-based duplicates.
# ======================================================
# Topic 6 - Script 1
# Create synthetic files with duplicate content
# ======================================================
$BasePath = "$env:USERPROFILE\Documents\AI Practical Training\PowerShell\Topic 6"
$PhotosPath = Join-Path $BasePath "Photos"
New-Item -Path $PhotosPath -ItemType Directory -Force | Out-Null
# Same content, different file names
"EMPLOYEE_PHOTO_A" | Set-Content -Path (Join-Path $PhotosPath "10001.jpg")
"EMPLOYEE_PHOTO_A" | Set-Content -Path (Join-Path $PhotosPath "Copy_John_Profile.jpg")
"EMPLOYEE_PHOTO_B" | Set-Content -Path (Join-Path $PhotosPath "10002.jpg")
"EMPLOYEE_PHOTO_B" | Set-Content -Path (Join-Path $PhotosPath "Old_Badge_7002.jpg")
# Unique files
"EMPLOYEE_PHOTO_C" | Set-Content -Path (Join-Path $PhotosPath "10003.jpg")
"EMPLOYEE_PHOTO_D" | Set-Content -Path (Join-Path $PhotosPath "10004.jpg")
"EMPLOYEE_PHOTO_E" | Set-Content -Path (Join-Path $PhotosPath "Temp_Upload_9999.jpg")
Write-Host "Synthetic files created in:" $PhotosPath
Get-ChildItem $PhotosPath -File | Select-Object Name, Length
Script 2 — Detectar duplicados por hash
Este script calcula el hash de cada archivo, agrupa los archivos por hash y muestra solamente los grupos donde hay más de un archivo con el mismo contenido.
Script 2 — Detect duplicates by hash
This script calculates the hash of each file, groups files by hash, and shows only the groups where more than one file has the same content.
# ======================================================
# Topic 6 - Script 2
# Detect duplicate files by hash
# ======================================================
$BasePath = "$env:USERPROFILE\Documents\AI Practical Training\PowerShell\Topic 6"
$PhotosPath = Join-Path $BasePath "Photos"
Get-ChildItem $PhotosPath -File |
Get-FileHash |
Group-Object Hash |
Where-Object { $_.Count -gt 1 } |
ForEach-Object {
[PSCustomObject]@{
Hash = $_.Name
Duplicate_Count = $_.Count
Files = ($_.Group.Path -join " | ")
}
}
Script 3 — Exportar reporte de duplicados por hash
Este script genera un CSV con cada archivo duplicado, el hash detectado y el grupo al que pertenece.
Script 3 — Export hash duplicate report
This script generates a CSV with each duplicate file, the detected hash, and the group it belongs to.
# ======================================================
# Topic 6 - Script 3
# Export duplicate hash report
# ======================================================
$BasePath = "$env:USERPROFILE\Documents\AI Practical Training\PowerShell\Topic 6"
$PhotosPath = Join-Path $BasePath "Photos"
$ReportPath = Join-Path $BasePath "Duplicate_Hash_Report.csv"
$HashData = Get-ChildItem $PhotosPath -File | Get-FileHash
$DuplicateHashes = $HashData |
Group-Object Hash |
Where-Object { $_.Count -gt 1 }
$Report = foreach ($Group in $DuplicateHashes) {
foreach ($File in $Group.Group) {
[PSCustomObject]@{
Hash = $Group.Name
Duplicate_Count = $Group.Count
File_Path = $File.Path
}
}
}
$Report | Export-Csv -Path $ReportPath -NoTypeInformation
Write-Host "Duplicate hash report created:"
Write-Host $ReportPath
$Report
Explicación simple del script
- Get-ChildItem -File obtiene los archivos de la carpeta.
- Get-FileHash calcula la huella digital de cada archivo.
- Group-Object Hash agrupa archivos con el mismo hash.
- Where-Object Count -gt 1 deja solo los grupos duplicados.
- Export-Csv guarda el resultado para revisión.
Simple script explanation
- Get-ChildItem -File gets the files from the folder.
- Get-FileHash calculates the digital fingerprint of each file.
- Group-Object Hash groups files with the same hash.
- Where-Object Count -gt 1 keeps only duplicate groups.
- Export-Csv saves the result for review.
Ejemplo esperado
| Contenido duplicado | Archivos detectados |
|---|---|
| EMPLOYEE_PHOTO_A | 10001.jpg / Copy_John_Profile.jpg |
| EMPLOYEE_PHOTO_B | 10002.jpg / Old_Badge_7002.jpg |
Expected example
| Duplicate content | Detected files |
|---|---|
| EMPLOYEE_PHOTO_A | 10001.jpg / Copy_John_Profile.jpg |
| EMPLOYEE_PHOTO_B | 10002.jpg / Old_Badge_7002.jpg |
Conclusión
Este topic enseña una forma más confiable de detectar duplicados: no por el nombre, sino por el contenido real del archivo. Esto es clave cuando los archivos fueron copiados, renombrados o descargados varias veces con nombres distintos.
Conclusion
This topic teaches a more reliable way to detect duplicates: not by name, but by the actual content of the file. This matters when files were copied, renamed, or downloaded multiple times with different names.