Mostrando entradas con la etiqueta script. Mostrar todas las entradas
Mostrando entradas con la etiqueta script. Mostrar todas las entradas

miércoles, 17 de septiembre de 2025

Windows. PS. Como instalar masivamente-remotamente un programa en red.

Como instalar un programa remoto en PS.


Desde la descarga hasta su instalación y verificación.

En este caso vamos a poner un ejemplo de como instalar el cliente de Wazuh en una red de servidores con comandos de PS.

La idea es desde un servidor central (Servidor1) lanzar la instalación del programa en varios servidores remotos.

Solo necesitaremos lanzar el script desde un servidor abriendo una consola de Powershell

Necesitaremos antes algunos preparativos previos:

Preparativo 1: Preparamos el script que se ejecutará en los servidores locales

Preparativo 2: Preparamos el script que se lanzará la instalación a los servidores remotos

Preparativo 3: Prepararemos el listado de host a los que instalaremos el programa.

Paso 1: Ejecutamos el proceso


Preparativo 1: Preparamos el script que se ejecutará en los servidores locales


Se debe copiar en una ruta donde todos los hosts tengan acceso, en este ejemplo la dejaremos en:

\\Domain.local\SYSVOL\Domain.LOCAL\MovApp\SIEM\Wazuh_agent_4.12.ps1

FICHERO: SIEM\Wazuh_agent_4.12.ps1

# PowerShell Script

 

# --- Guard clause: salir si Wazuh ya está instalado ---

$svc = Get-Service -Name 'WazuhSvc' -ErrorAction SilentlyContinue

$agentDir = "${env:ProgramFiles(x86)}\ossec-agent"

 

if ($svc -or (Test-Path "$agentDir\client.keys")) {

    Write-Output "Wazuh Agent ya instalado. Saliendo."

    exit 0

}

# --- fin guard clause ---

 

# PowerShell Script

 

# Define el nombre del host

$hostname = [System.Net.Dns]::GetHostName()

 

# Descarga el instalador del agente Wazuh de la web del fabricante

Invoke-WebRequest -Uri https://packages.wazuh.com/4.x/windows/wazuh-agent-4.12.0-1.msi -OutFile $env:tmp\wazuh-agent;

 

# Instala el agente Wazuh con el nombre del host como el nombre del agente

msiexec.exe /i $env:tmp\wazuh-agent /q WAZUH_MANAGER='192.168.x.x' WAZUH_AGENT_GROUP='default' WAZUH_AGENT_NAME=$hostname

 

#Pausa de 10 segundos antes de iniciar el servicio

Start-Sleep -Seconds 10

 

Write-Host " Inicializamos el servicio1. Puede dar error "

NET START WazuhSvc

Write-Host " Inicializamos el servicio2 "

Start-Sleep -Seconds 10

Start-Service -Name "WazuhSvc"

Set-Service -Name "WazuhSvc" -StartupType Automatic

#Fin de Servicio instalado

 

#ejecución remota de executable

 

Start-Sleep -Seconds 5

Write-Host "Intento de conexión con el servidor Wazuh..."

 

$exePath = "C:\Program Files (x86)\ossec-agent\agent-auth.exe"

 

# Desbloquear el ejecutable si fue descargado

Unblock-File -Path $exePath

 

# Ejecutar el agente con argumentos

Start-Process -FilePath $exePath -ArgumentList "-m 10.115.79.215" -Wait -NoNewWindow

 

Write-Host "Verifica el servio instalado"

$svc = Get-Service -Name 'WazuhSvc' -ErrorAction SilentlyContinue

$agentDir = "${env:ProgramFiles(x86)}\ossec-agent"

 

if ($svc -or (Test-Path "$agentDir\client.keys")) {

    Write-Output "Verifica Wazuh Agent -> instalado OK. Saliendo."

  

}

# --- fin guard clause ---

 

 

Preparativo 2: Preparamos el script que se lanzará la instalación a los servidores remotos


Este es el único script que ejecutaremos.

FICHERO: InstallRemoto.ps1 

# Ruta al archivo de servidores

$servidores = Get-Content "servidores.txt"

 

# Ruta del script a copier, en una ruta donde accedan todos los hosts

$scriptPath = \\YYYYY.local\SYSVOL\XXXX.LOCAL\MovApp\SIEM\Wazuh_agent_4.12.ps1

 

foreach ($serverName in $servidores) {

    Write-Host " Iniciando despliegue en ${serverName}..." -ForegroundColor Cyan

 

    try {

        # Crear sesión remota con credenciales actuales

        $session = New-PSSession -ComputerName $serverName

 

        # Crear carpeta en remoto

        Invoke-Command -Session $session -ScriptBlock {

            $folder = "C:\tmp"

            if (-Not (Test-Path $folder)) {

                New-Item -Path $folder -ItemType Directory

            }

        }

 

        # Copiar el script al servidor remoto usando ruta UNC

        $remoteScriptPath = "\\${serverName}\C$\tmp\Wazuh_agent_4.12.ps1"

        Copy-Item -Path $scriptPath -Destination $remoteScriptPath

 

        # Ejecutar el script en remoto

        Invoke-Command -Session $session -ScriptBlock {

            & "C:\tmp\Wazuh_agent_4.12.ps1"

        }

 

        Write-Host " Despliegue completado en ${serverName}" -ForegroundColor Green

    }

    catch {

        Write-Host " Error en el despliegue en ${serverName}: $_" -ForegroundColor Red

    }

    finally {

        # Cerrar sesión remota

        if ($session) {

            Remove-PSSession $session

        }

    }

}

 

Write-Host "Despliegue finalizado en todos los servidores." -ForegroundColor Yellow

 

 

 

Preparativo 3: Prepararemos el listado de host a los que instalaremos el programa.

Es muy importante que los nombres no tengan espacios en blanco

 Antes de la ejecución debemos crear el listado de servidores. Para ello usaremos el fichero servidores.txt, en este ejemplo pondremos dos host a ser receptores de la nueva instalación

 



Paso 1: Ejecutamos el proceso

 Conectarse a un DC y/o abrir una consola de PowerShell como administrador del dominio para que no tenga problemas a la hora de la ejecución local en los hosts de este dominio.


Yo por ejemplo estoy monitorizando con Nagios si se va levantado el servicio en mis servidores

by GoN | Published: Sep 2025 | Last Updated:

sábado, 10 de abril de 2021

WINDOWS. PS. Update and modify extensionAttribute

Purpose

Modifie the Windows user extensionAttribute.

We wan copy the user "company" field in to "extensionAttribute2"

Script

 #Filter all users

$ALLUserTest = get-aduser -filter * -properties *

#Filter some user

#$x = 'Smith'

#$ALLUserTest =Get-ADUser -Filter "SamAccountName -like '*$x*'" -Properties *

 

ForEach($TestUser In $ALLUserTest)

{

   write-host "User: " $TestUser.samaccountname, $TestUser.company

  # Check before

  Get-ADUser  -identity $TestUser.samaccountname -Properties * | Select sAMAccountName, Company, extensionAttribute2 | sort-object -property extensionAttribute2

 #Update fields

                Set-ADUser –Identity $TestUser.samaccountname -Clear "extensionAttribute2"

                Set-ADUser -Identity $TestUser.samaccountname -Add @{extensionAttribute2 = $TestUser.company}

 # Check after

                Get-ADUser  -identity $TestUser.samaccountname -Properties * | Select sAMAccountName, Company, extensionAttribute2 | sort-object -property extensionAttribute2

 

}

 

by GoN | Published: Apr 10, 2021 | Last Updated:

martes, 21 de junio de 2011

Usuarios Acceso Remoto

Me ha salido una solicitud de buscar que usuarios del AD que están  autorizados a conectarse remotamente. Después de unas cuantas consultas he encontra un script que nos puede ser muy útil en esta búsqueda y con unas pequeñas modificaciones alguna que otra más.

Tenemos que crear un fichero con el siguiente código:


On Error Resume Next
Const ADS_SCOPE_SUBTREE = 2
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE


objCommand.CommandText = _
"SELECT Name FROM 'LDAP://dc=MiDominio,dc=com' WHERE objectCategory='user' " & _
        "AND msNPAllowDialin = TRUE"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    Wscript.Echo objRecordSet.Fields("Name").Value
    objRecordSet.MoveNext
Loop


El fichero lo debermos guardar con la extension vbs, por ejemplo "accesos.vbs"
Para ejecutar la consulta  hay que ir al interprete de comando y escribir
"cscript. accesos.vbs > users.txt"

Antes de ejecutarlo deberíamos modificar "SELECT Name FROM 'LDAP://dc=MiDominio,dc=com'   deberíamos y sustituir "MiDominio" y el "com" por el equivalente de nuestro AD.


Esta búsqueda se centrará en los usuarios que tengan activa la variable "Permitir acceso" de la siguiente pantalla:



Para ver los resultadados hay que ir al fichero generado "users.txt"

Obtendremos un resultado del estilo:


lunes, 22 de noviembre de 2010

Ultimo logon en el AD

Muchas veces se empiza a llenar nuestro AD de usuarios que ya no trabajan en nuestra empresa ya sea por descuido o porque no nos han avisado van quedando para la posteridad.

Yo gracias al script de Richard L. Mueller de vez en cuando filtro la última vez que un usuario se logeo en nuestro sistema.

Para ejecutarlo copiar el siguiente código en un fichero de texto y ponerle la extensión .vbs luego escribir xxxx.vbs Fichero_de_salida


' VBScript program to determine when each user in the domain last logged
' on.
'
' ----------------------------------------------------------------------
' Copyright (c) 2002 Richard L. Mueller
' Hilltop Lab web site -
http://www.rlmueller.net
' Version 1.0 - December 7, 2002
' Version 1.1 - January 17, 2003 - Account for null value for lastLogon.
' Version 1.2 - January 23, 2003 - Account for DC not available.
' Version 1.3 - February 3, 2003 - Retrieve users but not contacts.
' Version 1.4 - February 19, 2003 - Standardize Hungarian notation.
' Version 1.5 - March 11, 2003 - Remove SearchScope property.
' Version 1.6 - May 9, 2003 - Account for error in IADsLargeInteger
'                             property methods HighPart and LowPart.
' Version 1.7 - January 25, 2004 - Modify error trapping.
' Version 1.8 - July 6, 2007 - Modify how IADsLargeInteger interface
'                              is invoked.
'
' Because the lastLogon attribute is not replicated, every Domain
' Controller in the domain must be queried to find the latest lastLogon
' date for each user. The lastest date found is kept in a dictionary
' object. The program first uses ADO to search the domain for all Domain
' Controllers. The AdsPath of each Domain Controller is saved in an
' array. Then, for each Domain Controller, ADO is used to search the
' copy of Active Directory on that Domain Controller for all user
' objects and return the lastLogon attribute. The lastLogon attribute is
' a 64-bit number representing the number of 100 nanosecond intervals
' since 12:00 am January 1, 1601. This value is converted to a date. The
' last logon date is in UTC (Coordinated Univeral Time). It must be
' adjusted by the Time Zone bias in the machine registry to convert to
' local time.
'
' You have a royalty-free right to use, modify, reproduce, and
' distribute this script file in any way you find useful, provided that
' you agree that the copyright owner above has no warranty, obligations,
' or liability for such use.

Option Explicit
Dim objRootDSE, strConfig, adoConnection, adoCommand, strQuery
Dim adoRecordset, objDC
Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
Dim strDN, dtmDate, objDate, objList, strUser
Dim strBase, strFilter, strAttributes, lngHigh, lngLow

' Use a dictionary object to track latest lastLogon for each user.
Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare

' 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

' Determine configuration context and DNS domain from RootDSE object.
Set objRootDSE = GetObject("
LDAP://RootDSE")
strConfig = objRootDSE.Get("configurationNamingContext")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use ADO to search Active Directory for ObjectClass nTDSDSA.
' This will identify all Domain Controllers.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection

strBase = "<LDAP://" & strConfig & ">"
strFilter = "(objectClass=nTDSDSA)"
strAttributes = "AdsPath"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 60
adoCommand.Properties("Cache Results") = False

Set adoRecordset = adoCommand.Execute
' Enumerate parent objects of class nTDSDSA. Save Domain Controller
' AdsPaths in dynamic array arrstrDCs.
k = 0
Do Until adoRecordset.EOF
    Set objDC = _
        GetObject(GetObject(adoRecordset.Fields("AdsPath").Value).Parent)
    ReDim Preserve arrstrDCs(k)
    arrstrDCs(k) = objDC.DNSHostName
    k = k + 1
    adoRecordset.MoveNext
Loop
adoRecordset.Close

' Retrieve lastLogon attribute for each user on each Domain Controller.
For k = 0 To Ubound(arrstrDCs)
    strBase = "<LDAP://" & arrstrDCs(k) & "/" & strDNSDomain & ">"
    strFilter = "(&(objectCategory=person)(objectClass=user))"
    strAttributes = "distinguishedName,lastLogon"
    strQuery = strBase & ";" & strFilter & ";" & strAttributes _
        & ";subtree"
    adoCommand.CommandText = strQuery
    On Error Resume Next
    Set adoRecordset = adoCommand.Execute
    If (Err.Number <> 0) Then
        On Error GoTo 0
        Wscript.Echo "Domain Controller not available: " & arrstrDCs(k)
    Else
        On Error GoTo 0
        Do Until adoRecordset.EOF
            strDN = adoRecordset.Fields("distinguishedName").Value
            On Error Resume Next
            Set objDate = adoRecordset.Fields("lastLogon").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
            If (objList.Exists(strDN) = True) Then
                If (dtmDate > objList(strDN)) Then
                    objList.Item(strDN) = dtmDate
                End If
            Else
                objList.Add strDN, dtmDate
            End If
            adoRecordset.MoveNext
        Loop
        adoRecordset.Close
    End If
Next

' Output latest lastLogon date for each user.
For Each strUser In objList.Keys
    Wscript.Echo strUser & " ; " & objList.Item(strUser)
Next

' Clean up.
adoConnection.Close
Set objRootDSE = Nothing
Set adoConnection = Nothing
Set adoCommand = Nothing
Set adoRecordset = Nothing
Set objDC = Nothing
Set objDate = Nothing
Set objList = Nothing
Set objShell = Nothing



Verificado en Windows 2003. Noviembre 2010

Espero os sea igual de útil que a mi lo está siendo.