Propósito:
El escenario es una empresa con muchos PCs repartidos en cientos de localizaciones. Ausencia de una herramienta de inventario y la dificultad en ocasiones de identificar quien ha sido la última persona que ha utilizado ese PC.
El problema es que si pasa algo y tenemos que contactar, entre otras cosas para que lo encienda, sin información sería una tarea complicada.
Lo que voy a guardar es: usuario + timestamp último logon, en TAREA PROGRAMADA en LOGON que se ejecuta con contexto del usuario como SYSTEM.
Lo bueno es que guardaras esta información en el AD, con lo que podrás consultarla aún estando apagado el PC.
Pasos
FASE 1
[ ] Ir a la OU donde están los PCs a gestionar
[ ] Delegar control….
Añadimos el usuario SELF
Elegimos el “extensionAttribute10”
FASE 2:
Pon el script en un recurso donde lleguen todos los PC, lo
normal el SYSVOL, para llamarlo desde la GPO.
Script
|
#gon 20260616 Start-Sleep -Seconds 5 $Computer = $env:COMPUTERNAME $User = (Get-WmiObject
Win32_ComputerSystem).UserName $Date = Get-Date -Format
"yyyy-MM-dd HH:mm:ss" if ($User) {
$Value = "$User - $Date"
$searcher = New-Object DirectoryServices.DirectorySearcher
$searcher.Filter =
"(&(objectClass=computer)(name=$Computer))"
$result = $searcher.FindOne()
if ($result) { $entry = $result.GetDirectoryEntry()
$entry.Put("extensionAttribute10", $Value) $entry.SetInfo() } } |
FASE 3, La GPO
En el DC:
Set-ADComputer
pc05 -Replace @{extensionAttribute10="hola gon"}
()Para leer el valor del nuevo atributo
Get-ADComputer
pc05 -Properties extensionAttribute10 | Select Name, extensionAttribute10
()Para mirar todos los PCs del AD:
*****************************************************************************************************
Resultado:
PC001-DOMINIO\usuario-2026-07-01 09:15:00-192.168.10.25-00:11:22:33:44:55
Si detecta errores:
PC001-DOMINIO\usuario-2026-07-01 09:15:00-192.168.10.25-00:11:22:33:44:55|cyserver:NOK-Stopped,CPHBWatcher:NOK-NotFound
Servicios en el PC como:
|
Start-Sleep -Seconds 5
$Computer = $env:COMPUTERNAME $User = (Get-WmiObject
Win32_ComputerSystem).UserName $Date = Get-Date -Format
"yyyy-MM-dd HH:mm:ss"
if ($User) {
# Obtener IP y MAC principal
$NIC = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object { $_.IPEnabled -eq $true -and $_.MACAddress } | Select-Object -First 1
$IP = ""
if ($NIC)
{ $IP = $NIC.IPAddress | Where-Object { $_ -match
'^\d{1,3}(\.\d{1,3}){3}$' } | Select-Object -First 1
$MAC = $NIC.MACAddress
}
else
{ $MAC = ""
}
$Value = "$Computer-$User-$Date-$IP-$MAC"
$services = @( "cyserver", "xdrhealth", "GoNBadService", "CPHBWatcher"
) $nokList = @() # Dar tiempo al arranque de servicios Start-Sleep -Seconds 90
foreach ($s in $services)
{ try { $svc = Get-Service -Name $s
-ErrorAction Stop
if ($svc.Status -ne
"Running") { $nokList +=
"${s}:NOK-$($svc.Status)" } } catch { $nokList +=
"${s}:NOK-NotFound" }
}
if ($nokList.Count -gt 0)
{ $Value = "$Value|" +
($nokList -join ",")
}
$searcher = New-Object DirectoryServices.DirectorySearcher
$searcher.Filter =
"(&(objectClass=computer)(name=$Computer))"
$result = $searcher.FindOne()
if ($result)
{ $entry = $result.GetDirectoryEntry()
$entry.Properties["extensionAttribute10"].Value = $Value
$entry.CommitChanges() } } |
Como tengo la información en el AD, si un PC no tiene arrancado o instalado el antivirus, puedo enviar un email a Help Desk para que lo revise. Genero una tarea programada a las 11:00 de la mañana, cuando en principio ya se han logeado mis usuarios y nutrido la información. Solo verifica los del día en curso.
|
<# .SYNOPSIS Revision
diaria de servicios criticos. .DESCRIPTION El script
revisa el atributo extensionAttribute10 de todos los equipos de Active
Directory. Solo
considera equipos que: - Han
actualizado extensionAttribute10 durante el dia actual. - Contienen
la cadena NOK. Si existen
equipos afectados: - Genera un
CSV. - Genera un
correo HTML. - Adjunta el
CSV. - Envia el
correo. Si no existen
equipos afectados: - No envia
correo. - Finaliza
sin generar alertas. Disenado para
ejecucion mediante Tarea Programada. #>
Import-Module ActiveDirectory
-ErrorAction Stop
# ========================== # VARIABLES
DEL USUARIO #
========================== $SMTPServer =
"smtp.xxxx.com" $SMTPPort = 25 $From = "alerta@midom.com" $To = "HelpDesk@midom.com" $Subject = ""
# ========================== # CONFIGURACION # ========================== $Hoy = Get-Date -Format
"yyyy-MM-dd" $FechaActual = Get-Date -Format
"yyyy-MM-dd - HH:mm"
$RutaInforme =
"C:\Scripts\Informes"
if (!(Test-Path $RutaInforme)) {
New-Item -Path $RutaInforme -ItemType Directory -Force | Out-Null }
$CSVFile = Join-Path $RutaInforme
"ServiciosCriticos_NOK_$Hoy.csv"
try { # ========================== # OBTENCION DE EQUIPOS # ========================== $EquiposConProblemas = Get-ADComputer ` -LDAPFilter "(extensionAttribute10=*)" ` -Properties extensionAttribute10 | Where-Object { $_.extensionAttribute10 -like
"*$Hoy*" -and $_.extensionAttribute10 -like
"*NOK*" } | Select-Object @{ Name = "Equipo" Expression = { $_.Name } }, @{ Name = "Detalle" Expression = {
$_.extensionAttribute10 } } | Sort-Object Equipo
$TotalEquipos = $EquiposConProblemas.Count # ========================== # SOLO SI HAY NOK # ========================== if ($TotalEquipos -gt 0) { # ========================== # EXPORTACION CSV # ========================== $EquiposConProblemas | Export-Csv ` -Path $CSVFile ` -Delimiter ";" ` -NoTypeInformation ` -Encoding UTF8 # ========================== # ASUNTO # ========================== $Subject = "$FechaActual -
Equipos con problemas al arrancar servicios criticos - $TotalEquipos
elementos" # ========================== # TABLA HTML # ========================== $TablaHTML = $EquiposConProblemas | ConvertTo-Html -Fragment $Body = @" <html>
<head>
<style>
body{
font-family: Arial;
font-size: 10pt; }
table{
border-collapse: collapse; }
table, th, td{
border: 1px solid black;
padding: 5px; }
th{
background-color: #D9EAD3; }
</style>
</head> <body> <h2>Revision
diaria de servicios criticos</h2> <p> De los PC que
hoy se han conectado, se han encontrado <b>$TotalEquipos</b>
equipos con problemas al arrancar servicios criticos. </p> <p> Fecha de
ejecucion: $(Get-Date) </p> $TablaHTML <br> <p> Se adjunta el
detalle completo en formato CSV. </p> </body> </html> "@ # ========================== # ENVIO EMAIL # ========================== Send-MailMessage ` -SmtpServer $SMTPServer ` -Port $SMTPPort ` -From $From ` -To $To ` -Subject $Subject ` -Body $Body ` -BodyAsHtml ` -Attachments $CSVFile ` -Encoding UTF8
} } catch {
$ErrorMessage = $_.Exception.Message
$Subject = "$FechaActual - Error revision servicios
criticos" $Body = @" <html> <body> <h2>Error
durante la ejecucion</h2> <p> Se ha
producido un error durante la revision diaria. </p>
<p> $ErrorMessage </p>
</body> </html> "@
Send-MailMessage ` -SmtpServer $SMTPServer ` -Port $SMTPPort ` -From $From ` -To $To ` -Subject $Subject ` -Body $Body ` -BodyAsHtml ` -Encoding UTF8 } |
%20-%20Word.jpg)
No hay comentarios:
Publicar un comentario