PowerShell Training · Topic 4

Mover archivos encontrados y no encontrados

Un ejercicio práctico para separar automáticamente lo válido de lo que necesita revisión manual.

Move found and not found files

A hands-on exercise to automatically separate valid files from the ones that need manual review.

⚠️ 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 4

El objetivo es comparar los archivos contra una lista oficial y moverlos a carpetas separadas según el resultado: Found para los que tienen match y Excluded para los que no aparecen en la lista.

01 · Crear data
02 · Separar archivos
03 · Verificar carpetas
Idea central: este topic añade control visual al flujo. No solo detectamos el match; también organizamos físicamente los archivos para revisión.

Topic 4 Objective

The goal is to compare files against an official list and move them into separate folders based on the result: Found for matched files and Excluded for files not found in the list.

01 · Create data
02 · Separate files
03 · Verify folders
Core idea: this topic adds visual control to the workflow. We do not just detect the match; we physically organize files for review.

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 4"

Qué vamos a aprender

  • Crear carpetas de salida: Found y Excluded.
  • Cargar una lista oficial desde CSV.
  • Extraer el ID desde el nombre del archivo.
  • Evaluar con if / else.
  • Mover archivos con Move-Item.

What you will learn

  • Create output folders: Found and Excluded.
  • Load an official list from CSV.
  • Extract the ID from the file name.
  • Evaluate with if / else.
  • Move files with Move-Item.
01

Script 1 — Crear data sintética y carpetas de control

Este script crea una carpeta de práctica, una lista oficial en CSV, varios archivos JPG y dos carpetas de salida: Found y Excluded.

Script 1 — Create synthetic data and control folders

This script creates a practice folder, an official CSV list, several JPG files, and two output folders: Found and Excluded.

# ======================================================
# Topic 4 - Script 1
# Create synthetic files, official CSV, and folders
# ======================================================

$BasePath     = "$env:USERPROFILE\Documents\AI Practical Training\PowerShell\Topic 4"
$SourcePath   = Join-Path $BasePath "Photos"
$FoundPath    = Join-Path $BasePath "Found"
$ExcludedPath = Join-Path $BasePath "Excluded"
$CsvPath      = Join-Path $BasePath "Employees.csv"

New-Item -Path $SourcePath, $FoundPath, $ExcludedPath -ItemType Directory -Force | Out-Null

# Official list of valid Alt IDs
$Employees = @(
    [PSCustomObject]@{ Alt_ID = "7001"; Employee_ID = "10001" },
    [PSCustomObject]@{ Alt_ID = "7002"; Employee_ID = "10002" },
    [PSCustomObject]@{ Alt_ID = "7003"; Employee_ID = "10003" },
    [PSCustomObject]@{ Alt_ID = "7004"; Employee_ID = "10004" },
    [PSCustomObject]@{ Alt_ID = "7005"; Employee_ID = "10005" },
    [PSCustomObject]@{ Alt_ID = "7006"; Employee_ID = "10006" }
)

$Employees | Export-Csv -Path $CsvPath -NoTypeInformation

# Some files are valid, others are intentionally not in the CSV
$Files = @(
    "Photo_7001.jpg",
    "Badge-7002.jpg",
    "Employee 7003 Profile.jpg",
    "Scan_7004_old.jpg",
    "P-7005.jpg",
    "Temp 7006 upload.jpg",
    "NoMatch_8001.jpg",
    "Unknown_8002.jpg",
    "Review_9999.jpg"
)

foreach ($File in $Files) {
    New-Item -Path (Join-Path $SourcePath $File) -ItemType File -Force | Out-Null
}

Write-Host "Training data created in:" $BasePath
Get-ChildItem $SourcePath -Filter "*.jpg" | Select-Object Name
02

Script 2 — Mover encontrados y no encontrados

Este script lee el CSV, revisa cada archivo, extrae el número del nombre y decide si moverlo a Found o a Excluded.

Script 2 — Move found and not found files

This script reads the CSV, checks each file, extracts the number from the name, and decides whether to move it to Found or Excluded.

# ======================================================
# Topic 4 - Script 2
# Move found and not found files
# ======================================================

$BasePath     = "$env:USERPROFILE\Documents\AI Practical Training\PowerShell\Topic 4"
$SourcePath   = Join-Path $BasePath "Photos"
$FoundPath    = Join-Path $BasePath "Found"
$ExcludedPath = Join-Path $BasePath "Excluded"
$CsvPath      = Join-Path $BasePath "Employees.csv"

$Lookup = Import-Csv $CsvPath

Get-ChildItem $SourcePath -Filter "*.jpg" | ForEach-Object {

    # Extract numeric ID from the file name
    $id = $_.BaseName -replace "\D", ""

    # Check if the ID exists in the official list
    $match = $Lookup | Where-Object { $_.Alt_ID -eq $id }

    if ($match) {
        Move-Item -Path $_.FullName -Destination $FoundPath

        [PSCustomObject]@{
            File_Name = $_.Name
            Extracted_ID = $id
            Destination = "Found"
            Status = "Match found"
        }
    }
    else {
        Move-Item -Path $_.FullName -Destination $ExcludedPath

        [PSCustomObject]@{
            File_Name = $_.Name
            Extracted_ID = $id
            Destination = "Excluded"
            Status = "No match found"
        }
    }
}
Prueba segura: antes de mover archivos reales, puedes agregar -WhatIf al final de cada Move-Item para simular la acción sin mover nada.
Safe test: before moving real files, you can add -WhatIf at the end of each Move-Item to simulate the action without moving anything.
03

Script 3 — Verificar resultados

Este script muestra cuántos archivos quedaron en cada carpeta y lista sus nombres para confirmar la separación.

Script 3 — Verify results

This script shows how many files ended up in each folder and lists their names to confirm the separation.

# ======================================================
# Topic 4 - Script 3
# Verify Found and Excluded folders
# ======================================================

$BasePath     = "$env:USERPROFILE\Documents\AI Practical Training\PowerShell\Topic 4"
$FoundPath    = Join-Path $BasePath "Found"
$ExcludedPath = Join-Path $BasePath "Excluded"

Write-Host "FOUND FILES:" -ForegroundColor Green
Get-ChildItem $FoundPath -Filter "*.jpg" | Select-Object Name

Write-Host ""
Write-Host "EXCLUDED FILES:" -ForegroundColor Yellow
Get-ChildItem $ExcludedPath -Filter "*.jpg" | Select-Object Name

Write-Host ""
Write-Host "Summary:"
[PSCustomObject]@{
    Found_Count    = (Get-ChildItem $FoundPath -Filter "*.jpg").Count
    Excluded_Count = (Get-ChildItem $ExcludedPath -Filter "*.jpg").Count
}

Explicación simple del script

  • Import-Csv carga la lista oficial de IDs válidos.
  • $_.BaseName -replace "\D", "" extrae el número desde el nombre del archivo.
  • Where-Object busca si ese número existe en el CSV.
  • if ($match) mueve el archivo a Found.
  • else mueve el archivo a Excluded.

Simple script explanation

  • Import-Csv loads the official list of valid IDs.
  • $_.BaseName -replace "\D", "" extracts the number from the file name.
  • Where-Object checks whether that number exists in the CSV.
  • if ($match) moves the file to Found.
  • else moves the file to Excluded.

Ejemplo esperado

ArchivoIDDestino
Photo_7001.jpg7001Found
Badge-7002.jpg7002Found
NoMatch_8001.jpg8001Excluded
Review_9999.jpg9999Excluded

Expected example

FileIDDestination
Photo_7001.jpg7001Found
Badge-7002.jpg7002Found
NoMatch_8001.jpg8001Excluded
Review_9999.jpg9999Excluded

Conclusión

Este topic enseña cómo separar automáticamente archivos válidos de archivos que necesitan revisión manual. Es una práctica muy útil cuando trabajamos con fotos, documentos, expedientes, escaneos o cargas masivas que dependen de una lista oficial.

Lección clave: no todo archivo debe procesarse igual. Los encontrados avanzan; los no encontrados se aíslan para revisión, evitando errores silenciosos.

Conclusion

This topic teaches how to automatically separate valid files from files that require manual review. It is very useful when working with photos, documents, records, scans, or bulk uploads that depend on an official list.

Key lesson: not every file should be processed the same way. Found files move forward; not found files are isolated for review, preventing silent errors.