Listar los Domain controllers de un dominio

$dcObj = [adsi]"LDAP://OU=domain controllers,dc=ar,dc=lugsaju,dc=com"
$dcs = $dcObj.PSBase.Children | % { $_.name }
$cantDCs = $dcs.count
$contDC = 0
foreach ($dc in $dcs){
$a = ping -n 1 $dc
$a = $(($a[2]).split("[")[1]).split("]")[0]
write-output "$dc`t$a"
}

con la ip de bonus track

función para nombrar archivos de log - vbscript

Function NomArch(NomArch)    ' Para nombrar los archivos.
Dim arch,hoy,aa,mm,dd
hoy = Date
aa = year(hoy)
mm = month(hoy)
dd = day(hoy)
arch = aa & "_0" & mm & "_" & dd & "_" & NomArch & ".log" ' Formato: \AAAA_MM_DD_NomArch.log
NomArch = arch
End Function

' uso
Set objFS = CreateObject("Scripting.FileSystemObject")
carpeta = "C:\logs"
ArchLogGen = "LogGeneral"
NomLog = NomArch(strArchLogGen)
Set logArchLogGen = objFS.OpenTextFile(carpeta & NomLog, 8,TRUE)

objFS.Close

Ultimo logon de usuario

Creditos a Richard Mueller por el script, posteado originalmente aqui.
He modificado la propiedad LastLogon por LastLogonTimeStamp, valor que SI se replica entre DCs.



Option Explicit

Dim objRootDSE, adoConnection, adoCommand, strQuery
Dim adoRecordset, strDNSDomain, objShell, lngBiasKey
Dim lngBias, k, strDN, dtmDate, objDate, nom
Dim strBase, strFilter, strAttributes, lngHigh, lngLow

' Obtain local Time Zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
& "TimeZoneInformation\ActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
lngBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
lngBias = 0
For k = 0 To UBound(lngBiasKey)
lngBias = lngBias + (lngBiasKey(k) * 256^k)
Next
End If
Set objShell = Nothing

' Determine DNS domain from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
Set objRootDSE = Nothing

' Use ADO to search Active Directory.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection

' Search entire domain.
strBase = ""

' Filter on all user objects.
strFilter = "(&(objectCategory=person)(objectClass=user))"

' Comma delimited list of attribute values to retrieve.
strAttributes = "distinguishedName,sAMAccountName,lastLogonTimeStamp"

' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

' Run the query.
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 1000000
adoCommand.Properties("Timeout") = 6000
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute

' Enumerate resulting recordset.
Do Until adoRecordset.EOF
' Retrieve attribute values for the user.
strDN = adoRecordset.Fields("sAMAccountName").Value
nom = adoRecordset.Fields("sAMAccountName").Value
' Convert Integer8 value to date/time in current time zone.
On Error Resume Next
Set objDate = adoRecordset.Fields("lastLogonTimeStamp").Value
If (Err.Number <> 0) Then
On Error GoTo 0
dtmDate = #1/1/1601#
Else
On Error GoTo 0
lngHigh = objDate.HighPart
lngLow = objDate.LowPart
If (lngLow < 0) Then
lngHigh = lngHigh + 1
End If
If (lngHigh = 0) And (lngLow = 0 ) Then
dtmDate = #1/1/1601#
Else
dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow)/600000000 - lngBias)/1440
End If
End If
' Display values for the user.
If (dtmDate = #1/1/1601#) Then
Wscript.Echo nom & ";Never"
Else
Wscript.Echo nom & ";" & dtmDate
End If
adoRecordset.MoveNext
Loop

' Clean up.
adoRecordset.Close
adoConnection.Close
Set adoConnection = Nothing
Set adoCommand = Nothing
Set adoRecordset = Nothing
Set objDate = Nothing

Directorios con mas de 255 caracteres

Cuando una ruta excede los 255 caracteres, no se puede borrar por limitación del sistema de archivos (permite crear, pero no eliminar). Como no encontré una herramienta, se me ocurrió lo siguiente:

dado 2 carpetas:
d:\carpetaMala
d:\carpetaVacia

robocopy /ZB /MIR d:\carpetaVacia d:\carpetaMala

con esto hacemos un "espejo" de la carpeta Vacia contra la Carpeta con datos erroneos. De ésta manera se eliminan todos los archivos y carpetas (incluyendo los inválidos).

Conexión a Escritorio Remoto

Muy buenas, amigos!

{Antes que nada quiero hacerles la aclaración de que ésto del escritorio remoto funciona sólo si en la red donde se encuentra la PC remota o la red donde estamos nosotros tenemos corriendo un SO servidor (Windows 2000 server o 2003 server, ambos en todas sus versiones), ya que es necesario que el mismo nos brinde el servicio de "Terminal Server". De lo contrario les recomiendo utilizar aplicaciones como: RAdmin o VNC, donde nosotros seremos "los clientes" y la máquina remota "el servidor"}

Acá les resumo la forma de conectarse a través del protocolo RDP (remote desktop protocol) a una máquina donde quiera que se encuentre en el planeta :-)
Lo primero es instalar en la PC remota, a la cual ustedes quieren ingresar, una aplicación que les irá actualizando la dirección IP asociada a un nombre de dominio, al final les explico de qué estamos hablando.
Para eso debemos ingresar en www.no-ip.com y registrarnos como usuario nuevo, en "Sign-up now!". Cuando ya hemos validado nuestra credencial de nuevo usuario podemos entonces crear el/los dominio/s para asociar.
Ingresamos a www.no-ip.com con nuestra credencial recién creada y vamos al apartado "Hosts / Redirects / Add", ahí debemos completar en el casillero "Hostname" el nombre que antecederá al dominio, por ejemplo: mipcremota, donde luego elegiremos el dominio: .no-ip.biz, .no-ip.org, .no-ip.info, etc. Por lo demás no hay que tocar ninguna otra opción.
Muy bien, ahora que hemos creado el dominio tenemos que descargar, según el SO que usemos, la aplicación que actualizará la IP y la asociará al dominio creado. Vamos a la pestaña "Downloads" www.no-ip.com/downloads.php?sid=5fc067745b7c1a5d1bbf52e9b81eb5a0 y bajamos entonces la aplicación para luego instalarla en la PC remota. Al iniciar la aplicación recién instalada se les pedirá que se autentiquen con la credencial de No-IP, luego se les mostrará un cuadro donde se listan todos los nombres de dominio que crearon, junto a un casillero a tildar a la izquierda de c/u. Ustedes deberán marcar el que corresponde al dominio que asociarán a dicha PC. Ésta aplicación, luego de instalada, nos ofrece ciertas opciones que podrán elegir, cada una les muestra una breve explicación al poner el puntero del mouse encima, les recomiendo activar el programa con la tercera opción, la que lo inicia como servicio del sistema y no les deja ícono en la bandeja, para evitar que los usuarios que se encuentran localmente en el equipo se den cuenta ;-)
El protocolo de Escritorio Remoto trabaja con el puerto "3389", ésto es importante saberlo porque posiblemente el firewall de nuestro SO o del antivirus lo bloquée, entonces hay que configurar la regla para abrirlo y permitir que por dicho puerto se acepten peticiones redirigidas hacia él. La creación de una nueva regla merece otro capítulo, en un futuro próximo les explicaré cómo crear reglas.
Además, al conocer la identificación del puerto, podemos habilitar la redirección de los paquetes entrantes a nuestro router hacia el puerto 3389 apuntándolo a la IP de la PC remota (ésto es obligatorio en todos los casos en que la PC remota se encuentre dentro de una LAN -Local Area Network ó Red de Área Local-). Merece otro capítulo ésta tarea, pero si no se encuentra en un grupo de trabajo (o LAN), ésta última configuración no es necesaria.
Suponiendo que ya se hizo todo como se indicó procederemos a abrir una consola para enviar un ping al dominio creado, por ejemplo: C:\ping mipcremota.no-ip.org
Si la configuración que hicimos está bien recibiremos respuesta indicándonos la IP actual del equipo (si el mismo está dentro de una LAN dicha IP será la de la red, pero eso no nos importa porque, al haber configurado el router apuntando el puerto 3389 hacia la IP del equipo remoto, nada nos afectará que el mismo tenga una IP privada y distinta de la IP de red). No intenten conectarse remotamente a un equipo si se encuentran en otro que está en la misma LAN utilizando el nombre de dominio creado porque no lograrán hacer conexión, para ello usen la IP privada o nombre de la PC.
Ahora sí, vayan a un cyber y ejecuten "Conexión a Escritorio Remoto", escriban el dominio creado, Enter y .......Vualá....!!!!! Ya podrán tener la pantalla de "login" del equipo remoto; les sugiero crear un usuario con permisos limitados y otro con privilegios de administrador, ambos con contraseña, para que protejan el acceso.
En lo que respecta a la instalación de la aplicación de No-IP, ésta es para que automáticamente actualice y asocie una nueva IP que nos otorgue nuestro proveedor de servicio de Internet (ISP), ya que lo más probable es que tengamos contratado un servicio con IP dinámica que irá cambiando día a día. En caso de tener contratada una IP fija, que es otro precio..., la instalación de ésta aplicación no es necesaria. Por una cuestión de memoria es más fácil recordar un nombre que una serie de números, es por eso que al crear un dominio no tendremos que preocuparnos por averiguar de una u otra forma la IP que le toca al equipo o red en el momento que queremos conectarnos, para eso está la aplicación de No-IP.

Bueno, eso es todo por el momento. Gracias a los amigos que leyeron éste artículo y lo consideraron útil.
Saludos.
Carlos (B. A.)

script para agregar un pc a un dominio

Lo hice en vbscript porque los clientes no tienen powershell.

'**************************************************
' Agregar PC al Dominio.
' Autor: Jorge Mestre
' Fecha: 26/06/08
' Descripción: Agrega un PC al dominio.
'
'**************************************************

'objeto para obtener el nombre de usuario actual
set net = WScript.CreateObject("WSCript.Network")
'objeto para los inputbox
Set WSHShell = WScript.CreateObject("WScript.Shell")

'Definiciones por defecto
pcDef = "testprep"
domDef = "lab.dominio.local"
OUDef = "OU=PCs"
userDef = Net.UserName
userLocalDef = "Administrator"

'inputbox PC
pc = InputBox("introduzca el HOSTNAME del PC", _
"Introducir hostname del PC",pcDef)

'saliendo por no poner ningún hostname
If pc = "..." or pc = "" Then
WScript.Echo "no se indicó ningún hostname, saliendo..."
WScript.Quit()
End If

'check pc
wscript.echo "PC: " & pc

'revisando que se llega al PC
If Ping(pc) = False then
wscript.Echo pc & " no responde a PING..."
Wscript.Quit()
end If

'inputbox Dominio
dominio = InputBox("introduzca el DOMINIO (formato DNS) " & _
"al que debe pertenecer " & pc, _
"Introducir dominio para " & pc,domDef)

'saliendo por no poner dominio
If dominio = "..." or dominio = "" Then
WScript.Echo "no se indicó ningún dominio, saliendo..."
WScript.Quit()
End If

'comprobar que se introdujeron "." con el nombre de dominio
If Instr(dominio, ".") = 0 Then
wscript.echo "el dominio debe estar indicado como " & _
"subdominio.dominio - Ejemplo: es.prueba.com"
wscript.Quit()
End If

'check dominio
wscript.echo "Dominio: " & dominio


' Introducir OU
ou = InputBox("introduzca la OU: Ej: OU=Workstations," & _
"OU=Standard","Introducir OU",OUDef)

'pedir usuario dominio / por defecto, poner el nombre
'de usuario actual en el inputbox
user = InputBox("introduzca un usuario con permisos para " & _
"agregar " & pc & " al dominio " & dominio, _
"Introducir usuario de DOMINIO",userDef)

'pedir password
msg=MsgBox("introducir el password en la consola luego de " &_
"este mensaje",0,"password en consola")
Set objPassword = CreateObject("ScriptPW.Password")
WScript.StdOut.Write "Contraseña para " & user & " (DOMINIO):"
pass = objPassword.GetPassword()

'pedir admin local pc
userLocal = InputBox("introduzca un usuario con permisos " & _
"LOCALES en " & pc & " (por ejemplo el " & _
"administrador local ","Introducir usuario LOCAL" _
,userLocalDef)

'pedir password usuario local
msg=MsgBox("introducir el password para el usuario LOCAL " & _
"de " & pc & " en la consola luego de este " & _
"mensaje",0,"password en consola de usuario LOCAL")

Set objPassword = CreateObject("ScriptPW.Password")
WScript.StdOut.Write VbCrLf & "Contraseña para " & _
userLocal & " (LOCAL):"
passLocal = objPassword.GetPassword()

' confirmar datos
confirmar=MsgBox("¿Son los siguientes datos correctos?" & _
VbCrLf & VbCrLf & "PC: " & pc & VbCrLf & _
"Dominio: " & dominio & " (" & ou & ")" & VbCrLf & _
"Usuario Dominio: " & user & VbCrLf & _
"Usuario Local: " & userLocal & VbCrLf _
,1,"Confirmar datos")

if confirmar = 2 then
msg=MsgBox("proceso cancelado",0,"Cancelado")
wscript.quit()
end if

reiniciar = MsgBox("¿Desea reiniciar " & pc & _
" luego de agregarlo a dominio?" & VbCrLf & _
VbCrLf & "(Es Necesario, " & _
"pero quizas es conveniente mas tarde)",4, _
"¿Reiniciar?")

Set objShell = CreateObject("WScript.Shell")
if reiniciar = 1 then
strCmdNetDom = "%comspec% /c netdom join " & pc & _
" /Domain:" & dominio & _
" /userD:" & user & _
" /passwordD:" & pass & _
" /OU:" & ou & _
" /userO:" & userLocal & _
" /PasswordO:" & passLocal & _
" /reboot"
else
strCmdNetDom = "%comspec% /c netdom join " & pc & _
" /Domain:" & dominio & _
" /userD:" & user & _
" /passwordD:" & pass & _
" /OU:" & ou & _
" /userO:" & userLocal & _
" /PasswordO:" & passLocal
End if

Set objExecObj = objShell.Exec(strCmdNetDom)
strResNetDom = objExecObj.StdOut.ReadAll()

resultado = MsgBox ("Resultado" & vbcrlf & strResNetDom)

' Función para hacer Ping
Function Ping(pc)
Set objShell = CreateObject("WScript.Shell")
strCmdPing = "%comspec% /c ping -n 1 " & pc & ""
Set objExecObj = objShell.Exec(strCmdPing)
strResPing = objExecObj.StdOut.ReadAll()

If Instr(strResPing, "Respuesta") > 0 Then
Ping = True
Else
Ping = False
End If
End Function

Pasar un formato personalizado de fecha a powershell

$fechaPer = "20081005"
$fechaFormateado = [datetime]::ParseExact($fechaRaw,'yyyyMMdd',$null)
$fecha = get-date $fechaFormateado -format dd/MM/yyyy

fecha contiene un valor tipo "Date" válido, obtenido del string $fechaPer y formateado con el método ParseExact.

VirtualWin - Desktops virtuales en Windows

aqui pueden descargarlo. Está muy bueno, con la tecla Win+flechitas cambian de escritorio.

función para escribir logs

Lo acabo de hacer, y me pareció útil guardarlo por aqui:

# archivo con fecha ej: log_20030318.log
$ArchLog = "log_"+"$(get-date -format yyyyMMdd)"+".log"

function escLog($texto){
write-output "$(get-date -format hh:mm:ss): $texto" |
out-file -encoding ascii -append $ArchLog
}

#pruebas
escLog "Incio LOG"
sleep 2
escLog "Otra Linea"
sleep 5
escLog "2+2 son $(2+2)"

la salida es:
11:34:14: Incio LOG
11:34:16: Otra Linea
11:34:21: 2+2 son 4

mostrar traps snmp

param($lista)
$arch = ".\salida.csv"
"hostname`tcomunidad`ttrap`tvalor" > $arch

function check-ping ([string]$pc) {
$HostVivo = Get-WmiObject -Class Win32_PingStatus -Filter "Address='$pc'"
if (($HostVivo.StatusCode -ne "0") -or ($pc -eq $null)){
return $false
}
else{
return $true
}
}

function nulo ($txthost,$txtout){
write-host "$txthost" -fore cyan
write-output "txtout" out-file -append $arch
}

$listaS = gc $lista

foreach ($s in $listaS){
if (-not $(check-ping $s)){nulo "$s`tno responde (por wmi)" "$s`tno responde (por wmi)";continue}
$baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $s)
$key = $baseKey.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\SNMP\\Parameters\\TrapConfiguration", $false)
if ($key -eq $null){nulo "$s`t$dirBase no existe" "$s`t$dirBase no existe";continue}
$comunidades = $key.GetSubKeyNames()
if ($comunidades -eq $null){nulo "$s`tNo hay comunidades definidas" "$s`tno hay comunidades definidas";continue}
foreach ($comunidad in $comunidades){
$com = $Key.OpenSubKey("$comunidad", $false)
$traps = $com.getValueNames()
if ($traps -eq $null){nulo "$s`tNo hay traps configurados definidos en la comunidad $com" "$s`tNo hay traps definidos en la comunidad $com";continue}
foreach ($trap in $traps){
$val = $com.GetValue($trap)
}
write-output "$s`t$comunidad`t$trap`t$val" out-file -append $arch

write-host "`t$s" -fore cyan
write-host "`t`tcomunidad: $comunidad" -fore green
write-host "`t`t trap: $trap" -fore green
write-host "`t`t valor: $val`n" -fore green
}
}
$com.Close()
$key.Close()
$baseKey.Close()

crear snapshots de VMs en VMware server

# crea snapshots de VMs en vmware-server.
# Jorge Mestre

clear
write-host "- Este script asume que está instalado VMware Server 1.0.4" -fore yellow
write-host "y que está instalado en `"c:\Program Files\VMware\`"" -fore yellow
write-host "" -fore yellow
write-host "- También asume que este script se está instalando desde el host" -fore yellow
write-host "donde se encuentra instalado VMware server." -fore yellow
write-host "" -fore yellow
write-host "ATENCION!!!" -fore yellow
write-host "-----------" -fore yellow
write-host "" -fore yellow
write-host "este script detendra el Guest que se especifique," -fore yellow
write-host "y creará una copia en la subcarpeta donde reside," -fore yellow
write-host "con el formato AAAAMMDD_HHMMSS" -fore yellow
write-host ""
write-host "¿Desea continuar (S/N)? " -fore cyan -nonewline
$cont = read-host
if ($cont -ne "s"){exit}

$vmrun_List = & 'C:\Program Files\VMware\VMware VIX\vmrun.exe' list

if ($vmrun_List -eq 'Total running VMs: 0'){
"Ningun guest en ejecución...";exit
}

write-host "`nGuests en ejecución: " -fore darkgreen
write-host "------ -- ----------`n" -fore blue
for ($i=0;$i -lt $vmrun_List.length;$i++){
if ($i -eq 0){continue}
write-host "`t$i - $($vmrun_List[$i])`n" -fore cyan
}

write-host "`nElija el número de guest para crear el snapshot: " -fore green -nonewline
$opc = read-host
if ($opc -ge $vmrun_List.length){
"Opción erronea";exit
}

$vm = $vmrun_list[$opc]

write-host "¿apagar $vm y crear snapshot? (S/N):" -fore cyan -nonewline

$cont = read-host
if ($cont -ne "s"){exit}

write-host "apagando guest...." -fore darkGreen
$vmrun_stop = & 'C:\Program Files\VMware\VMware VIX\vmrun.exe' stop $vm
write-host "guest apagado." -fore darkGreen

$padre = (ls $vm).Directory.FullName
$padre = "$padre"

$nomDir = "{0:yyyyMMdd_HHmmss}" -f (get-date)
$nDir = "$padre"+"\"+"$nomdir"

mkdir $nDir

cp "$padre\*.vmdk" $nDir -passthru
cp "$padre\*.vmem" $nDir -passthru
cp "$padre\*.vmx" $nDir -passthru
cp "$padre\*.nvram" $nDir -passthru

write-host "`n`tsnapshot creado en $nDir`n" -fore green