Cómo actualizar directivas de contraseñas de Windows con PowerShell

Directivas de contraseñas: puntos clave

  • Las directivas de contraseñas son esenciales para reforzar la seguridad informática en las organizaciones.
  • El script que analizaremos hoy automatiza el proceso de modificar la complejidad de la contraseña en Windows.
  • El script admite tanto ordenadores con dominio como sin dominio.
  • Ejecutar el script sin privilegios administrativos resultará en la terminación.
  • Los métodos tradicionales para cambiar las directivas de contraseñas pueden llevar más tiempo que este script.
  • Prueba siempre el script en un entorno controlado antes de desplegarlo.
  • Informar a los usuarios de los cambios en las directivas de contraseñas puede evitar confusiones y posibles bloqueos.
  • Revisar y ajustar periódicamente las directivas de contraseñas es una buena práctica.
  • NinjaOne puede integrarse perfectamente con herramientas de automatización para reforzar las medidas de seguridad.

En el panorama informático actual, la seguridad sigue siendo primordial. Con las filtraciones de datos acaparando los titulares, establecer directivas de contraseñas seguras se convierte no sólo en una opción, sino en una necesidad. A medida que las organizaciones buscan fortificar sus defensas, surge como tema crucial una forma eficiente de actualizar las directivas de contraseñas de Windows.

Antecedentes

Las directivas de contraseñas, especialmente en entornos Windows, ayudan a definir los requisitos para crear y mantener contraseñas. Asegurarse de que son estrictas reduce el riesgo de acceso no autorizado. El script que analizamos en este post está diseñado para que los profesionales de TI y los proveedores de servicios gestionados (MSP) cambien sin esfuerzo la complejidad de la contraseña de un equipo con dominio o sin dominio.

¿Por qué es tan valiosa esta herramienta? Cambiar manualmente las directivas de contraseñas, especialmente en grandes organizaciones, puede resultar engorroso. Un script de este tipo automatiza el proceso, haciéndolo más rápido y menos propenso a errores humanos.

El script para actualizar directivas de contraseñas de Windows

#Requires -Version 5.1

<#
.SYNOPSIS
    Modifies the password complexity settings for a domain or a non-domain computer.
.DESCRIPTION
    This script can be used to enable or disable the password complexity requirement on a domain or a non-domain computer.
    When using -Domain, this script must be run on a Domain Controller with the RSAT feature installed.
.PARAMETER ComplexityEnabled
    Enables the Password Complexity requirement.
.PARAMETER Domain
    Specifies the name of the domain. If specified, it will enable or disable the password complexity requirement on the Active Directory Default Domain Password Policy.
    The computer this script is executed on MUST have the PowerShell RSAT features installed when using the -Domain flag.
.EXAMPLE
     -ComplexityEnabled
    Enables the password complexity requirement on the computer this script runs on.
.EXAMPLE
     No param needed
    Disables the password complexity requirement on the computer this script runs on.
.EXAMPLE
     -ComplexityEnabled -Domain "test.consto.com"
    Enables the password complexity requirement in Active Directory for the Default Domain Password Policy.
    When using -Domain, this script must be run on a Domain Controller with the RSAT feature installed.
.EXAMPLE
     -Domain "test.consto.com"
    Disables the password complexity requirement in Active Directory for the Default Domain Password Policy.
    When using -Domain, this script must be run on a Domain Controller with the RSAT feature installed.
.NOTES
    Minimum OS Architecture Supported: Windows 10, Windows Server 2016
    Release Notes: Renamed script and added Script Variable support
    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(Mandatory = $false)]
    [Switch]
    $ComplexityEnabled,
    [Parameter(Mandatory = $false)]
    [String]
    $Domain
)
begin {
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
        { Write-Output $true }
        else
        { Write-Output $false }
    }
    function Test-DomainJoined {
        # Check if the computer is domain joined
        if ((Get-Command -Name Get-WmiObject -ErrorAction SilentlyContinue)) {
            return $(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain
        }
        elseif ((Get-Command -Name Get-CIMInstance -ErrorAction SilentlyContinue)) {
            return $(Get-CimInstance -ClassName Win32_ComputerSystem).PartOfDomain
        }
        else {
            Write-Host "[Error] Get-WmiObject and Get-CIMInstance are not available. This script requires at least one of these cmdlets to run."
            exit 1
        }
    }
}
process {
    if (-not (Test-IsElevated)) {
        Write-Host "[Error] Access Denied. Please run with Administrator privileges."
        exit 1
    }
    
    if (-not ([string]::IsNullOrWhiteSpace($Domain))) {
        # Active Directory
    
        # Check if we are running on a Domain Controller, exit if we aren't
        $osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
        if ($osInfo.ProductType -ne 2) {
            Write-Host "[Error] This needs to run on a Domain Controller."
            exit 1
        }
        # Set ComplexityEnabled to what was passed into $ComplexityEnabled
        Set-ADDefaultDomainPasswordPolicy -Identity $Domain -ComplexityEnabled $(if ($ComplexityEnabled) { $true }else { $false }) -Confirm:$false
        # Sleep for a while, just in case Get-ADDefaultDomainPasswordPolicy connects to a different AD server and replication is slow
        Start-Sleep -Seconds 60
        # Check if the ComplexityEnabled policy was applied correctly
        $Results = Get-ADDefaultDomainPasswordPolicy -Identity $Domain
        # Check that the policy matches what was requested
        if ($Results -and $Results.ComplexityEnabled -eq $ComplexityEnabled) {
            Write-Host "[Info] Set Complexity in Default Domain Password Policy to $ComplexityEnabled"
            return
        }
        else {
            # The policy was not set for some reason
            Write-Host "[Error] Failed to set Complexity in Default Domain Password Policy to $ComplexityEnabled"
            exit 1
        }
    }
    else {
        # Localhost
        # Check if the computer is domain joined

        if ($(Test-DomainJoined)) {
            Write-Host "[Error] This Computer is domain joined. Modifying the local policy is not supported for domain joined computers."
            exit 1
        }

        # Set the path for our temp local policy config file
        $Path = "$PSScriptRoot\Set-Password-Complexity-secpol.cfg"
        # Get our local policy
        SecEdit.exe /export /cfg $Path
        if ($LASTEXITCODE -gt 0) {
            Write-Host "[Error] Failed to read local machine Policy"
            exit 1
        }

        # Next make sure that we are not changing something that does not need to be changed
        # if $ComplexityEnabled is True and the temp local policy config file has PasswordComplexity set to 0, then proceed
        if ($ComplexityEnabled -and $(Get-Content -Path $Path) -Match "^PasswordComplexity = 0$") {
            # Change PasswordComplexity from 0 to 1
            $(Get-Content -Path $Path) -Replace "PasswordComplexity = 0", "PasswordComplexity = 1" | Out-File $Path
            # Update the local policy with our changes
            SecEdit.exe /configure /db c:\windows\security\local.sdb /cfg $Path /areas SECURITYPOLICY
            if ($LASTEXITCODE -gt 0) {
                Write-Host "[Error] Failed to set Complexity in local machine Policy to $ComplexityEnabled"
                exit 1
            }
        }# if $ComplexityEnabled is False and the temp local policy config file has PasswordComplexity set to 1, then proceed
        elseif (-not $ComplexityEnabled -and $(Get-Content -Path $Path) -Match "^PasswordComplexity = 1$") {
            # Change PasswordComplexity from 1 to 0
            $(Get-Content -Path $Path) -Replace "PasswordComplexity = 1", "PasswordComplexity = 0" | Out-File $Path
            # Update the local policy with our changes
            SecEdit.exe /configure /db c:\windows\security\local.sdb /cfg $Path /areas SECURITYPOLICY
            if ($LASTEXITCODE -gt 0) {
                Write-Host "[Error] Failed to set Complexity in local machine Policy to $ComplexityEnabled"
                exit 1
            }
        }
        # Remove our temp local policy config file
        Remove-Item $Path -Force
        # Get our local policy
        SecEdit.exe /export /cfg $Path
        # Check if the temp local policy config file has PasswordComplexity set to match our $ComplexityEnabled
        if (
            ($ComplexityEnabled -and $(Get-Content $Path) -Match "^PasswordComplexity = 1$") -or
            (-not $ComplexityEnabled -and $(Get-Content $Path) -Match "^PasswordComplexity = 0$")
        ) {
            # Remove our temp local policy config file again
            Remove-Item $Path -Force
            Write-Host "[Info] Set Complexity in local machine Policy to $ComplexityEnabled"
            return
        }
        else {
            # Remove our temp local policy config file again
            Remove-Item $Path -Force
            Write-Host "[Error] Failed to set Complexity in local machine Policy to $ComplexityEnabled"
            exit 1
        }
    }
}

 

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

Obtén acceso

Análisis detallado

  • Requisitos iniciales: el script está diseñado para Windows 10 o Windows Server 2016. Además, si se utiliza la función Active Directory, deberá instalarse RSAT para Active Directory.
  • Parámetros: el script acepta dos parámetros opcionales:
  • $ComplexityEnabled: un interruptor que activa o desactiva la complejidad de la contraseña.
  • $Domain: especifica el nombre de dominio para el que se cambiará la directiva de contraseñas.
  • Control de la elevación de los permisos: antes de cualquier acción, el script comprueba si tiene privilegios de administrador. En caso contrario, finaliza, garantizando que las acciones sólo se ejecutan con los permisos adecuados.
  • Active Directory: si se especifica un dominio, éste:
  • Comprueba si se está ejecutando en un controlador de dominio.
  • Valida la presencia del módulo ActiveDirectory.
  • Modifica la directiva de contraseñas de dominio por defecto basándose en el parámetro $ComplexityEnabled.
  • Política local: si no se especifica ningún dominio, se:
  • Crea un archivo temporal de configuración de políticas.
  • Comprueba la configuración actual de la complejidad de la contraseña.
  • Modifica esta configuración en función del parámetro $ComplexityEnabled.

Posibles casos de uso

Estudio de caso: Imagina a Ana, una profesional de TI que trabaja en una organización que ha sufrido recientemente ataques de phishing. Su equipo decide aplicar directivas de contraseñas más estrictas. En lugar de revisar manualmente cada sistema o controlador de dominio, Ana utiliza este script. Simplemente ejecutándolo con los parámetros deseados, puede actualizar rápidamente las directivas de contraseñas, mejorando así la postura de seguridad de la organización.

Comparaciones

Tradicionalmente, cambiar las directivas de contraseñas en Windows a menudo requería navegar a través de múltiples interfaces basadas en GUI, como la Administración de Políticas de Grupo o la Política de Seguridad Local. Aunque eficaces, estos métodos pueden llevar mucho tiempo. Este script de PowerShell agiliza el proceso, proporcionando un enfoque más rápido y eficiente.

FAQ

  • ¿Qué versiones de Windows admite este script? 
    Windows 10 y Windows Server 2016.
  • ¿Es necesario especificar siempre un dominio? 
    No, si no especifica un dominio, el script utilizará por defecto el equipo local.
  • ¿Qué ocurre si el script no se ejecuta con privilegios administrativos?
    Terminará y dará un mensaje de error.

Implicaciones

Aunque la automatización de los cambios en la política de contraseñas puede agilizar los procesos, es vital notificar a los usuarios estos cambios. Los cambios repentinos en la política de contraseñas pueden generar confusión y posibles bloqueos, lo que repercute en la productividad. Además, desde el punto de vista de la seguridad de TI, actualizar y aplicar periódicamente las directivas de contraseñas puede reducir drásticamente el riesgo de accesos no autorizados.

Recomendaciones

  • Ejecuta siempre el script en un entorno de prueba antes de aplicarlo a una configuración activa.
  • Revisa y ajusta periódicamente las directivas de contraseñas de acuerdo con las recomendaciones de seguridad más recientes.
  • Educa a los usuarios sobre la importancia de las contraseñas seguras y el motivo de los cambios de política.

Reflexiones finales

En el contexto de la mejora de la seguridad de TI, herramientas como NinjaOne pueden desempeñar un papel fundamental. No sólo proporcionan soluciones de supervisión, sino que se integran perfectamente con scripts como el que hemos analizado. Utilizando NinjaOne junto con estas herramientas de automatización, los profesionales de TI pueden gestionar y reforzar eficazmente las medidas de seguridad de su organización.

Próximos pasos

La creación de un equipo de TI próspero y eficaz requiere contar con una solución centralizada que se convierta en tu principal herramienta de prestación de servicios. NinjaOne permite a los equipos de TI supervisar, gestionar, proteger y dar soporte a todos sus dispositivos, estén donde estén, sin necesidad de complejas infraestructuras locales.

Obtén más información sobre NinjaOne Endpoint Management, echa un vistazo a un tour en vivoo tu prueba gratuita de la plataforma NinjaOne.

Categorías:

Quizá también te interese…

Ver demo×
×

¡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).