PowerShell Advanced Series

19. Enmascarar datos sensibles (PII)

19. Mask Sensitive Data (PII)

Ocultar los primeros dígitos de un ID, número de seguro o cuenta, dejando solo los últimos 4 visibles antes de compartir el reporte.

Hide the first digits of an ID, social security number, or account number, leaving only the last 4 visible before sharing the report.

⚠️ Advertencia de ciberseguridad, privacidad y producción ⚠️ Cybersecurity, privacy, and production warning

Este ejercicio es solo para aprendizaje y pruebas. No ejecutes scripts contra datos reales, PII, ambientes de producción, carpetas compartidas, sistemas críticos o repositorios empresariales sin autorización, respaldos, pruebas previas, permisos mínimos, control de cambios y cumplimiento de los protocolos de ciberseguridad y privacidad de tu organización.

This exercise is for learning and testing only. Do not run scripts against real data, PII, production environments, shared folders, critical systems, or enterprise repositories without authorization, backups, prior testing, least-privilege permissions, change control, and compliance with your organization's cybersecurity and privacy protocols.

Objetivo del ejercicio

Exercise objective

Crear una versión compartible de un archivo donde los valores sensibles queden protegidos. La idea es conservar una referencia mínima para auditoría, pero evitar exponer el identificador completo.

Create a shareable version of a file where sensitive values are protected. The idea is to keep a minimal reference for audit purposes while avoiding exposure of the full identifier.

Datos sintéticos

Synthetic data

EmployeeIDNombreSSNCuenta
1001Ana Perez1234567899876543210
1002John Smith5556677771234509876
1003Maria Lopez8889900004567890123
1004Robert Diaz2223344447890123456

Ejemplo base

Base example

$idOriginal = $_.SSN
$_.SSN_Masked = "***-**-" + $idOriginal.Substring($idOriginal.Length - 4)

Resultado esperado

Expected result

EmployeeIDNombreSSN_MaskedCuenta_Masked
1001Ana Perez***-**-6789******3210
1002John Smith***-**-7777******9876
1003Maria Lopez***-**-0000******0123
1004Robert Diaz***-**-4444******3456

Script completo

Complete script

# ==========================================================
# PowerShell Advanced Topic 19
# Mask Sensitive Data / PII
# ==========================================================

$inputFile  = "C:\Data\Employee_Master.csv"
$outputFile = "C:\Data\Employee_Master_Masked.csv"

$datos = Import-Csv $inputFile

$resultado = foreach ($row in $datos) {

    # Keep original values in memory only
    $ssnOriginal    = [string]$row.SSN
    $cuentaOriginal = [string]$row.Cuenta

    # Mask SSN: show only last 4 digits
    if ($ssnOriginal.Length -ge 4) {
        $row | Add-Member -NotePropertyName "SSN_Masked" `
            -NotePropertyValue ("***-**-" + $ssnOriginal.Substring($ssnOriginal.Length - 4)) -Force
    }
    else {
        $row | Add-Member -NotePropertyName "SSN_Masked" -NotePropertyValue "INVALID" -Force
    }

    # Mask account number: show only last 4 digits
    if ($cuentaOriginal.Length -ge 4) {
        $row | Add-Member -NotePropertyName "Cuenta_Masked" `
            -NotePropertyValue ("******" + $cuentaOriginal.Substring($cuentaOriginal.Length - 4)) -Force
    }
    else {
        $row | Add-Member -NotePropertyName "Cuenta_Masked" -NotePropertyValue "INVALID" -Force
    }

    # Remove original sensitive fields before exporting
    $row.PSObject.Properties.Remove("SSN")
    $row.PSObject.Properties.Remove("Cuenta")

    $row
}

$resultado | Export-Csv $outputFile -NoTypeInformation -Encoding UTF8

Write-Host "PII masking completed."
Write-Host "Output file: $outputFile"

Versión flexible para cualquier columna

Flexible version for any column

Esta función permite enmascarar cualquier valor dejando visibles solo los últimos caracteres definidos.

This function masks any value while keeping only the defined number of ending characters visible.

function Mask-Value {
    param(
        [string]$Value,
        [int]$VisibleLast = 4,
        [string]$MaskChar = "*"
    )

    if ([string]::IsNullOrWhiteSpace($Value)) { return "" }
    if ($Value.Length -le $VisibleLast) { return $Value }

    $hiddenLength = $Value.Length - $VisibleLast
    return ($MaskChar * $hiddenLength) + $Value.Substring($Value.Length - $VisibleLast)
}

# Example
Mask-Value -Value "123456789" -VisibleLast 4

Aplicaciones reales

Real-world applications

  • Compartir reportes sin exponer SSN completos.
  • Preparar archivos para revisión externa.
  • Reducir riesgo en reportes enviados por correo.
  • Crear datasets de prueba a partir de datos operativos.
  • Share reports without exposing full SSNs.
  • Prepare files for external review.
  • Reduce risk in reports sent by email.
  • Create testing datasets from operational data.

Recomendaciones

Recommendations

  • No exportar las columnas originales sensibles.
  • Guardar el archivo en una carpeta separada y controlada.
  • Validar que el resultado no contenga PII completa.
  • Documentar quién generó el archivo y cuándo.
  • Do not export the original sensitive columns.
  • Save the file in a separate controlled folder.
  • Validate that the output does not contain full PII.
  • Document who generated the file and when.

Valor del tópico

Topic value

Este patrón es clave para privacidad, cumplimiento y reducción de riesgo. Permite compartir información útil para análisis o revisión sin revelar identificadores completos que no son necesarios para la tarea.

This pattern is critical for privacy, compliance, and risk reduction. It allows useful information to be shared for analysis or review without revealing full identifiers that are not needed for the task.