Active Directory: Limpieza de equipos obsoletos

Para poder filtrar las maquinas obsoletas  del directorio activo, he usado el atributo lastlogontimestamp.
Es un atributo que puede no estar tan actualizado como el atributo lastlogon, pero lastlogon no se replica entre los controladores de dominio por lo que tendrias que preguntar a todos hasta saber la fecha real de ultimo logon en el dominio.
lastlogontimestamp si se replica, pero su fecha puede estar hasta 14 dias desactualizada con la fecha real.
Para mi caso, que voy a filtrar las maquinas que no han conectado en 100 dias, 14 dias arriba o abajo no me importan demasiado.

function listar-obsoletas()
{
$maxOldLogonDays = 100
$ahora=get-date
$Dom='LDAP://DC=dominio,DC=local'
$objDomain   = New-Object System.DirectoryServices.DirectoryEntry $Dom
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 2000
$objSearcher.filter = "(&(objectCategory=Computer))"
$machines=$objSearcher.FindAll()
out-file "maquinasobsoletas.csv" -input "NAME OS LASTLOGONTIMESTAMP DAYS PATH"
Foreach($machine in $machines) 
{
$lastlogon=get-date ([DateTime]::FromFileTime([Int64]::Parse($machine.properties.lastlogontimestamp)))
$intTimeInterval = [int32]($ahora - $lastlogon).days
 if ($intTimeInterval -gt $maxOldLogonDays -and [string]$machine.properties.distinguishedname -notmatch "OU=EquiposObsoletos")
 {
 $ESPlastlogon=get-date ($lastlogon) -uformat "%d/%m/%Y"
 $msg="$($machine.properties.name) $($machine.properties.operatingsystem) $ESPlastlogon $intTimeInterval $($machine.path)"
 out-file "maquinasobsoletas.csv" -input $msg -append
 write-host $msg
 }

} #fin foreach
}#fin funcion listar-obsoletas

function mover-maquinas()
{
$rutaobsoletos=[ADSI]("LDAP://OU=EquiposObsoletos,OU=Equipos,DC=dominio,DC=local")
$content=get-content("maquinasobsoletas.csv")
foreach ($linea in $content)
 {
 $campo=$linea.split(" ") #tabulador
 $name=$campo[0]
 $path=$campo[4]
 write-host "Moviendo $name a OU de Obsoletos"
 $from = new-object System.DirectoryServices.DirectoryEntry($path)
 $from.MoveTo($rutaobsoletos)
 }
}#fin funcion mover-maquinas

###main###
write-host "REVISAR/LIMPIAR MAQUINAS OBSOLETAS ACTIVE DIRECTORY" -fore cyan
Write-host "1. Listar maquinas obsoletas" -fore cyan
write-host "2. Mover maquinas obsoletas" -fore cyan
$val=read-host "Elige una opción"

switch ($val)
{
1{listar-obsoletas}
2{mover-maquinas}
}#fin del switch

He separado el script en dos funciones, la primera saca el listado, a un archivo csv y la segunda mueve las maquinas del listado a una OU creada especificamente para guardar las maquinas obosletas.
De hecho la primera funcion excluye del listado las maquinas que ya estan en la OU de obsoletas.

Comentarios