PowerShell Advanced — Topic #7

Identify Illogical or Out-of-Range Dates

Identificar fechas ilógicas o fuera de rango

Flag records where a calculated date value breaks a business rule, such as employees who appear to be under the minimum age requirement.

Marcar registros donde una fecha calculada rompe una regla de negocio, como empleados que aparentan ser menores de la edad mínima requerida.

FocusEnfoque
Business rule logicLógica de negocio
ToolHerramienta
PowerShell + Date Calculation
OutputResultado
Valid records and exception reportRegistros válidos y reporte de excepciones

Cybersecurity & Production Environment Warning

Advertencia de ciberseguridad y ambiente de producción

This exercise is for learning and testing purposes only. Do not run scripts against production data, network shares, official HR files, student records, patient records, enterprise repositories, or business-critical folders without proper authorization, backups, testing, least-privilege permissions, change-control approval, and compliance with your organization’s cybersecurity policies.

Este ejercicio es solo para aprendizaje y pruebas. No ejecutes scripts contra datos de producción, carpetas compartidas, archivos oficiales de recursos humanos, expedientes de estudiantes, expedientes de pacientes, repositorios empresariales o carpetas críticas sin autorización, respaldos, pruebas, permisos mínimos, aprobación de control de cambios y cumplimiento de las políticas de ciberseguridad de tu organización.

Business Scenario

Escenario de negocio

An employee, student, or applicant file contains birth dates entered from different sources. Some records may contain realistic values, while others may contain dates that create an impossible or risky business condition, such as a person being calculated as younger than the allowed minimum age. These records should be flagged before reporting, onboarding, compliance review, or system import.

Un archivo de empleados, estudiantes o aplicantes contiene fechas de nacimiento ingresadas desde diferentes fuentes. Algunos registros pueden ser correctos, mientras otros pueden generar una condición imposible o riesgosa, como una persona calculada como menor de la edad mínima permitida. Estos registros deben marcarse antes de reportes, contratación, revisión de cumplimiento o importación a sistemas.

Age 25 → ValidAge 17 → ReviewFuture DOB → InvalidBlank DOB → Exception

Learning Objectives

Objetivos de aprendizaje

Sample Input Data

Data de entrada de ejemplo

EmployeeID,Name,FechaNacimiento
1001,Juan Carballo,1985-04-15
1002,Ana Torres,2007-09-10
1003,Pedro Martinez,1992-11-22
1004,Maria Lopez,2030-01-01
1005,Luis Perez,
1006,Carmen Diaz,2010-05-03

Step 1 — Define Source and Output Files

Paso 1 — Definir archivos de entrada y salida

$sourceFile = "C:\Training\employees.csv"
$validFile = "C:\Training\ValidAgeRecords.csv"
$exceptionFile = "C:\Training\AgeExceptions.csv"

Step 2 — Define the Business Rule

Paso 2 — Definir la regla de negocio

In this example, records where the calculated age is under 18 are flagged for review.

En este ejemplo, los registros donde la edad calculada es menor de 18 se marcan para revisión.

$minimumAge = 18
$today = Get-Date

Step 3 — Import the CSV File

Paso 3 — Importar el archivo CSV

$records = Import-Csv -Path $sourceFile

Step 4 — Calculate Age and Flag Exceptions

Paso 4 — Calcular edad y marcar excepciones

$processed = foreach ($record in $records) {
    $status = "Valid"
    $issue = ""
    $age = $null

    if ([string]::IsNullOrWhiteSpace($record.FechaNacimiento)) {
        $status = "Review"
        $issue = "Missing date of birth"
    }
    else {
        try {
            $birthDate = [datetime]$record.FechaNacimiento
            $age = $today.Year - $birthDate.Year

            if ($birthDate.Date -gt $today.AddYears(-$age).Date) {
                $age--
            }

            if ($birthDate -gt $today) {
                $status = "Review"
                $issue = "Future date of birth"
            }
            elseif ($age -lt $minimumAge) {
                $status = "Review"
                $issue = "Under minimum age"
            }
        }
        catch {
            $status = "Review"
            $issue = "Invalid date format"
        }
    }

    $record | Add-Member -NotePropertyName CalculatedAge -NotePropertyValue $age -Force
    $record | Add-Member -NotePropertyName ValidationStatus -NotePropertyValue $status -Force
    $record | Add-Member -NotePropertyName ValidationIssue -NotePropertyValue $issue -Force
    $record
}

Step 5 — Export Valid and Review Records

Paso 5 — Exportar registros válidos y de revisión

$validRecords = $processed | Where-Object { $_.ValidationStatus -eq "Valid" }
$reviewRecords = $processed | Where-Object { $_.ValidationStatus -eq "Review" }

$validRecords | Export-Csv -Path $validFile -NoTypeInformation -Encoding UTF8
$reviewRecords | Export-Csv -Path $exceptionFile -NoTypeInformation -Encoding UTF8

Complete Script

Script completo

$sourceFile = "C:\Training\employees.csv"
$validFile = "C:\Training\ValidAgeRecords.csv"
$exceptionFile = "C:\Training\AgeExceptions.csv"

$minimumAge = 18
$today = Get-Date

$records = Import-Csv -Path $sourceFile

$processed = foreach ($record in $records) {
    $status = "Valid"
    $issue = ""
    $age = $null

    if ([string]::IsNullOrWhiteSpace($record.FechaNacimiento)) {
        $status = "Review"
        $issue = "Missing date of birth"
    }
    else {
        try {
            $birthDate = [datetime]$record.FechaNacimiento
            $age = $today.Year - $birthDate.Year

            if ($birthDate.Date -gt $today.AddYears(-$age).Date) {
                $age--
            }

            if ($birthDate -gt $today) {
                $status = "Review"
                $issue = "Future date of birth"
            }
            elseif ($age -lt $minimumAge) {
                $status = "Review"
                $issue = "Under minimum age"
            }
        }
        catch {
            $status = "Review"
            $issue = "Invalid date format"
        }
    }

    $record | Add-Member -NotePropertyName CalculatedAge -NotePropertyValue $age -Force
    $record | Add-Member -NotePropertyName ValidationStatus -NotePropertyValue $status -Force
    $record | Add-Member -NotePropertyName ValidationIssue -NotePropertyValue $issue -Force
    $record
}

$validRecords = $processed | Where-Object { $_.ValidationStatus -eq "Valid" }
$reviewRecords = $processed | Where-Object { $_.ValidationStatus -eq "Review" }

$validRecords | Export-Csv -Path $validFile -NoTypeInformation -Encoding UTF8
$reviewRecords | Export-Csv -Path $exceptionFile -NoTypeInformation -Encoding UTF8

Write-Host "Valid records: $($validRecords.Count)"
Write-Host "Records for review: $($reviewRecords.Count)"

Expected Result

Resultado esperado

Valid Records

Registros válidos

NameDOBStatus
Juan Carballo1985-04-15Valid
Pedro Martinez1992-11-22Valid

Records for Review

Registros para revisión

NameDOBIssue
Ana Torres2007-09-10Under minimum age
Maria Lopez2030-01-01Future date of birth
Luis PerezMissing date of birth
Carmen Diaz2010-05-03Under minimum age

Validation Checklist

Lista de validación

Professional Notes

Notas profesionales

Out-of-range dates are not always simple formatting errors. They can represent compliance risk, onboarding problems, incorrect source data, or manual entry mistakes. In production environments, records should usually be flagged for review instead of automatically deleted or overwritten.

Las fechas fuera de rango no siempre son simples errores de formato. Pueden representar riesgo de cumplimiento, problemas de contratación, datos incorrectos en la fuente o errores de captura manual. En ambientes de producción, normalmente estos registros deben marcarse para revisión en lugar de eliminarse o sobrescribirse automáticamente.