Agregar o quitar usuarios de Active Directory y grupos de equipos locales con Powershell

Gestionar y modificar la pertenencia de los usuarios a grupos, ya sea en un equipo local o en Active Directory, es una tarea habitual para los profesionales de TI. La gestión eficaz de estas operaciones puede mejorar enormemente la administración del sistema, agilizando los procesos y evitando errores. En este contexto, el poder de los scripts cobra protagonismo, ofreciendo automatización y precisión.

Antecedentes

El script proporcionado profundiza en la esencia de la gestión de TI: permite a los administradores añadir o eliminar usuarios de grupos específicos. Está diseñado para ser versátil, funcionando tanto en el ámbito de un ordenador local como en la esfera más amplia de Active Directory. A medida que las empresas y los proveedores de servicios gestionados (MSP) crecen, la gestión manual de usuarios puede resultar ardua. Estos scripts no sólo reducen el tiempo dedicado a tareas rutinarias, sino que también minimizan los errores humanos.

El script para agregar o quitar usuarios de Active Directory y grupos de equipos locales

#Requires -Version 2.0

<#
.SYNOPSIS
    Add or remove a user to a group in Active Directory or the local computer.
.DESCRIPTION
    Add or remove a user to a group in Active Directory or the local computer.
.EXAMPLE
     -Group "MyGroup" -UserName "MyUser" -Action Add -IsDomainUser
    Adds MyUser to the group MyGroup in AD.
.EXAMPLE
     -Group "MyGroup" -UserName "MyUser" -Action Remove -IsDomainUser
    Removes MyUser from the group MyGroup in AD.
.EXAMPLE
     -Group "MyGroup" -UserName "MyUser" -Action Add
    Adds MyUser to the group MyGroup on the local computer.
.EXAMPLE
    PS C:> Modify-User-Membership.ps1 -Group "MyGroup" -UserName "MyUser" -Action Remove
    Removes MyUser from the group MyGroup on the local computer.
.OUTPUTS
    String[]
.NOTES
    Minimum OS Architecture Supported: Windows 7, Windows Server 2012
    This will require RSAT with the AD feature to be installed to function.
    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 (
    # Specify one Group
    [Parameter(Mandatory = $true)]
    [String]
    $Group,
    # Specify one User
    [Parameter(Mandatory = $true)]
    [String]
    $UserName,
    # Add or Remove user from group
    [Parameter(Mandatory = $true)]
    [ValidateSet("Add", "Remove")]
    [String]
    $Action,
    # Modify a domain user's membership
    [Parameter(Mandatory = $false)]
    [Switch]
    $IsDomainUser
)

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 }
    }
}

process {
    if (-not (Test-IsElevated)) {
        Write-Error -Message "Access Denied. Please run with Administrator privileges."
        exit 1
    }
    if (-not $IsDomainUser) {
        # Modify Local User
        if ($Action -like "Remove") {
            if ($PSVersionTable.PSVersion.Major -lt 3) {
                # Connect to localhost
                try {
                    $ADSI = [ADSI]("WinNT://$env:COMPUTERNAME")
                }
                catch {
                    Write-Error -Message "Failed to connect to $env:COMPUTERNAME via ADSI object"
                    exit 1
                }
                # Find the group
                try {
                    $ASDIGroup = $ADSI.Children.Find($Group, 'group')
                }
                catch {
                    Write-Error -Message "Failed to find $Group via ADSI object"
                    exit 1
                }
                # Remove the user from the group
                try {
                    $ASDIGroup.Remove(("WinNT://$env:COMPUTERNAME/$UserName"))
                }
                catch {
                    Write-Error -Message "Failed to remove User $UserName from Group $Group"
                    exit 529 # ERROR_MEMBER_NOT_IN_GROUP
                }
                
            }
            else {
                if (
                    # Check that the group exists
                (Get-LocalGroup -Name $Group -ErrorAction SilentlyContinue) -and
                    # Check that the user exists in the group
                (Get-LocalGroupMember -Group $Group -Member $UserName -ErrorAction SilentlyContinue)
                ) {
                    Write-Output "Found $UserName in Group $Group, removing."
                    try {
                        # Remove user from Group, -Confirm:$false used to not prompt and stop the script
                        Remove-LocalGroupMember -Group $Group -Member $UserName -Confirm:$false
                        Write-Output "Removed User $UserName from Group $Group"
                    }
                    catch {
                        Write-Error -Message "Failed to remove User $UserName from Group $Group"
                        exit 529 # ERROR_MEMBER_NOT_IN_GROUP
                    }
                }
                elseif (-not (Get-LocalGroup -Name $Group -ErrorAction SilentlyContinue)) {
                    Write-Error -Message "Group $Group does not exist"
                    exit 528 # ERROR_NO_SUCH_GROUP
                }
                elseif (-not (Get-LocalGroupMember -Group $Group -Member $UserName -ErrorAction SilentlyContinue)) {
                    Write-Error -Message "User does not exist in Group $Group"
                    exit 529 # ERROR_MEMBER_NOT_IN_GROUP
                }
            }
            
        }
        elseif ($Action -like "Add") {
            if ($PSVersionTable.PSVersion.Major -lt 3) {
                # Connect to localhost
                try {
                    $ADSI = [ADSI]("WinNT://$env:COMPUTERNAME")
                }
                catch {
                    Write-Error -Message "Failed to connect to $env:COMPUTERNAME via ADSI object"
                    exit 1
                }
                # Find the group
                try {
                    $ASDIGroup = $ADSI.Children.Find($Group, 'group')
                }
                catch {
                    Write-Error -Message "Failed to find $Group via ADSI object"
                    exit 1
                }
                # Get the members of the group
                $GroupResults = try {
                    $ASDIGroup.psbase.invoke('members')  | ForEach-Object {
                        $_.GetType().InvokeMember("Name", "GetProperty", $Null, $_, $Null)
                    }
                }
                catch {
                    $null
                }
                # Check if the user is in the group
                if ($UserName -in $GroupResults) {
                    # User already in Group
                    Write-Output "User $UserName already in Group $Group"
                    exit 1320 # ERROR_MEMBER_IN_GROUP
                }
                else {
                    # User not in group, add them to the group
                    try {
                        $ASDIGroup.Add(("WinNT://$env:COMPUTERNAME/$UserName"))
                    }
                    catch {
                        Write-Error -Message "Failed to add User $UserName to Group $Group"
                        exit 1388 # ERROR_INVALID_MEMBER
                    }
                    
                    # We can verify the membership by running the following  command:
                    if ($UserName -in (
                            $ASDIGroup.psbase.invoke('members')  | ForEach-Object {
                                $_.GetType().InvokeMember("Name", "GetProperty", $Null, $_, $Null)
                            }
                        )
                    ) {
                        # User in Group
                        Write-Output "Added User $UserName to Group $Group"
                    }
                    else {
                        Write-Error -Message "Failed to add User $UserName to Group $Group"
                        exit 1388 # ERROR_INVALID_MEMBER
                    }
                }
                
            }
            else {
                # Verify that the user and group exist
                if (
                    # Check that the user exists
                (Get-LocalUser -Name $UserName -ErrorAction SilentlyContinue) -and
                    # Check that the group exists
                (Get-LocalGroup -Name $Group -ErrorAction SilentlyContinue)
                ) {
                    # Check if user is already in group
                    if (-not (Get-LocalGroupMember -Group $Group -Member $UserName -ErrorAction SilentlyContinue)) {
                        # User not in group, good to add
                        try {
                            # Add user to group
                            Add-LocalGroupMember -Group $Group -Member (Get-LocalUser -Name $UserName)
                            Write-Output "Added User $UserName to Group $Group"
                        }
                        catch {
                            Write-Error -Message "Failed to add User $UserName to Group $Group"
                            exit 1388 # ERROR_INVALID_MEMBER
                        }
                    }
                    else {
                        # User already in Group
                        Write-Output "User $UserName already in Group $Group"
                        exit 1320 # ERROR_MEMBER_IN_GROUP
                    }
                
                }
            }
        }
    }
    else {
        if ((Get-Module -Name ActiveDirectory -ListAvailable -ErrorAction SilentlyContinue)) {
            try {
                Import-Module -Name ActiveDirectory
                # Get most of our data needed for the logic, and to reduce the number of time we need to talk to AD
                $ADUser = (Get-ADUser -Identity $UserName -Properties SamAccountName -ErrorAction SilentlyContinue).SamAccountName
                $ADGroup = Get-ADGroup -Identity $Group -ErrorAction SilentlyContinue
                $ADInGroup = Get-ADGroupMember -Identity $Group -ErrorAction SilentlyContinue | Where-Object { $_.SamAccountName -like $ADUser }
            }
            catch {
                Write-Error -Message "Ninja Agent could not access AD, please check that the agent has permissions to add and remove users from groups."
                exit 5 # Access Denied exit code
            }
            
            # Modify AD User
            if ($Action -like "Remove") {
                # Verify that the user and group exist, and if the user is in the group
                if (
                    $ADUser -and
                    # Check that the group exists
                    $ADGroup -and
                    # Check that the user exists in the group
                    $ADInGroup
                ) {
                    Write-Output "Found $UserName in Group $Group, removing."
                    try {
                        # Remove user from Group, -Confirm:$false used to not prompt and stop the script
                        Remove-ADGroupMember -Identity $Group -Members $ADUser -Confirm:$false
                        Write-Output "Removed User $UserName from Group $Group"
                    }
                    catch {
                        Write-Error -Message "Failed to remove User $UserName from Group $Group"
                        exit 529 # ERROR_MEMBER_NOT_IN_GROUP
                    }
                }
                elseif (-not $ADGroup) {
                    Write-Error -Message "Group $Group does not exist"
                    exit 528 # ERROR_NO_SUCH_GROUP
                }
                elseif (-not $ADInGroup) {
                    Write-Error -Message "User does not exist in Group $Group"
                    exit 529 # ERROR_MEMBER_NOT_IN_GROUP
                }
            }
            elseif ($Action -like "Add") {
                # Verify that the user and group exist
                if (
                    # Check that the user exists
                    $ADUser -and
                    # Check that the group exists
                    $ADGroup
                ) {
                    # Check if user is already in group
                    if (-not $ADInGroup) {
                        # User not in group, good to add
                        try {
                            # Add user to group
                            Add-ADGroupMember -Identity $Group -Members $ADUser
                            Write-Output "Added User $UserName to Group $Group"
                        }
                        catch {
                            Write-Error -Message "Failed to add User $UserName to Group $Group"
                            exit 1388 # ERROR_INVALID_MEMBER
                        }
                    }
                    else {
                        # User already in Group
                        Write-Output "User $UserName already in Group $Group"
                        exit 1320 # ERROR_MEMBER_IN_GROUP
                    }
                }
            }
        }
        else {
            # Throw error that RSAT: ActiveDirectory isn't installed
            Write-Error -Message "RSAT: ActiveDirectory is not installed or not found on this computer. The PowerShell Module called ActiveDirectory is needed to proceed." -RecommendedAction "https://docs.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2019-ps"
            exit 2 # File Not Found exit code
        }
    }
}

end {}

 

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

Obtén acceso

Análisis detallado

El script para agregar o quitar usuarios de Active Directory y grupos de equipos locales comienza con un comentario exhaustivo que ofrece información sobre sus funcionalidades, ejemplos y requisitos. Se definen parámetros esenciales como Group, UserName, Action y un modificador opcional IsDomainUser, que controlan la lógica principal. Una función de ayuda, Test-IsElevated, comprueba si el script se ejecuta con privilegios administrativos. La lógica principal se inicia con una comprobación de elevación, seguida de si la tarea concierne a un usuario local o a un usuario de Active Directory. Dependiendo de la versión de PowerShell y de la acción deseada (Agregar/Quitar), el script interactúa con Interfaces de servicio de Active Directory (ADSI) o emplea cmdlets nativos de PowerShell. Para los usuarios de Active Directory, se emplea el módulo Active Directory, que ofrece una integración y gestión perfectas.

Posibles casos de uso

Estudio de caso:

Sara, administradora de TI en una empresa en expansión, necesita incorporar a 50 nuevos empleados. Dado que los departamentos y las funciones varían, la asignación manual de usuarios a los respectivos grupos de AD llevaría mucho tiempo. Con este script para agregar o quitar usuarios de Active Directory y grupos de equipos locales, Sara asigna rápidamente los usuarios a sus respectivos grupos, garantizando que los controles de acceso se apliquen de forma eficaz. Durante las auditorías informáticas trimestrales, también utiliza el script para eliminar usuarios de grupos específicos o de los equipos locales de empleados que han dejado la empresa.

Comparaciones

La gestión tradicional de usuarios suele girar en torno a herramientas basadas en GUI como Usuarios y equipos de Active Directory (ADUC) o Administración de equipos para usuarios locales. Aunque son fáciles de usar, no son eficaces para las operaciones a gran escala. Este script de PowerShell para agregar o quitar usuarios de Active Directory y grupos de equipos locales garantiza que tareas que llevarían horas se reduzcan a meros minutos. Sin embargo, a diferencia de las herramientas GUI que proporcionan información visual, el script requiere pruebas exhaustivas para garantizar que no se produzcan acciones involuntarias.

FAQ

  • ¿Puedo utilizar este script en versiones anteriores de PowerShell?
    Sí, el script es compatible con versiones de PowerShell tan antiguas como la 2.0. Sin embargo, la funcionalidad puede variar en función de la versión.
  • ¿Es obligatorio el módulo Active Directory?
    Para las acciones relativas a los usuarios del dominio, es necesario el módulo Active Directory.
  • ¿Cómo puedo asegurarme de que tengo los derechos administrativos necesarios?
    El script contiene comprobaciones integradas de derechos administrativos y proporcionará un mensaje de error si no se ejecuta con los privilegios necesarios.

Implicaciones

El script para agregar o quitar usuarios de Active Directory y grupos de equipos locales puede reducir drásticamente los errores en la gestión de grupos de usuarios, lo que puede tener importantes implicaciones para la seguridad informática. Garantizar que los usuarios sólo formen parte de los grupos necesarios refuerza el principio del mínimo privilegio, piedra angular de la seguridad de TI. Sin embargo, la automatización conlleva la responsabilidad de garantizar que los scripts no proporcionen inadvertidamente un acceso excesivo, abriendo potencialmente las puertas a violaciones de la seguridad.

Recomendaciones

  • Prueba siempre el script en un entorno controlado antes de desplegarlo en producción.
  • Mantén un registro de todos los cambios realizados con el script con fines de auditoría.
  • Asegúrate de que dispones de copias de seguridad de Active Directory o de las bases de datos de usuarios locales para revertir cualquier cambio involuntario.

Reflexiones finales

A medida que los entornos de TI se vuelven más complejos, herramientas como NinjaOne son fundamentales para ofrecer soluciones integrales. Para tareas como la gestión de grupos de usuarios, scripts como el que hemos analizado anteriormente pueden integrarse en plataformas como NinjaOne, garantizando que los administradores de TI tengan las mejores herramientas a su alcance, automatizando y agilizando los procesos a la vez que mantienen una seguridad óptima.

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…

×

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