Limpiapendrives, o como empeze a scriptear.

Hoy comparto mi primer script, de cuando recién arrancaba.
El 11 de julio del 2011, mi hermana vino a casa con un pendrive infectado con un virus que ocultaba todos los archivos y creaba accesos directos que apuntaban a un .vbs que se copiaba a los demás discos.
Básicamente lo que hace es sacarle a todos los archivos del directorio y subcarpetas donde se corre los atributos Hidden, System y Read-Only.

Me había olvidado de este pequeño paso, pero hoy me lleve una sorpresita, ya que me entere que todo el curso de mi hermana (y varias personas mas) lo usan casi a diario!

Pueden bajar el .bat de aca mismo (o para los mas curiosos, acá abajo les va la transcripción)

@echo off
echo Este ejecutable te devuelve todo lo que tenias en el pendrive.
echo Acordate de borrar todos los accesos directos y los .EXE que estan aca.
attrib /d /s -r -h -s *.*
echo.
echo.
echo Listo!
echo.
echo.
echo.
echo Creado por Lucas Camilo
echo.
echo.
pause
exit
view raw LimpiaPendrives.bat hosted with ❤ by GitHub

Gracias Clari por la inspiración para un nuevo post! 🙂

Feliz dia del sysadmin!

Hoy, como todos los ultimos viernes de julio, es el dia del sysadmin.
Vayan a abrazar a su administrador de sistemas amigo, haganle un regalito, aunque sea un mail para saludarlos, un poco de reconocimiento cada tanto no viene mal 🙂

Y para mis compañeros, sumense hoy a la AdminFest, mas abajo les dejo el mapita de como llegar.

 

Ver usuarios bloqueados

Alguna vez les paso que un usuario de Active Directory se les bloqueo varias veces una misma semana? Y un mismo día?
Bueno, a no preocuparse, con este pequeño script vamos a poder ver en donde se produce ese bloqueo o intento fallido de login para poder resolverlo fácilmente.

Antes que nada, necesitamos tener instaladas las herramientas de administración remota (también llamado RSAT).
Podemos bajarlas desde estos links:
Windows 7 x86
Windows 7 x64

Una vez instalados, solo queda abrir una ventana de Powershell y ejecutar el siguiente script.

function show-progressbar([int]$actual,[int]$completo,[string]$status,[string]$Activity)
{
$porcentaje=($actual/$completo)*100
if (!$status){
$status="Buscando datos $actual de $completo"
}
if (!$Activity){
$Activity="Obteniendo Resultados"
}
Write-Progress -Activity $Activity -status $status -percentComplete $porcentaje
}
###############################################################
# Ya explique esta funcion en este post #
# https://powershelleando.com.ar/2014/05/30/show-progressbar/ #
###############################################################
import-module activedirectory
$logcompleto=@()
$logdcs=@()
$cuentadc=1
# crea una carpeta "Eventos". Si ya existe no hace nada.
New-Item -Name eventos -Type directory -Force
# Levanta todos los DCs
$dcs=Get-ADDomainController -Filter *
$dctotal=$dcs.count
foreach ($dc in $dcs){
$nombredc=$dc.name
# Variable de ayuda para filtrar cuando no hay eventos
$sineventos=$false
$cuentaeventos=0
# Variable de ayuda para filtrar eventos de no repeticion
$mostrar=$true
$tipo=" "
# Revisando Domain Controller $nombredc - Chequeando disponibilidad.
$Status="Revisando Domain Controller $nombredc ($cuentadc de $dctotal)- Chequeando disponibilidad."
show-progressbar $cuentadc $dctotal $status
$online = Test-Connection $nombredc -Quiet -count 1
if ($online){
# Revisando Domain Controller $nombredc - Recuperando eventos.
$Status="Revisando Domain Controller $nombredc ($cuentadc de $dctotal) - Recuperando eventos."
show-progressbar $cuentadc $dctotal $status
# Get-WinEvent busca en el log de eventos, usamos -FilterXPath
#para consultar por eventos especificos, en este caso, indicamos
#los dos EventIDs que nos pueden resultar interesantes.
# EventID=4740 es el evento de bloqueo de usuario
# EventID=4625 es el evento de intento fallido de login
$logs=(Invoke-Command -computername $nombredc -ScriptBlock {Get-WinEvent -FilterXml "<QueryList><Query Path='Security'><Select Path='Security'>*[System[(EventID=4740 or EventID=4625)]]</Select></Query></QueryList>" -ErrorAction silentlyContinue} )
if ($logs -eq $null){
# Marca que no hay eventos para acomodar
$sineventos=$true
$eventostotal=0
}
if (!$sineventos){
$eventostotal=$logs.count
# Revisa evento por evento
foreach ($evento in $logs){
$cuentaeventos+=1
# Revisando Domain Controller $nombredc - cantidad de eventos
$Status="Revisando Domain Controller $nombredc ($cuentadc de $dctotal) - Evento numero $cuentaeventos de $eventostotal"
show-progressbar $cuentadc $dctotal $status
# mensaje tiene la variable message del evento
$mensaje=$evento.message
$hora=$evento.TimeCreated.ToShortTimeString()
$fecha=$evento.TimeCreated.ToShortDateString()
$id=$evento.ID
$datos=$mensaje.Split("`n")
Switch ($id)
{
4740{
## CASE 4740 - Bloqueo de un usuario
# datos[10] tiene la linea del usuario
$usuario=(($datos[10].split("`t"))[3])
# datos[13] tiene la linea del equipo que genero el evento
$Maquina=(($datos[13].split("`t"))[2])
$tipo="Bloqueo"
## FIN CASE 4740
}
4625{
## CASE 4625 - Intento de login fallido
## (chequear por si es un error)
if ($evento.Providername -eq "Microsoft-Windows-Security-Auditing"){
# datos[12] tiene la linea del usuario
$usuario=(($datos[12].split("`t"))[3])
# datos[25] tiene la linea del equipo que
#genero el evento
$Maquina=(($datos[25].split("`t"))[2])
$tipo="Intento de Login"
}
else{
$mostrar=$false
}
## FIN CASE 4625
}
default{
## Hubo un error.
$usuario="ERROR"
$maquina="ERROR"
$tipo="ERROR"
}
}
if ($mostrar){
$logcompleto+= $usuario | select-object @{Expression={$usuario};Label="Usuario"},@{Expression={$maquina};Label="Equipo"},@{Expression={$tipo};Label="Evento"},@{Expression={$fecha};Label="Fecha"},@{Expression={$Hora};Label="Hora"},@{Expression={$nombredc};Label="DC"}
}
}
}
}
else{
# Si el domain controller no esta disponible
write-host "El domain controller $nombredc esta OFFLINE" -backgroundcolor "red" -ForegroundColor black
}
$logDCS+=$cuentadc|select-object @{Expression={$nombredc};Label="DC"}, @{Expression={$online};Label="Online"}, @{Expression={$cuentaeventos};Label="Eventos"}
$cuentadc+=1
}
# Exporta el log de los usuarios bloqueados a CSV
$logcompleto| export-csv ./eventos/Log_Bloqueados.csv
# Exporta el log de estado de los DCs a CSV
$logdcs | export-csv ./eventos/log_dcs.csv
##Fin

Esto fue todo por hoy, si tienen alguna duda, comentario o sugerencia pueden escribirme mas abajo.

Hasta la próxima!

Show-ProgressBar

Hoy voy a mostrar una pequeña función que suelo usar cuando corro algún ciclo largo, mas que nada para poder seguirlo paso a paso mientras se ejecuta.

Los únicos datos que si o si hay que pasarle son los números actual y el total de registros del ciclo que se esta recorriendo.

function show-progressbar([int]$actual,[int]$completo,[string]$status,[string]$Activity)
{
$porcentaje=($actual/$completo)*100
# Si no le pasamos un parametro $Status, pone uno generico
if (!$status){
$status="Buscando datos $actual de $completo"
}
# Si no le pasamos un parametro $Activity, pone uno generico
if (!$Activity){
$Activity="Obteniendo Resultados"
}
Write-Progress -Activity $Activity -status $status -percentComplete $porcentaje
}
view raw Show-ProgressBar.ps1 hosted with ❤ by GitHub

En los proximos scripts voy a usar esta pequeña funcion, asi que preferia presentarla primero antes de marear a algun colgado.

Hasta la próxima!

Hola!

Hace tiempo que andaba con ganas de tener un lugar publico donde compartir la magia (?) que hago con esta genial herramienta que es Powershell. El único problema estaba en lo poco creativo que soy cuando tengo que escribir, y eso hacia que cada vez que me decidía a hacer algo así, lo dejaba de lado.

PERO BASTA!

A partir de ahora, cada script que escriba, cada función que arme, cada comando que ejecute VA A ESTAR PUBLICADO ACÁ. Eso es una promesa.

Por que?

Para crecer y mejorar necesitamos ayuda, ya sea de un libro, un amigo, o un salame que haya hecho tu misma pregunta antes.
Mucho tiempo me aproveche de este ultimo caso, leyendo en distintos foros, blogs, artículos de Technet, en donde sea que pudiera encontrar algo, una puntita de información que me acercara a donde quería (o necesitaba) llegar.
Hoy no me alcanza con eso. Quiero poder ser esa persona a la cual le agradecen en silencio, esa persona que le salva las papas a un pobre pibe de soporte que tiene que arreglar un quilombo gigante por si solo, o al super mega administrador que necesita ver el problema desde otro angulo.
Tantos años leyendo y leyendo me dieron ganas de dejar de solo aprovechar la información, y empezar a crear algo por mi cuenta.

Así surgió esta idea hace un tiempo, y hoy se materializa en este intento de blog, ya veremos como sigue.

Hasta el próximo update (que les prometo que va a ser menos chamuyo y mas código)

Luke.