Anuncios

Bienvenidos sean a este post, en este post hemos mejorado la creacion de usuarios y en este post agregamos la posibilidad de ubicar a nuestro usuario en otro contenedor pero hoy tomaremos este script y le añadiremos un par de modificaciones con temas vistos recientemente.

Anuncios

En el primer caso veremos como asignar el contenedor para nuestro usuario, la otra modificacion sera con el grupo que le asignaremos al usuario y finalmente automatizaremos lo primero pero antes tomemos nuestro ultimo codigo de creacion de usuarios actual:

newuser.vbs

Const ADS_PROPERTY_APPEND = 3
Const ADS_PORPERTY_UPDATE = 2
Const Dominio = "dc=laboratorio,dc=local"
Const udominio = "laboratorio.local"
Const titulo = "Alta de usuario v. 1.0"

Dim objFSOut, objStreamout, fileout,textolog

cuenta = inputbox("Ingresa la cuenta",titulo)
nombre = inputbox("Ingresa el nombre",titulo)
apellido = inputbox("Ingresa el apellido",titulo)
uDisplay = apellido & ", " & nombre

chequeo = FindUser(cuenta,uDisplay,ucase(Dominio))

if (chequeo="Not Found") then
empresa = inputbox("Ingresa la empresa",titulo)
descrip = inputbox("Ingresa la descripcion",titulo)
pais = inputbox("Ingresa el pais",titulo)
departamento = inputbox("Ingresa el departamento",titulo)
ou = inputbox("Ingresa la ubicacion del objeto (ou)",titulo)

if (ou="") then ou="cn=Users"

Set oRootLDAP = GetObject("LDAP://rootDSE")
Set oContenedor = GetObject("LDAP://" & ou & "," & Dominio)
Set oNuevoUsuario = oContenedor.Create("User","cn=" & chr(34) & uDisplay & chr(34))

oNuevoUsuario.put "sAMAccountName", lcase(cuenta)
oNuevoUsuario.put "givenName", nombre
oNuevoUsuario.put "sn", apellido
oNuevoUsuario.put "UserPrincipalName", lcase(cuenta) & "@" & uDominio
oNuevoUsuario.put "cn", uDisplay
oNuevoUsuario.put "DisplayName", uDisplay
oNuevoUsuario.put "company", empresa
oNuevoUsuario.put "c", pais
oNuevoUsuario.put "department", departamento
oNuevoUsuario.put "Description", descrip

oNuevoUsuario.SetInfo


randomize timer

dim texto

do while a<12
	if (a=0) then 

	caracter = int(rnd * 25) + 65
	texto = chr(caracter)
	a = a + 1

	else
	
	caracter = int(rnd * 122) + 1
	if ((caracter>47 and caracter<58) or (caracter>96 and caracter<123)) then
		texto = texto & chr(caracter)
		a = a + 1
	end if

	end if		 
loop

uPassword = texto

'msgbox uPassword

oNuevoUsuario.SetPassword uPassword
oNuevoUsuario.Put "pwdLastSet", 0

oNuevoUsuario.put "userAccountControl", 544
oNuevoUsuario.SetInfo

fileout = cuenta & ".log"

textolog = "Se creo la cuenta: " & cuenta & vbCrLf
textolog = textolog & "El nombre completo: " & uDisplay & vbCrLf
textolog = textolog & "La contraseña es: " & uPassword

Set objFSOut = CreateObject("Scripting.FileSystemObject")
Set objStreamout = objFSOut.CreateTextFile(fileout, 1, false)

objStreamout.Write textolog

objStreamout.close()
Set objStreamout = nothing
Set objFSOut = nothing

msgbox "Se creo el usuario correctamente"

else

msgbox "Se encontro el siguiente objeto: " & chequeo,,titulo

end if

Function FindUser(Byval UserName, ByVal CanonName, Byval Domain)


	set cn = createobject("ADODB.Connection")
	set cmd = createobject("ADODB.Command")
	set rs = createobject("ADODB.Recordset")
	cn.open "Provider=ADsDSOObject;"

	cmd.activeconnection=cn
	cmd.commandtext="SELECT ADsPath FROM 'GC://" & Domain & _
	   "' WHERE sAMAccountName = '" & UserName & "'"

	set rs = cmd.execute
	if err<>0 then
		 FindUser="Error conectandose a la base del AD:" & err.description
	else
		 if not rs.BOF and not rs.EOF then
			FindUser=UserName
		 else
			cmd.commandtext="SELECT ADsPath FROM 'GC://" & Domain & _
			"' WHERE cn = '" & CanonName & "'"

			set rs = cmd.execute
			if not rs.BOF and not rs.EOF then
				FindUser=CanonName
		 	else
				FindUser = "Not Found"
			end if
	 	end if
	end if
	cn.close
end function 
Anuncios

Nuestra primera modificacion sera agregar la funcion de convertir OUs que vimos en este post en el final del codigo anterior:

function ConvertirOU(ByVal camino)
	dim c, texto
	c = split(camino,"/")
	for a=ubound(c) to 1 step -1
		texto = texto & "ou=" & c(a) & ","
	next
	texto = mid(texto,1,len(texto)-1)
	ConvertirOU = texto
end function
Anuncios

Trabaja de la misma forma que vimos en ese post pero nuestra siguiente modificacion sera en las siguientes lineas:

ou = inputbox("Ingresa la ubicacion del objeto (ou)",titulo)

if (ou="") then ou="cn=Users"

Por el siguiente bloque:

path = inputbox("Ingresa la ubicacion del objeto",titulo)
if (path="") then 
	ou="cn=Users"
else
	ou = ConvertirOU(path)
end if
Anuncios

Primero nuestro inputbox no almacenara el ou convertido a mano sino el path como vimos en este post y luego chequeara si lo dejamos vacio, en caso de ser verdadero utilizara directamente a cn=users de lo contrario almacenara en ou el resultado de ConvertirOU, el resto del script trabaja de la misma forma.

Anuncios

Para nuestra siguiente modificacion en el script haremos una serie de modificaciones en el Active Directory:

  • Agregaremos nuevas OUs dentro de una OU por fuera de Users
  • Agregar nuevos grupos dentro de una OU particular
  • En lo posible que los nombre de los grupos coincidan con los sectores
  • Aunque yo pondre uno distinto para ver como trabajarlo
Anuncios

Por ejemplo pueden crear una OU con una empresa X donde despues iran creando distintos contenedores para las PCs, las Notebooks, los Servidores, los grupos y los usuarios, a su vez cada contenedor puede tener un pais o varios paises, dependiendo si la empresa es multinacional o no, en mi caso decidi dejar todos los grupos juntos en un solo OU pero si hice varios contenedores para cada uno de los sectores de esta empresa, como pueden ver en la siguiente imagen

Anuncios

A la izquierda pueden observar los OUs que genere para este ejemplo y en la derecha pueden ver los grupos que hice para la ocasion, la relacion entre ellos es la siguiente:

DepartamentoGruposAMAccountname
Call CenterCall CenterCall_Center
Comercio ExteriorComexComex
ITITIT
PresidenciaPresidenciaPresidencia
VendorsVendorsVendors
VentasVentasVentas
Nota: Podemos usar el script para crear grupos visto en este post pero deberan modificarlo porque sino creara los grupos en cn=users y despues deberan moverlos a la OU correspondiente.
Anuncios

Para nuestra siguiente modificacion agregaremos la siguiente funcion al final de nuestro codigo:

Function FindGroup(Byval GroupName, Byval Domain)

	dim vGrupo

	set cn = createobject("ADODB.Connection")
	set cmd = createobject("ADODB.Command")
	set rs = createobject("ADODB.Recordset")
	cn.open "Provider=ADsDSOObject;"

	cmd.activeconnection=cn
	cmd.commandtext="SELECT ADsPath FROM 'GC://" & Domain & _
	   "' WHERE sAMAccountName = '" & GroupName & "'"

	set rs = cmd.execute
	if err<>0 then
		 FindUser="Error conectandose a la base del AD:" & err.description
	else
		rs.MoveFirst
		vGrupo = Replace(rs(0),"GC://","")
		FindGroup=vGrupo
	end if
	cn.close
end function 
Anuncios

Dado que el FindUser trabaja de forma distinta al resto de nuestros ejemplos tuvimos que crear una funcion que sirva exclusivamente para los grupos, en este caso recibira la cuenta (o el nombre del grupo) y el dominio contenido en la constante Dominio, buscara la cuenta pasada y nos devolvera todo el path del mismo, con esto aclarado agregaremos el siguiente bloque despues de haber actualizado todos los datos del usuario:

select case lcase(departamento)
	case "presidencia"
		g="presidencia"
	case "it"
		g="it"
	case "comercio exterior"
		g="comex"
	case "vendors"
		g="vendors"
	case "ventas"
		g="ventas"
	case "call center"
		g="call_center"
end select

grupo=FindGroup(g, Dominio)
Set objGroup = GetObject("LDAP://" & grupo )
u=FindGroup(cuenta,Dominio)
objGroup.PutEx ADS_PROPERTY_APPEND, "member", Array(u)
objGroup.SetInfo
Anuncios

En base al departamento que informemos asignaremos el grupo que le corresponde, para ello usaremos un select case y para evitar inconvenientes usaremos un lcase para reducir a minusculas el valor informado, en base a cada valor capturado le asignaremos el nombre del grupo que le corresponde, en realidad el valor de sAMAccountname que se ve en la tabla, ese valor lo asignaremos a la variable g, una vez asignado el valor de g, usaremos la variable grupo a la cual le pasaremos el valor obtenido por FindGroup, una vez obtenido crearemos un objeto llamado objGroup y por medio de GetObject le asignaremos el resultado de FindGroup, despues usaremos la variable u para buscar al usuario creado y almacenado en cuenta, luego procederemos a agregarlo tal como vimos en este post y seteamos el valor modificado, con esta modificacion realizada no solamente podemos ubicar nuestros usuarios en otros lados sino tambien asignarles un grupo por defecto del sector, nuestro ultima modificacion sera para automatizar la asignacion del contenedor.

Para ello tomaremos el select case anterior y lo moveremos al final del bloque donde ingresamos los datos y eliminamos el inputbox que nos solicitaba el ingreso del path, por ultimo modificaremos el select case de la siguiente forma:

select case lcase(departamento)
	
case "presidencia"
	g="presidencia"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Presidencia")
case "it"
	g="it"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/IT")
case "comercio exterior"
	g="comex"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Comercio Exterior")
case "vendors"
	g="vendors"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Vendors")
case "ventas"
	g="ventas"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Ventas")
case "call center"
	g="call_center"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Call Center")
case else
	g="Vendors"
	ou="cn=Users"	
end select
Anuncios

En este caso tendremos el mismo select case pero le agregamos a la variable que asignara en base al departamento la ubicacion del contenedor, por medio de ConvertirOU lo convertiremos en el formato para nuestro script sin necesidad de tener que volvernos locos simplemente copiando el path que le corresponde, cual es la ventaja de usarlo asi, si aparecen nuevos sectores simplemente debemos agregarlos con mas cases tanto para los grupos como el contenedor y tambien agregamos un default para evitar errores en el script, antes de mostrar como trabaja veamos como quedo nuestro codigo final:

Const ADS_PROPERTY_APPEND = 3
Const ADS_PORPERTY_UPDATE = 2
Const Dominio = "dc=laboratorio,dc=local"
Const udominio = "laboratorio.local"
Const titulo = "Alta de usuario v. 1.0"

Dim objFSOut, objStreamout, fileout,textolog

cuenta = inputbox("Ingresa la cuenta",titulo)
nombre = inputbox("Ingresa el nombre",titulo)
apellido = inputbox("Ingresa el apellido",titulo)
uDisplay = apellido & ", " & nombre

chequeo = FindUser(cuenta,uDisplay,ucase(Dominio))

if (chequeo="Not Found") then
empresa = inputbox("Ingresa la empresa",titulo)
descrip = inputbox("Ingresa la descripcion",titulo)
pais = inputbox("Ingresa el pais",titulo)
departamento = inputbox("Ingresa el departamento",titulo)

select case lcase(departamento)
	
case "presidencia"
	g="presidencia"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Presidencia")
case "it"
	g="it"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/IT")
case "comercio exterior"
	g="comex"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Comercio Exterior")
case "vendors"
	g="vendors"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Vendors")
case "ventas"
	g="ventas"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Ventas")
case "call center"
	g="call_center"
	ou = ConvertirOU("laboratorio.local/Tinchicus/Usuarios/Argentina/Call Center")
case else
	g="Vendors"
	ou="cn=Users"	
end select

Set oRootLDAP = GetObject("LDAP://rootDSE")
Set oContenedor = GetObject("LDAP://" & ou & "," & Dominio)
Set oNuevoUsuario = oContenedor.Create("User","cn=" & chr(34) & uDisplay & chr(34))


oNuevoUsuario.put "sAMAccountName", lcase(cuenta)
oNuevoUsuario.put "givenName", nombre
oNuevoUsuario.put "sn", apellido
oNuevoUsuario.put "UserPrincipalName", lcase(cuenta) & "@" & uDominio
oNuevoUsuario.put "cn", uDisplay
oNuevoUsuario.put "DisplayName", uDisplay
oNuevoUsuario.put "company", empresa
oNuevoUsuario.put "c", pais
oNuevoUsuario.put "department", departamento
oNuevoUsuario.put "Description", descrip

oNuevoUsuario.SetInfo


grupo=FindGroup(g, Dominio)
Set objGroup = GetObject("LDAP://" & grupo )
u=FindGroup(cuenta,Dominio)
objGroup.PutEx ADS_PROPERTY_APPEND, "member", Array(u)
objGroup.SetInfo

randomize timer

dim texto

do while a<12
	if (a=0) then 

	caracter = int(rnd * 25) + 65
	texto = chr(caracter)
	a = a + 1

	else
	
	caracter = int(rnd * 122) + 1
	if ((caracter>47 and caracter<58) or (caracter>96 and caracter<123)) then
		texto = texto & chr(caracter)
		a = a + 1
	end if

	end if		 
loop

uPassword = texto

oNuevoUsuario.SetPassword uPassword
oNuevoUsuario.Put "pwdLastSet", 0

oNuevoUsuario.put "userAccountControl", 544
oNuevoUsuario.SetInfo

fileout = cuenta & ".log"

textolog = "Se creo la cuenta: " & cuenta & vbCrLf
textolog = textolog & "El nombre completo: " & uDisplay & vbCrLf
textolog = textolog & "La contraseña es: " & uPassword

Set objFSOut = CreateObject("Scripting.FileSystemObject")
Set objStreamout = objFSOut.CreateTextFile(fileout, 1, false)

objStreamout.Write textolog

objStreamout.close()
Set objStreamout = nothing
Set objFSOut = nothing

msgbox "Se creo el usuario correctamente"

else

msgbox "Se encontro el siguiente objeto: " & chequeo,,titulo

end if

Function FindUser(Byval UserName, ByVal CanonName, Byval Domain)


	set cn = createobject("ADODB.Connection")
	set cmd = createobject("ADODB.Command")
	set rs = createobject("ADODB.Recordset")
	cn.open "Provider=ADsDSOObject;"

	cmd.activeconnection=cn
	cmd.commandtext="SELECT ADsPath FROM 'GC://" & Domain & _
	   "' WHERE sAMAccountName = '" & UserName & "'"

	set rs = cmd.execute
	if err<>0 then
		 FindUser="Error conectandose a la base del AD:" & err.description
	else
		 if not rs.BOF and not rs.EOF then
			FindUser=UserName
		 else
			cmd.commandtext="SELECT ADsPath FROM 'GC://" & Domain & _
			"' WHERE cn = '" & CanonName & "'"

			set rs = cmd.execute
			if not rs.BOF and not rs.EOF then
				FindUser=CanonName
		 	else
				FindUser = "Not Found"
			end if
	 	end if
	end if
	cn.close
end function 

Function FindGroup(Byval GroupName, Byval Domain)

	dim vGrupo

	set cn = createobject("ADODB.Connection")
	set cmd = createobject("ADODB.Command")
	set rs = createobject("ADODB.Recordset")
	cn.open "Provider=ADsDSOObject;"

	cmd.activeconnection=cn
	cmd.commandtext="SELECT ADsPath FROM 'GC://" & Domain & _
	   "' WHERE sAMAccountName = '" & GroupName & "'"

	set rs = cmd.execute
	if err<>0 then
		 FindUser="Error conectandose a la base del AD:" & err.description
	else
		rs.MoveFirst
		vGrupo = Replace(rs(0),"GC://","")
		FindGroup=vGrupo
	end if
	cn.close
end function 

function ConvertirOU(ByVal camino)
	dim c, texto
	c = split(camino,"/")
	for a=ubound(c) to 1 step -1
		texto = texto & "ou=" & c(a) & ","
	next
	texto = mid(texto,1,len(texto)-1)
	ConvertirOU = texto
end function

Con esto hemos creado un script que en base a la informacion que le ingresemos procedera a decidir donde debe ubicar el objeto y que grupos debera tener asignado, por otro lado hemos reducido la maximo posible el ingreso de datos.

Anuncios

En resumen, hoy hemos visto como mejorar nuestro script de creacion de usuarios con conocimientos recientemente hechos, hemos visto como poder ubicar de mejor forma nuestros objetos, primero de forma manual y luego automatica, tambien hemos visto como asignarles un grupo en base al departamento que pertenecen y como automatizar las tareas para disminuir los ingresos del operador, en el proximo post veremos lo mismo pero aplicado a las creaciones masivas, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes comprar mi libro sobre VBscript en Amazon

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00