none
Aplicar gpo a distintos usuarios de varias unidades organizativas RRS feed

  • Pregunta

  • Buenas tardes

    Os realizo una pregunta de un problema que me ha surgido en mi organizacion. Tengo un directorio activo, en el cual existen un tipo de usuarios (usuarios citrix) que se encuentran en distintas unidades organizativas dentro del ad. Este tipo de usuarios se conectan mediante citrix a una aplicacion. Algunos de estos usuarios tienen definido un home forlder (directorio particular) y otros no. Necesito aplicar una politica o definirles una home folder a estos usuarios que no las tiene, PERO solo definirselas a los usuarios que no las tienen, SIN machacarselas a los que si las tiene definidas. Todos estos usuarios se encuentran dentro un grupo. Por favor necesito que me orienteis.

    Si necesitais que os alguna aclaracion, por favor indicarmelo.

    Muchas gracias.

    domingo, 17 de julio de 2011 15:57

Respuestas

  • Con PowerShell sería algo así. Vamos primero a obtener los usuarios del dominio que no tienen carpeta personal (en el ejemplo pondremos como dominio tia.org).

    Lo primero es conectar al dominio:

     

    $Dominio = [ADSI] "LDAP://DC=tia,dc=org"

     


    Una vez hemos conectado al dominio, creamos un objeto buscador conectado al dominio:

     

    $Buscador = [System.DirectoryServices.DirectorySearcher]$Dominio

     


    Una vez creado el buscador, especificamos el filtro LDAP para obtener objetos de tipo usuario y de categoría persona que no tengan nada establecido como carpeta personal:

     

    $Filtro = "(&(objectClass=user)(objectCategory=person)(!(homeDirectory=*)))"
    $Buscador.Filter = $Filtro

     

    Ahora establecemos que la búsqueda sea en subárbol, es decir, que se busque en todo el dominio:

     

    $Buscador.SearchScope = "Subtree"

     


    Ya estamos preparados para ejecutar la búsqueda. Esto se hace con el método FindAll del objeto buscador. Lo que devuelve este método son objetods de tipo System.DirectoryServices.SearchResult, que tienen dos propiedades: Path y Properties. La primera es la ruta LDAP del objeto devuelto y la segunda es un array con las propiedades del objeto. Usaremos la propiedad Path para obtener el objeto System.DirectoryServices.DirectoryEntry que nos permitirá establecer la ruta de la carpeta personal y la letra de unidad personal. En este ejemplo estableceremos como carpeta personal \\bacterio-srv\usuarios$\<sAMAccountName> y como letra de unidad personal la P. Una vez establecidos los valores se graban usando el método SetInfo del objeto DirectoryEntry:

     

    $Buscador.FindAll() | ForEach{ `
      $Usuario = [ADSI] $_.Path
      $Usuario.homeDirectory = "\\bacterio-srv\Usuarios$\$($Usuario.sAMAccountName)"
      $Usuario.homeDrive = "P:"
      $Usuario.SetInfo()
    }

     

    Si ponemos todo junto:

    # Conectamos al dominio
    $Dominio = [ADSI] "LDAP://DC=tia,dc=org"
    # Creamos el buscador de LDAP
    $Buscador = [System.DirectoryServices.DirectorySearcher]$Dominio
    # Establecemos el filtro para encontrar usuario de categoría persona que
    # no tengan establecida carpeta personal
    $Filtro = "(&(objectClass=user)(objectCategory=person)(!(homeDirectory=*)))"
    $Buscador.Filter = $Filtro
    # establecemos que se busqye en todo el dominio
    $Buscador.SearchScope = "Subtree"
    # Ejecutamos la búsqueda
    $Buscador.FindAll() | ForEach{ `
      # Obtenemos el objeto DirectoryEntry del usuario actual
      $Usuario = [ADSI] $_.Path
      # Establecemos su carpeta personal
      $Usuario.homeDirectory = "\\bacterio-srv\Usuarios$\$($Usuario.sAMAccountName)"
      # Establecemos la letra de la unidad personal
      $Usuario.homeDrive = "P:"
      # Guardamos los cambios
      $Usuario.SetInfo()
    }

    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)
    • Propuesto como respuesta Ismael Borche martes, 19 de julio de 2011 20:58
    • Marcado como respuesta Ismael Borche miércoles, 27 de julio de 2011 20:26
    lunes, 18 de julio de 2011 11:34
    Moderador
  • Filtra la aplicación de la GPO por grupo/s, de modo que sólo los usuarios que estén ese grupo/s se vean afectados.
    Saludos,

    Marc
    MCSA/MCSE 2003
    MCITP: Enterprise Administrator (Windows Server 2008)
    MCITP: Enterprise Messaging Administrator (Microsoft Exchange 2007 & Exchange 2010)
    MCC: Microsoft Community Contributor 2011
    Citrix CCA
    • Marcado como respuesta Ismael Borche miércoles, 27 de julio de 2011 20:27
    jueves, 21 de julio de 2011 8:40
    Moderador

Todas las respuestas

  • La carpeta personal no se define a nivel de GPO si no de usuario, por tanto lo que se debería hacer es establecerla en aquellos usuarios que no la tengan definida.
    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)
    lunes, 18 de julio de 2011 6:27
    Moderador
  • OK. Pero me gustaria algun script o algo parecido que pudiera contralar eso, es decir, que me compruebe los usuarios que las tiene y me las mantega las que tienen actualmente, y los usuarios que no las tienen definida me coloque las que yo le indique. Para todos los usuarios que no las tiene seria siempre la misma.

    Ruego me indiqueis la forma correcta e idónea para llevar a cabo.

    Muchas gracias.

    lunes, 18 de julio de 2011 7:38
  • Con PowerShell sería algo así. Vamos primero a obtener los usuarios del dominio que no tienen carpeta personal (en el ejemplo pondremos como dominio tia.org).

    Lo primero es conectar al dominio:

     

    $Dominio = [ADSI] "LDAP://DC=tia,dc=org"

     


    Una vez hemos conectado al dominio, creamos un objeto buscador conectado al dominio:

     

    $Buscador = [System.DirectoryServices.DirectorySearcher]$Dominio

     


    Una vez creado el buscador, especificamos el filtro LDAP para obtener objetos de tipo usuario y de categoría persona que no tengan nada establecido como carpeta personal:

     

    $Filtro = "(&(objectClass=user)(objectCategory=person)(!(homeDirectory=*)))"
    $Buscador.Filter = $Filtro

     

    Ahora establecemos que la búsqueda sea en subárbol, es decir, que se busque en todo el dominio:

     

    $Buscador.SearchScope = "Subtree"

     


    Ya estamos preparados para ejecutar la búsqueda. Esto se hace con el método FindAll del objeto buscador. Lo que devuelve este método son objetods de tipo System.DirectoryServices.SearchResult, que tienen dos propiedades: Path y Properties. La primera es la ruta LDAP del objeto devuelto y la segunda es un array con las propiedades del objeto. Usaremos la propiedad Path para obtener el objeto System.DirectoryServices.DirectoryEntry que nos permitirá establecer la ruta de la carpeta personal y la letra de unidad personal. En este ejemplo estableceremos como carpeta personal \\bacterio-srv\usuarios$\<sAMAccountName> y como letra de unidad personal la P. Una vez establecidos los valores se graban usando el método SetInfo del objeto DirectoryEntry:

     

    $Buscador.FindAll() | ForEach{ `
      $Usuario = [ADSI] $_.Path
      $Usuario.homeDirectory = "\\bacterio-srv\Usuarios$\$($Usuario.sAMAccountName)"
      $Usuario.homeDrive = "P:"
      $Usuario.SetInfo()
    }

     

    Si ponemos todo junto:

    # Conectamos al dominio
    $Dominio = [ADSI] "LDAP://DC=tia,dc=org"
    # Creamos el buscador de LDAP
    $Buscador = [System.DirectoryServices.DirectorySearcher]$Dominio
    # Establecemos el filtro para encontrar usuario de categoría persona que
    # no tengan establecida carpeta personal
    $Filtro = "(&(objectClass=user)(objectCategory=person)(!(homeDirectory=*)))"
    $Buscador.Filter = $Filtro
    # establecemos que se busqye en todo el dominio
    $Buscador.SearchScope = "Subtree"
    # Ejecutamos la búsqueda
    $Buscador.FindAll() | ForEach{ `
      # Obtenemos el objeto DirectoryEntry del usuario actual
      $Usuario = [ADSI] $_.Path
      # Establecemos su carpeta personal
      $Usuario.homeDirectory = "\\bacterio-srv\Usuarios$\$($Usuario.sAMAccountName)"
      # Establecemos la letra de la unidad personal
      $Usuario.homeDrive = "P:"
      # Guardamos los cambios
      $Usuario.SetInfo()
    }

    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)
    • Propuesto como respuesta Ismael Borche martes, 19 de julio de 2011 20:58
    • Marcado como respuesta Ismael Borche miércoles, 27 de julio de 2011 20:26
    lunes, 18 de julio de 2011 11:34
    Moderador
  • Muchisimas gracias, lo voy a probar y te cuento.

    lunes, 18 de julio de 2011 11:43
  • Como puedo aplicar este script tan solo a un grupo en concreto?? Es decir la busqueda de estos usuarios no es en todo el dominio AD sino que en algunos grupos del AD, donde sus usuarios se encuentran dispersos por varias ou. Este script me vale, pero necesitario aplicarlo solo a estos grupos que te comento.

    Muchisimas gracias por el interes mostrado y por la gran ayuda Fernando.

    lunes, 18 de julio de 2011 12:07
  • Filtra la aplicación de la GPO por grupo/s, de modo que sólo los usuarios que estén ese grupo/s se vean afectados.
    Saludos,

    Marc
    MCSA/MCSE 2003
    MCITP: Enterprise Administrator (Windows Server 2008)
    MCITP: Enterprise Messaging Administrator (Microsoft Exchange 2007 & Exchange 2010)
    MCC: Microsoft Community Contributor 2011
    Citrix CCA
    • Marcado como respuesta Ismael Borche miércoles, 27 de julio de 2011 20:27
    jueves, 21 de julio de 2011 8:40
    Moderador
  •  

    Muchisimas gracias Marc. Pero una ultima pregunta, la gpo como la creo como script de inicio de sesion a nivel de equipo? Gracias por tu respuesta.

    jueves, 21 de julio de 2011 8:51
  • Depende. Si la GPO afecta a los usuarios, la aplicación de la misma debería ser a ese nivel y el filtrado, también.

    Si es de equipo, el filtrado será por grupo de equipos.

     

    Lo que no he probado nunca es de aplicar un script de PS1 directamente por GPO :S


    Saludos,

    Marc
    MCSA/MCSE 2003
    MCITP: Enterprise Administrator (Windows Server 2008)
    MCITP: Enterprise Messaging Administrator (Microsoft Exchange 2007 & Exchange 2010)
    MCC: Microsoft Community Contributor 2011
    Citrix CCA
    jueves, 21 de julio de 2011 9:11
    Moderador
  • Bueno, deberías contar con que los equipos tienen powershell e invocarlo desde un bat. De todas maneras, si sé desde un principio que se trata de un script para usarlo en una GPO como script de inicio de sesión, le habría dado el script en VbScript. Seria algo así:

     

    '**********************************************************************
    '* Este script está pensado para establecer la unidad personal de
    '* un usuario de Active Directory vía GPO, con un script de inicio
    '* de sesión, cuando el usuario no tiene ya establecida esta carpeta
    '* personal.
    '*
    '* © Fernando Reyes
    '* Agosto De 2011
    '**********************************************************************
    
    Dim str_UsuarioNT
    Dim obj_Usuario
    Dim obj_NW
    Dim str_RutaCarpeta
    Dim str_LetraUnidad
    
    'Creamos un objeto WshNetwork
    Set obj_NW = CreateObject("WScript.Network")
    
    'Montamos la ruta UNC de la carpeta personal en función del nombre
    'NT del usuario (sAMAccountName)
    str_RutaCarpeta = "\\bacterio-srv\usuarios$\" & obj_NW.UserName
    
    'Establecemos la letra de la unidad personal
    str_LetraUnidad = "P:"
    
    'Montamos el nombre NT del usuario (dominio\sAMAccountName)
    str_UsuarioNT = obj_NW.UserDomain & "\" & obj_NW.UserName
    
    'Obtenemos el objeto iADsUser del usuario, obteniendo el nombre
    'distinguido del mismo por medio de una llamada a f_NTaDN
    Set obj_Usuario = GetObject("LDAP://" & f_NTaDN(str_UsuarioNT,""))
     
    'Si el usuario no tiene establecida carpeta personal, la propiedad
    'homeDirectory será una cadena vacía (longitud 0)
    If Len(obj_Usuario.HomeDirectory) = 0 Then
    
      'Establecemos la carpeta personal
      obj_Usuario.Put "homeDirectory", str_RutaCarpeta
      
      'Establecemos la letra de unidad personal
      obj_Usuario.Put "homeDrive", str_LetraUnidad
      
      'Validamos los cambios
      obj_Usuario.SetInfo
    
    End If
    
    'Limpieza de parte posterior saliente :oP
    Set obj_Usuario = Nothing
    Set obj_NW = Nothing
    
    
    Function f_NTaDN(str_RutaNT, str_DN)
    '**********************************************************************
    '* Procedimiento: f_NTaDN
    '* Tipo     : Función
    '* Devolución  : Cadena
    '* Fecha y Hora : May 2007
    '* Autor    : Fernando Reyes
    '*¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    '* Propósito  : Esta función recibe o bien el nombre NT
    '*        ("dominionombre"), como primer parámetro, de un
    '*        objeto de dominio y devuelve el nombre distinguido
    '*        de ese objeto, o bien el nombre distinguido de un
    '*        objeto, como segundo parámetro, y devuelve el
    '*        nombre NT.
    '*        Basada en el código de Richard Mueller, MVP de
    '*        Scripting y ADSI (http://www.rlmueller.net)
    '**********************************************************************
    
      'Constantes para el objeto NameTranslate
      Const ADS_NAME_INITTYPE_GC = 3
      Const ADS_NAME_TYPE_NT4 = 3
      Const ADS_NAME_TYPE_1779 = 1
    
      Dim obj_TraductorDeNombres
      Dim int_De, int_A,str_Nombre
    
      If Len(str_RutaNT) > 0 Then
    
        int_De = ADS_NAME_TYPE_NT4
        int_A = ADS_NAME_TYPE_1779
        str_Nombre = str_RutaNT
    
      ElseIf Len(str_DN) > 0 Then
    
        int_De = ADS_NAME_TYPE_1779
        int_A = ADS_NAME_TYPE_NT4
        str_Nombre = str_DN
    
      Else
    
        WScript.Echo "Error 1 en f_DNaCanonico: No se ha pasado " & _
               "ningún nombre para traducir."
        Exit Function
      End If
      'Creamos el objeto NameTranslate.
      Set obj_TraductorDeNombres = CreateObject("NameTranslate")
    
      On Error Resume Next
    
      'Lo iniciamos localizando el catálogo global
      obj_TraductorDeNombres.Init ADS_NAME_INITTYPE_GC, ""
    
      'Establecemos el parámetro de nombre en el traductor de nombres
      obj_TraductorDeNombres.Set int_De, str_Nombre
    
      'Usamos el método Get del traductor de nombres para obtener el
      'nombre traducido
      f_NTaDN = obj_TraductorDeNombres.Get(int_A)
    
      'Limpieza de kks :-)
      Set obj_TraductorDeNombres = Nothing
    
      On Error GoTo 0
    
    End Function 'f_NTaDN

    No obstante, ahora que me paro a pensarlo, no estoy seguro de que un usuario pueda cambiar su ruta de unidad personal, nunca he intentado algo así, pues siempre he establecido como administrador la ruta personal de los usuarios, ya sea "a manubrio" o con un script que lo hiciera para muchos (que es como me lo planteé al inicio y de ahi usar PowerShell). La prueba es tan sencilla como ejecutar el script de manera interactiva desde la sesión de un usuario normal (no administrador del dominio) y ver si se produce el cambio en el objeto de active directory o le dice que acceso denegado. Por desgracia ahora no tengo un entorno de pruebas que me permita realizar esto.


    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)



    lunes, 22 de agosto de 2011 8:45
    Moderador
  • Yo probaría con el enfoque de hacerlo desde un equipo, en lugar de hacerlo por GPO, que ralentiza los inicios de sesión y, como he dicho, no estoy seguro de que pueda funcionar. Para poder hacer que sólo se realizen los cambios en los usuarios que pertenezcabn a un grupo, nos podemos ayudar de este Cmdlet:

    PowerShell: Cmdlet para obtener los miembros de un grupo
    http://urpiano.wordpress.com/2011/07/20/powershell-cmdlet-para-obtener-los-miembros-de-un-grupo/

    Incluyendo este Cmdlet, una pequeña modificación al anterior script PS que puse nos daría el resultado querido:

     

    Get-GroupMember -Group "cn=Agentes,cn=Users,dc=tia,dc=org" -ShowUsers | ForEach{ `
        # Obtenemos el objeto DirectoryEntry del usuario actual
       
    $Usuario = [ADSI] $_.Path     # Establecemos su carpeta personal     $Usuario.homeDirectory = "\\bacterio-srv\Usuarios$\$($Usuario.sAMAccountName)"     # Establecemos la letra de la unidad personal     $Usuario.homeDrive = "P:"     # Guardamos los cambios     $Usuario.SetInfo() }

    En este grupo no puedo poner el script completo, pues excede el límite de caracteres de mensaje, pero es tan simple como pegar el código, que hay en el enlace que he puesto, antes de estas líneas de código.


    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)




    lunes, 22 de agosto de 2011 8:49
    Moderador
  • Lo que no he probado nunca es de aplicar un script de PS1 directamente por GPO :S

    Je, no me había fijado en el título de la pregunta y no me di cuenta de que se trataba de GPO hasta ahora :oP.

    A partir de Windows 7/2008 R PowerShell va siempre incorporado y las GPOs de scripts de inicio (de equipo o usuario) incluyen una pestaña en la que establecer scripts PowerShell. En SOs anteriores puedes hacerlo invocando al script desde un bat y siempre que tengas instalado PowerShell en los equipos clientes.Realmente, si me hubiera fijado en el título de la pregunta no habría puesto el script PowerShell. No obstante, como verás en otras respuestas, no me convence hacer esta tarea por GPO.


    Un saludo

    Fernando Reyes [MS MVP]
    MCSA 2000/2003
    MCSE 2000/2003
    MCITP EnterpriseAdministrator
    Web: http://freyes.svetlian.com
    Blog: http://urpiano.wordpress.com
    RSS: http://urpiano.wordpress.com/feed/
    freyes.champú@champú.mvps.org
    (Aclárate la cabeza si quieres escribirme)
    lunes, 22 de agosto de 2011 9:08
    Moderador