Active Directory: Fast & useful user information with Powershell v3

Querying user information in Active Directory Users & Computers (dsa.msc) can be a bit slow, there is information not even shown, like the date in which users changed their passwords or the expiration days left.

We can write a little script in Powershell to see the LDAP attributes we need. And the new functionality of out-gridview in Powershell v3, make easier to search the users.
Out-GridView already existed in Powershell v2, and it shown the information in a form instead of the console. That is to say it was good for nothing.
In version v3, they have implemented a new parameter -passthru that allow us to select one or more registries from the form and return them to the script.

Let's see an example:
$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"


After selecting a user from the list and press accept, that registry pass to the variable $usuario and we can work on it on the rest of the 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 expiry-password($PasswordLastChanged, $intMaxPwdAge)
{
$now=get-date
$intTimeInterval = [int32]($now - $PasswordLastChanged).days
 If ($intTimeInterval -ge $intMaxPwdAge)
  {
  $strdays="is EXPIRED"
  }
  else
  {
  $ExpiringDate = $PasswordLastChanged.addDays($intMaxPwdAge)  
  $ExpiringDays = [int32]($ExpiringDate - $now).days 
  $strdays= "expires in $ExpiringDays days ($ExpiringDate)"
  }
return $strdays
}
#### main ####
$SECS_IN_A_DAY=86400
$line= "-" * 60
if ([int32][string]$host.version -lt 3){write-warning "Current Powershell version is $($host.version)`nYou need version 3.0 or higher.";start-sleep -s 4;exit}
do
{
$strsearch=read-host "Username/Surname/mail to search in Active Directory?"
write-host $line -fore yellow
$searcher = New-Object DirectoryServices.DirectorySearcher([adsi]"")
$searcher.filter = "(&(objectclass=user)(objectcategory=person)(|(samaccountname=$strsearch)(mail=$strsearch)(sn=$strsearch*)))" 
$users = $searcher.findall()
if ($users.count -eq 0)
{
write-host "$strsearch DOESN'T EXIST" -fore red
}
else
{
 if ($users.count -eq 1)
 {
 $user=$users
 }
 else
 {
 $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"
 $user=$users|?{$_.properties.samaccountname -eq $usuario.samaccountname}  
 }
}
}while ($user -eq $null)
write-host "Active Directory Info" -fore black -back magenta
$user=$user.GetDirectoryEntry()
$usuario=$user.samaccountname
if ($user.scriptpath -ne $null){$script=$user.scriptpath}else{$script="$usuario.bat"}
write-host "Username: " -fore cyan -nonewline;write-host $usuario
write-host "UPN: " -fore cyan -nonewline;write-host "$($user.userprincipalname)"
write-host "Name: " -fore cyan -nonewline;write-host "$($user.givenname)"
write-host "Surname: " -fore cyan -nonewline;write-host "$($user.sn)"
write-host "EmployeeType: " -fore cyan -nonewline;write-host "$($user.EmployeeType)"
write-host "Created (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 ""){$mailbox="Office 365 (Cloud)"}else{$mailbox="On-premise (Exchange) " + "$($user.homeMdb)".substring(0,19)+"..."}
write-host "mailbox: " -fore cyan -nonewline;write-host "$mailbox"
}
$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 "Password changed on $PasswordLastChanged" -fore yellow
$strdays=expiry-password $PasswordLastChanged $intMaxPwdAge
write-host "Password $strdays" -fore yellow}
write-host "Distinguishedname: " -fore cyan -nonewline;write-host "$($user.distinguishedname)"
write-host "UserAccountControl Flags:" -fore cyan
$flags
write-host $line -fore yellow

Comments