Active Directory: Rapida Información útil de usuarios con Powershell v3

Consultar la información de un usuario en Active Directory Users & Computers (dsa.msc) puede ser un poco lenta, incluso hay información que no muestra facilmente como la fecha en que cambió la contraseña. o los dias que faltan para que caduque.

Podemos hacer un pequeño script en Powershell para ver rapidamente los atributos LDAP que nos interesen. Y la nueva funcionalidad de out-gridview de Powershell v3, facilita un monton  la busqueda de usuarios.
Out-GridView ya existia en Powershell v2, y servia para sacar la información a un formulario en lugar de la consola, es decir, no valia para nada.
A partir de la version v3, han implementado un nuevo parametro -passthru que nos permite seleccionar uno o varios registro del formulario y devolverlos al script.

Veamos un ejemplo:
$strsearch="John"
$searcher = New-Object DirectoryServices.DirectorySearcher([adsi]"")
$searcher.filter = "(&(objectclass=user)(objectcategory=person)(givenname=$strsearch))" 
$users = $searcher.findall()
$usuarios=@()
foreach ($user in $users)
{
 $usuarios+=new-object PSObject -property @{  
  givenname=[string]$user.properties.givenname
  sn=[string]$user.properties.sn
  displayname=[string]$user.properties.displayname
  samaccountname=[string]$user.properties.samaccountname 
  }
}
$usuario=$usuarios|select samaccountname,givenname,sn,displayname|out-gridview -passthru -title "Pick a user"
He creado un objeto PSObject para almacenar 4 atributos basicos a modo de previsualización ya que la consulta devuelta tiene todos los atributos bajo properties, y no voy a hacer un GetDirectoryEntry() mientras no haya elegido elegido al usuario que me interesa.



Al seleccionar un usuario de la lista y pulsar aceptar ese registro pasa a la variable $usuario y podemos trabajar con él en el resto del script.

Function Get-UAC($uac)
{
$flags=@()
if ((2 -band $uac) -ne "0"){$flags+="ACCOUNTDISABLE"}
if ((32 -band $uac) -ne "0"){$flags+="PASSWD_NOTREQD"}
if ((512 -band $uac) -ne "0"){$flags+="NORMAL_ACCOUNT"}
if ((65536 -band $uac) -ne "0"){$flags+="DONT_EXPIRE_PASSWORD"}
return $flags
}
Function caducidad-contraseña($PasswordLastChanged, $intMaxPwdAge)
{
$ahora=get-date
$intTimeInterval = [int32]($ahora - $PasswordLastChanged).days
 If ($intTimeInterval -ge $intMaxPwdAge)
  {
  $strdias="está CADUCADA"
  }
  else
  {
  $ExpiringDate = $PasswordLastChanged.addDays($intMaxPwdAge)
  $fechacaducidad=$Expiringdate.toString("dd/MM/yyyy")
  $ExpiringDays = [int32]($ExpiringDate - $ahora).days 
  $strdias= "caduca en $ExpiringDays dias ($fechacaducidad)"
  }
return $strdias
}
#### main ####
$SECS_IN_A_DAY=86400
$raya= "-" * 60
if ([int32][string]$host.version -lt 3){write-warning "la version de powershell actual es $($host.version)`nNecesitas la version 3.0 o superior.";start-sleep -s 4;exit}
do
{
$buscar=read-host "Usuario/Apellido/mail a buscar en Directorio activo?"
write-host $raya -fore yellow
$searcher = New-Object DirectoryServices.DirectorySearcher([adsi]"")
$searcher.filter = "(&(objectclass=user)(objectcategory=person)(|(samaccountname=$buscar)(mail=$buscar)(sn=$buscar*)))" 
$users = $searcher.findall()
if ($users.count -eq 0)
{
write-host "NO EXISTE USUARIO $BUSCAR" -fore red
}
else
{
 if ($users.count -eq 1)
 {
 $user=$users
 }
 else
 {
 $usuarios=@()
 foreach ($user in $users)
 {
 $usuarios+=new-object PSObject -property @{  
  nombre=[string]$user.properties.givenname
  apellidos=[string]$user.properties.sn
  displayname=[string]$user.properties.displayname
  samaccountname=[string]$user.properties.samaccountname 
  }
 }
 $usuario=$usuarios|select samaccountname,nombre,apellidos,displayname|out-gridview -passthru -title "Elige un usuario"
 $user=$users|?{$_.properties.samaccountname -eq $usuario.samaccountname}  
 }
}
}while ($user -eq $null)
write-host "Datos Active Directory" -fore black -back magenta
$user=$user.GetDirectoryEntry()
$usuario=$user.samaccountname
if ($user.scriptpath -ne $null){$script=$user.scriptpath}else{$script="$usuario.bat"}
write-host "Cuenta de usuario: " -fore cyan -nonewline;write-host $usuario
write-host "UPN: " -fore cyan -nonewline;write-host "$($user.userprincipalname)"
write-host "Nombre: " -fore cyan -nonewline;write-host "$($user.givenname)"
write-host "Apellidos: " -fore cyan -nonewline;write-host "$($user.sn)"
write-host "EmployeeType: " -fore cyan -nonewline;write-host "$($user.EmployeeType)"
write-host "Alta (mm/dd/yyyy): " -fore cyan -nonewline;write-host "$($user.whenCreated)"
if ($user.mail -ne $null)
{
write-host "Mail: " -fore cyan -nonewline;write-host "$($user.mail)"
if ([string]$user.homeMTA -eq ""){$buzon="Office 365 (en la nube)"}else{$buzon="On-premise (Exchange) " + "$($user.homeMdb)".substring(0,19)+"..."}
write-host "Buzon: " -fore cyan -nonewline;write-host "$Buzon"
}
$uac=$user.userAccountControl
$flags=Get-Uac("$uac")
if ($flags -notcontains "DONT_EXPIRE_PASSWORD")
{
$domain = [ADSI]"WinNT://$env:userdomain"
$intMaxPwdAge =($domain.maxpasswordage.value)/$SECS_IN_A_DAY
$PasswordLastChanged =$user.PasswordLastChanged
write-host "Cambió la contraseña el $($PasswordLastChanged.toString("dd/MM/yyyy"))" -fore yellow
$strdias=caducidad-contraseña $PasswordLastChanged $intMaxPwdAge
write-host "La contraseña $strdias" -fore yellow}
write-host "Distinguishedname: " -fore cyan -nonewline;write-host "$($user.distinguishedname)"
write-host "UserAccountControl Flags:" -fore cyan
$flags
write-host $raya -fore yellow

Comentarios