Cómo supervisar el último inicio de sesión de un usuario con PowerShell

En la gestión de TI moderna, una de las tareas críticas consiste en supervisar las cuentas de usuario, sobre todo para identificar las inactivas. Esta empresa es algo más que una simple limpieza, y es que setá directamente relacionada con la seguridad, el cumplimiento de la normativa y la gestión eficaz de los recursos. Hoy nos adentramos en un script de PowerShell que permite supervisar el último inicio de sesión de un usuario.

Antecedentes

El script proporcionado está diseñado para identificar e informar sobre las cuentas de usuario en función de su último inicio de sesión, en particular aquellas que no se han utilizado durante un periodo de tiempo especificado. Garantizar la identificación y gestión de las cuentas no utilizadas es crucial para los profesionales de TI y los proveedores de servicios gestionados (MSP). Las cuentas inactivas plantean riesgos de seguridad y a menudo se convierten en objetivos fáciles para los ciberdelincuentes. Además, para las organizaciones sujetas a normativas de cumplimiento, el seguimiento de la actividad de los usuarios y la desactivación de las cuentas no utilizadas puede ser un requisito.

El script para supervisar el último inicio de sesión de un usuario

#Requires -Version 5.1

<#
.SYNOPSIS
    Returns exit code of 1 if any Enabled accounts that haven't been logged in over 90 days or a custom amount of days.
.DESCRIPTION
    Returns exit code of 1 if any Enabled accounts that haven't been logged in over 90 days or a custom amount of days.
.EXAMPLE
    No parameters needed.
    Returns exit code of 1 if any Enabled accounts that haven't been logged in over 90 days.
.EXAMPLE
    -IncludeDisabled
    Returns exit code of 1 if any Enabled or Disabled accounts that haven't been logged in over 90 days.
.EXAMPLE
    -Days 60
    Returns exit code of 1 if any Enabled accounts that haven't been logged in over 60 days.
.EXAMPLE
    -Days 60 -IncludeDisabled
    Returns exit code of 1 if any Enabled or Disabled accounts that haven't been logged in over 60 days.
.OUTPUTS
    None
.NOTES
    Minimum OS Architecture Supported: Windows 7, Windows Server 2012
    Exit code 1: Found users that haven't logged in over X days and are enabled.
    Exit code 2: Calling "net.exe user" or "Get-LocalUser" failed.
    Release Notes:
    Initial Release
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
    Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
.COMPONENT
    ManageUsers
#>

[CmdletBinding()]
param (
    [Parameter()]
    [int]
    $Days = 90,
    [Parameter()]
    [switch]
    $IncludeDisabled
)

begin {}
process {
    if ($Days -lt 0) {
        # Change negative days to the expected positive days
        $Days = 0 - $Days
    }
    $Accounts = if ($(Get-Command "Get-LocalUser").Name -like "Get-LocalUser") {
        try {
            Get-LocalUser | Select-Object Name, Enabled, SID, LastLogon
        }
        catch {
            exit 2
        }
    }
    else {
        # Get users from net.exe user
        $Data = $(net.exe user) | Select-Object -Skip 4
        # Check if the command ran the way we wanted and the exit code is 0
        if ($($Data | Select-Object -Last 2 | Select-Object -First 1) -like "*The command completed successfully.*" -and $LASTEXITCODE -eq 0) {
            # Process the output and get only the users
            $Users = $Data[0..($Data.Count - 3)] -split 's+' | Where-Object { -not $([String]::IsNullOrEmpty($_)) }
            # Loop through each user
            $Users | ForEach-Object {
                # Get the Account active property look for a Yes
                $Enabled = $(net.exe user $_) | Where-Object {
                    $_ -like "Account active*" -and
                    $($_ -split 's+' | Select-Object -Last 1) -like "Yes"
                }
                # Get the Last logon property
                $LastLogon = $(
                    $(
                        $(net.exe user $_) | Where-Object {
                            $_ -like "Last logon*"
                        }
                    ) -split 's+' | Select-Object -Skip 2
                ) -join ' '
                # Get the Password last set property
                $PasswordLastSet = $(
                    $(
                        $(net.exe user $_) | Where-Object {
                            $_ -like "Password last set*"
                        }
                    ) -split 's+' | Select-Object -Skip 3
                ) -join ' '
                # Output Name and Enabled almost like how Get-LocalUser displays it's data
                [PSCustomObject]@{
                    Name      = $_
                    Enabled   = if ($Enabled -like "*Yes*") { $true }else { $false }
                    LastLogon = if ($LastLogon -like "*Never*") { [DateTime]::Parse($PasswordLastSet) } else { [DateTime]::Parse($LastLogon) }
                }
            }
        }
        else {
            exit 2
        }
    }
    $Output = $Accounts | Where-Object {
        if ($IncludeDisabled) {
            $_.LastLogon -lt $(Get-Date).AddDays(0 - $Days)
        }
        else {
            $_.Enabled -and $_.LastLogon -lt $(Get-Date).AddDays(0 - $Days)
        }
    }
    $Output | Out-String | Write-Host
    if ($null -ne $Output) {
        exit 1
    }
}
end {}

 

Accede a más de 300 scripts en el Dojo de NinjaOne

Obtén acceso

Análisis detallado

El script comienza estableciendo una duración predeterminada de 90 días para comprobar la inactividad. A continuación, utiliza el cmdlet “Get-LocalUser” o el comando “net.exe user”, en función de lo que esté disponible.

  • Si el cmdlet “Get-LocalUser” está presente, obtiene los detalles directamente.
  • Si no, recurre al comando “net.exe user”. Este comando recupera los datos y luego procesa el output para filtrar los detalles necesarios.

La lógica principal consiste en comprobar si el último inicio de sesión de cada usuario es anterior al umbral definido. Si se encuentra una coincidencia, se muestra y el script sale con el código 1. Se utiliza un código de salida 2 para las excepciones cuando se obtienen datos de usuario.

Posibles casos de uso

Imagina a Ana, una profesional de TI en una empresa mediana. Recientemente, la empresa se ha enfrentado a un pequeño fallo de seguridad. Tras el incidente, se le ha encargado a Ana que refuerce la seguridad. Una de las sugerencias ha sido comprobar periódicamente si hay cuentas inactivas y desactivarlas. Con este script para supervisar el último inicio de sesión de un usuario, puede configurar una rutina mensual para obtener una lista de dichas cuentas, garantizando que el directorio de usuarios de la empresa permanece activo y seguro.

Comparaciones

Aunque el script emplea PowerShell, otro enfoque podría consistir en consultar directamente Active Directory (si está disponible) para obtener los detalles de las cuentas de usuario. Pueden utilizarse herramientas como ADManager Plus o incluso el Usuarios y equipos de Active Directory (ADUC) integrado. Sin embargo, nuestro script para supervisar el último inicio de sesión de un usuario ofrece una alternativa ligera, personalizable y gratuita.

FAQ

  • ¿Y si quiero comprobar una duración de inactividad diferente?
    Puedes personalizar el parámetro $Days.
  • ¿El script puede identificar tanto las cuentas habilitadas como las deshabilitadas?
    Sí, utilizando el modificador -IncludeDisabled, el script puede recuperar tanto las cuentas activadas como las desactivadas.

Implicaciones

Más allá de la identificación de cuentas inactivas, la implicación más amplia de este script para supervisar el último inicio de sesión de un usuario está relacionada con la seguridad informática. Las cuentas inactivas pueden ser fácilmente comprometidas, proporcionando acceso no autorizado. La comprobación periódica de la inactividad de los usuarios y la adopción de las medidas oportunas pueden evitar posibles infracciones.

Recomendaciones

  • Prueba siempre el script en un entorno controlado antes de desplegarlo en una configuración real.
  • Programa este script para que se ejecute periódicamente a fin de garantizar una supervisión continua.
  • Una vez detectadas las cuentas inactivas, toma las medidas oportunas, como desactivar la cuenta o notificárselo al usuario o a su manager.

Reflexiones finales

Si bien el script para supervisar el último inicio de sesión de un usuario proporciona una solución eficaz, integrar herramientas como NinjaOne puede mejorar aún más las capacidades, automatizando las tareas y proporcionando un panel de control para una gestión centralizada. Herramientas como NinjaOne están diseñadas para gestionar estas tareas de manera eficiente, garantizando que los profesionales de TI como Ana puedan centrarse en tareas más estratégicas, utilizando scripts como el anterior como parte de un conjunto de herramientas más amplio.

Categorías:

Quizá también te interese…

×

¡Vean a NinjaOne en acción!

Al enviar este formulario, acepto la política de privacidad de NinjaOne.

Términos y condiciones de NinjaOne

Al hacer clic en el botón “Acepto” que aparece a continuación, estás aceptando los siguientes términos legales, así como nuestras Condiciones de uso:

  • Derechos de propiedad: NinjaOne posee y seguirá poseyendo todos los derechos, títulos e intereses sobre el script (incluidos los derechos de autor). NinjaOne concede al usuario una licencia limitada para utilizar el script de acuerdo con estos términos legales.
  • Limitación de uso: solo podrás utilizar el script para tus legítimos fines personales o comerciales internos, y no podrás compartirlo con terceros.
  • Prohibición de republicación: bajo ninguna circunstancia está permitido volver a publicar el script en ninguna biblioteca de scripts que pertenezca o esté bajo el control de cualquier otro proveedor de software.
  • Exclusión de garantía: el script se proporciona “tal cual” y “según disponibilidad”, sin garantía de ningún tipo. NinjaOne no promete ni garantiza que el script esté libre de defectos o que satisfaga las necesidades o expectativas específicas del usuario.
  • Asunción de riesgos: el uso que el usuario haga del script corre por su cuenta y riesgo. El usuario reconoce que existen ciertos riesgos inherentes al uso del script, y entiende y asume cada uno de esos riesgos.
  • Renuncia y exención: el usuario no hará responsable a NinjaOne de cualquier consecuencia adversa o no deseada que resulte del uso del script y renuncia a cualquier derecho o recurso legal o equitativo que pueda tener contra NinjaOne en relación con su uso del script.
  • CLUF: si el usuario es cliente de NinjaOne, su uso del script está sujeto al Contrato de Licencia para el Usuario Final (CLUF).