
Con suerte, alguien puede solucionar un código simple con el que he estado jugando. Comenzaré diciendo que NO soy un codificador y que en realidad nunca he hecho mucho PowerShell.
El problema es que al principio esto funcionaba y devolvía LastLogonTimeStamp como se esperaba.
Ahora, cuando lo ejecuto, no obtengo ningún resultado en esta columna.
Estoy bastante seguro de que es algo estúpido que estoy pasando por alto, pero no puedo entenderlo.
Como dije, literalmente no tengo experiencia en esto, no sé qué significa la mitad del código.
¿Alguien podría ayudarme?
# Script to list member of VDI Desktop Users Group
# and export details to c:\VDIlastlogon.csv file
# [email protected] 24/11/14'
# Function get-NestedMembers
# List the members of a group including all nested members of subgroups
Import-Module ActiveDirectory
function get-NestedMembers ($group){
if ($group.objectclass[1] -eq 'group') {
write-verbose "Group $($group.cn)"
$Group.member |% {
$de = new-object directoryservices.directoryentry("LDAP://$_")
if ($de.objectclass[1] -eq 'group') {
get-NestedMembers $de
}
Else {
$de
}
}
}
Else {
Throw "$group is not a group"
}
}
# get a group
$group = new-object directoryservices.directoryentry("LDAP://CN=VDI Desktop Users,ou=Groups,ou=x,ou=uk,dc=uk,dc=x,dc=com")
# Get all nested members and send to CSV file
get-NestedMembers $group|FT @{l="First Name";e={$_.givenName}},@{l="Last Name";e={$_.sn}},@{l="Last Logon";e={[datetime]::FromFileTime($_.ConvertLargeItegerToInt64($_.lastLogonTimestamp[0]))}},sAMAccountName | tee c:\VDILastLogon.csv
#Send CSV file to mail recipient
$PSEmailServer = "mail.x.net"
$smtpServer = "mail.x.net"
$file = "c:\VDILastLogon.csv"
$att = new-object Net.Mail.Attachment($file)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient ($smtpServer)
$msg.From = "[email protected]"
$msg.To.Add("[email protected]")
$msg.Subject = "User logon report from VDI Solution"
$msg.Body = "Please find attached the most recent user logon report"
$msg.Attachments.Add($att)
$smtp.Send($msg)
$att.Dispose()
Respuesta1
Si importa el módulo AD PowerShell, no debería necesitar utilizar objetos de servicios de directorio adicionales (al menos no en esta ocasión). Puede usar el Get-ADGroupMember
cmdlet -Resursive
y también debería encontrar a sus usuarios anidados.
Editar: agregué -Server
argumentos a los cmdlets de AD para que pueda especificar controladores de dominio particulares. Los atributos de marca de tiempo pueden diferir (también lo hacen en mis 12 DC). Controlareste blogpara una reseña decente.
Esto obtiene la hora del último inicio de sesión y es un poco más fácil de leer:
$groupname = "name_of_AD_group"
Import-Module ActiveDirectory
Get-ADDomainController -Filter * | % {
$DC = $_
$group = Get-ADGroup -Identity $groupname -Server $DC.Name -ErrorAction SilentlyContinue
If ($group) {
$members = Get-ADGroupMember -Identity $group.Name -Recursive -Server $DC.Name -ErrorAction SilentlyContinue
ForEach ($member In $members) {
If (-not $member.objectClass -ieq "user") { Continue }
$user = Get-ADUser $member.SamAccountName -Server $DC.Name -ErrorAction SilentlyContinue
If ($user) {
$lastlogon = ($user | Get-ADObject -Properties lastLogon).LastLogon
New-Object PSObject -Property @{
"First Name" = $user.GivenName
"Last Name" = $user.Surname
"DC" = $DC.Name
"Last Logon" = [DateTime]::FromFileTime($lastlogon)
"SamAccountName" = $user.SamAccountName
}
} Else {
# $user not found on $DC
}
}
} Else {
# $groupname not found on $DC
}
} | ft -auto
Respuesta2
Este es un truco pero funciona. Tomé el Get-ADUserLastLogon de un artículo de Microsoft (http://technet.microsoft.com/en-us/library/dd378867%28v=ws.10%29.aspx)
Import-Module ActiveDirectory
function Get-ADUserLastLogon([string]$userName)
{
$dcs = Get-ADDomainController -Filter {Name -like "*"}
$time = 0
foreach($dc in $dcs)
{
$hostname = $dc.HostName
$user = Get-ADUser $userName | Get-ADObject -Properties lastLogon
if($user.LastLogon -gt $time)
{
$time = $user.LastLogon
}
}
$dt = [DateTime]::FromFileTime($time)
return $dt
}
function get-NestedMembers ($group){
if ($group.objectclass[1] -eq 'group') {
write-verbose "Group $($group.cn)"
$Group.member |% {
$de = new-object directoryservices.directoryentry("LDAP://$_")
if ($de.objectclass[1] -eq 'group') {
get-NestedMembers $de
}
Else {
$de
}
}
}
Else {
Throw "$group is not a group"
}
}
# get a group
$group = new-object directoryservices.directoryentry("LDAP://CN=Domain Users,CN=Users,DC=yourdomain,DC=com")
# Get all nested members and send to CSV file
get-NestedMembers $group|FT @{l="First Name";e={$_.givenName}},@{l="Last Name";e={$_.sn}},@{l="Last Logon";e={Get-ADUserLastLogon($_.sAMAccountName)}},sAMAccountName | tee c:\VDILastLogon.csv