Una pequeña referencia a algunos de los parámetros básicos, y muy útiles, a utilizar al crear un buen archivo .bat
%n donde n es un número, hacemos referencia a un parámetro pasado al ejecutar el archivo .bat
Por ejemplo %1 sería el primer parámetro, %2 el segundo, etcétera
%0 Hacemos referencia al nombre del archivo batch que estamos ejecutando, pero tenemos mas opciones, si hacemos un archivo .bat que tenga este contenido quedará suficientemente claro:
echo %0
echo Nombre : %~n0
echo Extension : %~x0
echo Unidad : %~d0
echo Ruta : %~p0
echo Ruta completa : %~s0
echo Fecha-Hora del archivo : %~t0
echo Atributos : %~a0
echo Nombre y extension : %~nx0
" Los parámetros con espacios deben de entrecomillarse.
% sirve para tomar el valor de una variable, %nombrevariable%
%%L donde L es una letra, sirve para hacer referencia al valor de la variable definida para construir un bucle for, por ejemplo %%a, y si tratamos de tomar el valor de diferentes tokens sería: el primer token, %%a, el segundo %%b, etcétera.
! como el %, nos dará el valor de una variable pero expandida tras activar setlocal enabledelayedexpansion. Muy útil dentro de bucles for por ejemplo.
& Separa comandos en una misma linea. Muy útil para concatenar varios comandos cortos y que el script no quede infinitamente largo. Por ejemplo echo hola & echo adios. Pruebalo.
&& Ejecuta el siguiente comando solo si el anterior comando ha dado un errorlevel 0.
|| Ejecuta el siguiente comando solo si el anterior comando NO ha dado un errorlevel 0.
> Salida a un archivo. El ejemplo clásico es hacer un echo Texto de ejemplo > archivo.txt
>> Salida a un archivo pero agregando al contenido ya existente.
| La salida del comando anterior se introduce como entrada del siguiente comando. Un ejemplo sencillo es directamente en el cmd:
Creo que para empezar son suficientes.
SaluDOS.
David Bohm
Hay dos frases que definen mi manera de pensar:
Realmente no hemos prestado mucha atención al pensamiento como un proceso; hemos participado en pensamientos, pero sólo hemos prestado atención al contenido, no al proceso.
La capacidad de percibir o pensar de manera diferente es más importante que el conocimiento adquirido.
Ambas son de David Bohm.
PÁGINAS
Mostrando entradas con la etiqueta Script. Mostrar todas las entradas
Mostrando entradas con la etiqueta Script. Mostrar todas las entradas
domingo, 16 de octubre de 2016
lunes, 10 de octubre de 2016
Reinicia todos los servidores en la distancia desde batch de Windows o PowerShell. Elige!
Muchas veces veo como administradores de sistemas para reiniciar servidores, van a formas muy rudimentarias como, por ejemplo, coger control remoto de los 5 o 6 servidores para reiniciarlos, uno a uno. ¿Que pasa cuando son 20 o 30 servidores los que hay que reiniciar? ¿o muchos mas?
Esto hoy por hoy no tiene sentido ya que abriendo una consola cmd en windows, por poner un ejemplo, podemos utilizar el comando shutdown que admite establecer el servidor de destino y algún que otro parámetro más:
C:\> shutdown /r /m \\servidor01 /t 10 /c "Reiniciado por usuario Admin01"
Esto en un script batch de Windows, por ejemplo, podemos automatizar para que vaya reiniciando una lista de servidores. Podríamos hacer algo así:
set LISTADO_SERVERS=servidor01 servidor02 servidor03
for %%a in (%LISTADO_SERVERS%) do (
shutdown /r /m \\%%a /t 10 "Reiniciado por usuario Admin01"
)
Incluso previamente podríamos primero controlar la conectividad antes de lanzar el comando. Puedes ver un ejemplo de esto en esta entrada: Control de conectividad en batch de Windows o en PowerShell
Vale, vamos a ver como sería hacer lo mismo desde PowerShell. El cmdlet es Restart-Computer y el ejemplo extraído de la misma ayuda de powershell. Para realizar lo mismo que antes y reiniciar una lista de servidores e incluso el equipo cliente desde donde lo estamos lanzando:
C:\PS>restart-computer -computername servidor01 servidor02 localhost
Fácil, rápido y sencillo.
SaluDOS.
Esto hoy por hoy no tiene sentido ya que abriendo una consola cmd en windows, por poner un ejemplo, podemos utilizar el comando shutdown que admite establecer el servidor de destino y algún que otro parámetro más:
C:\> shutdown /r /m \\servidor01 /t 10 /c "Reiniciado por usuario Admin01"
Esto en un script batch de Windows, por ejemplo, podemos automatizar para que vaya reiniciando una lista de servidores. Podríamos hacer algo así:
set LISTADO_SERVERS=servidor01 servidor02 servidor03
for %%a in (%LISTADO_SERVERS%) do (
shutdown /r /m \\%%a /t 10 "Reiniciado por usuario Admin01"
)
Incluso previamente podríamos primero controlar la conectividad antes de lanzar el comando. Puedes ver un ejemplo de esto en esta entrada: Control de conectividad en batch de Windows o en PowerShell
Vale, vamos a ver como sería hacer lo mismo desde PowerShell. El cmdlet es Restart-Computer y el ejemplo extraído de la misma ayuda de powershell. Para realizar lo mismo que antes y reiniciar una lista de servidores e incluso el equipo cliente desde donde lo estamos lanzando:
C:\PS>restart-computer -computername servidor01 servidor02 localhost
Fácil, rápido y sencillo.
SaluDOS.
Control de conectividad en batch de Windows o en PowerShell, tu decides, fácil o más fácil...
Muchas veces tenemos que controlar si un script se lanza o no dependiendo de si hay conectividad con la unidad de red, el servidor o simplemente a internet.
REM deshabilitamos el echo y retardamos la carga de las variables, para los bucles for
@echo off
setlocal enabledelayedexpansion
:: Establecer variables
REM En este caso vamos a separar los almacenamientos de los servidores
set ADMIN_UDs_Red=almacenamiento01 almacenamiento02 almacenamiento03
set ADMIN_Servers=servidor01 servidor02 servidor03
REM Vamos a volcar el resultado a un log, controlamos la ruta para crearla si es necesario y el nombre del log depende de la fecha, para poder lanzarlo a diario cuando llegamos al trabajo. Vamos a borrar su contenido con el echo. >
set ruta=C:\Connectivity_Logs
if not exist %ruta% mkdir %ruta%
set rutalog=%ruta%\%date:~6,4%%date:~3,2%%date:~0,2%_Connectivity_Test.log
echo. >%rutalog%
REM Nos vamos a apoyar en un par de archivos txt y una variable que me permita controlar que si hay una ip que no tiene conectividad mande un mail
set pinged=%ruta%\ping.txt
set pinged2=%ruta%\ping2.txt
set ENVIOMAIL=NO
:: Lanzar comprobaciones
REM Volcamos una cabecera en el .log
echo. >>%rutalog%
echo ************************* >>%rutalog%
echo *** CONNECTIVITY TEST *** >>%rutalog%
echo ************************* >>%rutalog%
echo. >>%rutalog%
REM Recorremos las unidades de red de la variable ADMIN_UDs
for %%a in (%ADMIN_UDs_Red%) do (
echo Checking %%a
REM Hacemos un ping y volcamos el resultado al primer .txt
PING -w 3000 %%a > %pinged%
REM Buscamos si en el primer .txt hay indicios de conectividad y volcamos al segundo .txt
@find /C "TTL=" %pinged% > %pinged2%
REM Ahora la variable estado es la que marcará la conectividad, viendo el número que se ha volcado al segundo .txt si no es 0 es que ha encontrado alguna coincidencia, en este caso por como hemos hecho el ping será 1
set estado=[nOK]
for /F "tokens=1,2,3" %%h in (%pinged2%) do (
set control=%%j
if "%%h" EQU "----------" (
if "!control!" NEQ "0" set estado=OK
)
)
REM Volcamos el resultado al .log
echo Checked ... %%a: !estado! >>%rutalog%
REM En caso de no haber conectividad en cualquiera de las ips activa el envio de un mail
if !ENVIOMAIL! EQU NO (
if !estado! EQU [nOK] set ENVIOMAIL=SI
)
)
REM Realizamos exactamente lo mismo con la lista de servidores
for %%a in (%ADMIN_Servers%) do (
echo Checking %%a
PING -w 3000 %%a > %pinged%
@find /C "TTL=" %pinged% > %pinged2%
set estado=[nOK]
for /F "tokens=1,2,3" %%h in (%pinged2%) do (
set control=%%j
if "%%h" EQU "----------" (
if "!control!" NEQ "0" set estado=OK
)
)
echo Checked ... %%a: !estado! >>%rutalog%
if !ENVIOMAIL! EQU NO (
if !estado! EQU [nOK] set ENVIOMAIL=SI
)
)
REM Volcamos un pie de log para constatar que hemos terminado con el
echo. >>%rutalog%
echo ************************* >>%rutalog%
echo *** END *** >>%rutalog%
echo ************************* >>%rutalog%
REM Borramos los ficheros .txt en los que nos hemos apoyado.
del %pinged%
del %pinged2%
REM Aqui controlariamos el envio del mail, en este caso solo hago un echo.
ECHO %ENVIOMAIL%
PAUSE
Si quieres saber como enviar el mail, mira esta entrada: Enviar un mail con PowerShell
Un apaño muy típico mio, y realmente rápido y facil de hacer, pasa por controlarlo desde el batch de windows para posteriormente ejecutar el comando que sea, aunque esto se puede hacer desde powershell de forma muy sencilla. Veamoslo primero desde un .bat y vamos a hacerlo a lo artesanal, así repasamos algunos conceptos básicos como volcar y buscar en un archivo .txt o los bucles for, así le añadimos un poco de lío.
REM deshabilitamos el echo y retardamos la carga de las variables, para los bucles for
@echo off
setlocal enabledelayedexpansion
:: Establecer variables
REM En este caso vamos a separar los almacenamientos de los servidores
set ADMIN_UDs_Red=almacenamiento01 almacenamiento02 almacenamiento03
set ADMIN_Servers=servidor01 servidor02 servidor03
REM Vamos a volcar el resultado a un log, controlamos la ruta para crearla si es necesario y el nombre del log depende de la fecha, para poder lanzarlo a diario cuando llegamos al trabajo. Vamos a borrar su contenido con el echo. >
set ruta=C:\Connectivity_Logs
if not exist %ruta% mkdir %ruta%
set rutalog=%ruta%\%date:~6,4%%date:~3,2%%date:~0,2%_Connectivity_Test.log
echo. >%rutalog%
REM Nos vamos a apoyar en un par de archivos txt y una variable que me permita controlar que si hay una ip que no tiene conectividad mande un mail
set pinged=%ruta%\ping.txt
set pinged2=%ruta%\ping2.txt
set ENVIOMAIL=NO
:: Lanzar comprobaciones
REM Volcamos una cabecera en el .log
echo. >>%rutalog%
echo ************************* >>%rutalog%
echo *** CONNECTIVITY TEST *** >>%rutalog%
echo ************************* >>%rutalog%
echo. >>%rutalog%
REM Recorremos las unidades de red de la variable ADMIN_UDs
for %%a in (%ADMIN_UDs_Red%) do (
echo Checking %%a
REM Hacemos un ping y volcamos el resultado al primer .txt
PING -w 3000 %%a > %pinged%
REM Buscamos si en el primer .txt hay indicios de conectividad y volcamos al segundo .txt
@find /C "TTL=" %pinged% > %pinged2%
REM Ahora la variable estado es la que marcará la conectividad, viendo el número que se ha volcado al segundo .txt si no es 0 es que ha encontrado alguna coincidencia, en este caso por como hemos hecho el ping será 1
set estado=[nOK]
for /F "tokens=1,2,3" %%h in (%pinged2%) do (
set control=%%j
if "%%h" EQU "----------" (
if "!control!" NEQ "0" set estado=OK
)
)
REM Volcamos el resultado al .log
echo Checked ... %%a: !estado! >>%rutalog%
REM En caso de no haber conectividad en cualquiera de las ips activa el envio de un mail
if !ENVIOMAIL! EQU NO (
if !estado! EQU [nOK] set ENVIOMAIL=SI
)
)
REM Realizamos exactamente lo mismo con la lista de servidores
for %%a in (%ADMIN_Servers%) do (
echo Checking %%a
PING -w 3000 %%a > %pinged%
@find /C "TTL=" %pinged% > %pinged2%
set estado=[nOK]
for /F "tokens=1,2,3" %%h in (%pinged2%) do (
set control=%%j
if "%%h" EQU "----------" (
if "!control!" NEQ "0" set estado=OK
)
)
echo Checked ... %%a: !estado! >>%rutalog%
if !ENVIOMAIL! EQU NO (
if !estado! EQU [nOK] set ENVIOMAIL=SI
)
)
REM Volcamos un pie de log para constatar que hemos terminado con el
echo. >>%rutalog%
echo ************************* >>%rutalog%
echo *** END *** >>%rutalog%
echo ************************* >>%rutalog%
REM Borramos los ficheros .txt en los que nos hemos apoyado.
del %pinged%
del %pinged2%
REM Aqui controlariamos el envio del mail, en este caso solo hago un echo.
ECHO %ENVIOMAIL%
PAUSE
Si quieres saber como enviar el mail, mira esta entrada: Enviar un mail con PowerShell
Bien, esto sería mas fácil haciéndolo desde powershell, ya que con un único comando obtenemos true o false al comprobar la conectividad y lo almacenamos en una variable:
a$=test-connection -computername <nombre_servidor> -quiet
En este caso la variable a$ tendrá el resultado true o false de la comprobación de conexión.
Por ejemplo, para saber si tenemos conectividad a internet, podemos lanzar directamente el comando en la consola de windows powershell:
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. Reservados todos los derechos.
PS C:\> test-connection -computername google.com -quiet
True
PS C:\>
Si consultamos la ayuda, podemos ver que admite algunas variantes, por ejemplo si queremos comprobar varios equipos:
test-connection -computername server01, server02, server12 -credential domain01\user01
Incluso personalizando los parametros del ping
test-connection -computername Server01 -count 3 -delay 2 -TTL 256 -buffersize 256 -throttle 32
Podríamos ir mas allá y concatenar la condición de conexión con un servidor a si esta es true lanzar una sesión interactiva:
if (test-connection -computername Server01 -quiet) {new-pssession Server01}
Veamos como lo realiza:
PS C:\> if (test-connection -computername servidor01 -quiet) {new-pssession servidor01}
Id Name ComputerName State ConfigurationName Availability
-- ---- ----------------- ----------------- ------------ -----------
1 Session1 servidor01 Opened Microsoft.PowerShell Available
PS C:\>
Nos ha creado la sesión en el servidor, introducimos el número de id en el comando Enter-PSSession 1 y cambiamos a esa sesión interactiva para lanzar comandos en el propio servidor:
PS C:\> Enter-PSSession 1
[servidor01]: PS C:\Users\usuario01\Documents>
Para gustos colores yo a veces prefiero coger scripts que ya tengo hechos y no perder ni un segundo y otras veces me apetece recordar un poco comandos y métodos olvidados.
Piensa en variantes de este método, si cambias el listado de servidores o almacenamientos por lista de dominios controlas si hay conectividad hacia los dominios que administras, o los que consultas de normal, etcétera.
Para gustos colores yo a veces prefiero coger scripts que ya tengo hechos y no perder ni un segundo y otras veces me apetece recordar un poco comandos y métodos olvidados.
Piensa en variantes de este método, si cambias el listado de servidores o almacenamientos por lista de dominios controlas si hay conectividad hacia los dominios que administras, o los que consultas de normal, etcétera.
SaluDOS.
Enviar un mail con PowerShell
En algunos de los desarrollos que he hecho últimamente con scripts, siempre acabo teniendo que enviar un correo electrónico, o bien a los usuarios, o bien a los administradores.
Veamos de forma muy simple y con un ejemplo concreto como sería ese script:
# Tomamos el valor de un argumento al ejecutar el script, este va a ser un archivo del que cogeremos su contenido.
$archivo=$args[0]
# Especificamos los destinatarios, en caso de ser varios hay que separarlos con coma.
$to = "destinatario1@dominio.com, destinatario2@dominio.com"
# Especificamos el remitente.
$from = "remitente@dominio.com"
# Especificamos el Asunto del correo electronico.
$subject = "Escribimos entre comillas el Asunto del correo electrónico"
# Aqui vamos a definir el cuerpo del mensaje. En este caso vamos a transformar el contenido de un fichero plano formateado en el contenido que agregará al correo.
$body = Get-Content -path $archivo | Out-String
#Definimos el servidor de correo mediante su ip
$smtpServer = "172.16.15.83"
#Creamos el objeto mail
$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25)
$smtpClient.EnableSsl = $false
#Lo enviamos
$smtpClient.Send($from, $to, $subject, $body)
Pues nada espero que sirva como referencia.
SaluDOS.
Veamos de forma muy simple y con un ejemplo concreto como sería ese script:
# Tomamos el valor de un argumento al ejecutar el script, este va a ser un archivo del que cogeremos su contenido.
$archivo=$args[0]
# Especificamos los destinatarios, en caso de ser varios hay que separarlos con coma.
$to = "destinatario1@dominio.com, destinatario2@dominio.com"
# Especificamos el remitente.
$from = "remitente@dominio.com"
# Especificamos el Asunto del correo electronico.
$subject = "Escribimos entre comillas el Asunto del correo electrónico"
# Aqui vamos a definir el cuerpo del mensaje. En este caso vamos a transformar el contenido de un fichero plano formateado en el contenido que agregará al correo.
$body = Get-Content -path $archivo | Out-String
#Definimos el servidor de correo mediante su ip
$smtpServer = "172.16.15.83"
#Creamos el objeto mail
$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer, 25)
$smtpClient.EnableSsl = $false
#Lo enviamos
$smtpClient.Send($from, $to, $subject, $body)
Pues nada espero que sirva como referencia.
SaluDOS.
sábado, 8 de octubre de 2016
Variable JAVA_HOME siempre actualizada con script Powershell
Aunque ha sido una cuestión de trabajo, he tenido que invertir cierto tiempo personal para definir un procedimiento sencillo, a mi alcance, y sobretodo que se pueda implantar rápido en ciertos archivos .bat de una aplicación.
La idea es muy básica, aunque estuve estudiando otras posibilidades, coger del registro de Windows la versión actual de Java, y dentro de esta el valor de la variable JavaHome, donde está la ruta del JRE que queremos actualizar en la variable de sistema JAVA_HOME.
Por lo que he ido comprobando es un problema recurrente, al actualizar la versión de Java, cambia la ruta y la variable ya no apunta a donde debería. Pero claro, esto a la hora de gestionarlo en cientos de usuarios y equipos, pues no es como cuando te pasa a ti, que identificas el problema, cambias el valor de la variable y listo.
Bien, la idea es crear un archivo .bat que realizará la llamada a un powershell .ps1 y después realizará la limpieza de archivos temporales. Esto se va a integrar en el lanzamiento de la aplicación, pero esta parte ya no puedo ponerla aquí, se complicaría mucho la entrada.
Veamos el script powershell donde está el meollo de la cuestión. Este sería el archivo .bat que realiza la llama al powershell simplificado y sin los condicionantes que pondría la aplicación que utilizamos.
REM---Comienzo de script .bat---
REM version_java.bat
powershell -noprofile ".\ruta_java.ps1" C:\ruta_java_current.txt C:\ruta_java.txt C:\ruta_java_final.txt
del C:\ruta_jav*.txt
REM---Fin de script .bat---
A continuación el script powershell que realiza el proceso de identificar la versión actual de java, voy a ir poniendo comentarios que no están en el script para que se entienda a rasgos generales que hace cada parte:
#version_java.ps1
#Tomamos los argumentos que nos pasa al .ps1 el script .bat. Esos argumentos son las rutas y nombres de archivos que utilizaremos posteriormente en el script.
$ruta_current=$args[0]
$ruta=$args[1]
$ruta_final=$args[2]
# Obtenemos la version actual, accediendo a la ruta concreta del registro de windows y lo almacenamos en el primer argumento ($ruta_current). Después le hacemos una limpieza quedándonos con lo que nos interesa, que sería un valor tal que 1.8 por ejemplo.
$ruta_java=get-ItemProperty -Path "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment" -name CurrentVersion
#Write-Host $ruta_java
$ruta_java | Out-File $ruta_current
(Get-Content -Path $ruta_current) | Where-Object -FilterScript {$_.Trim() -ne '' } | Set-Content -Path $ruta_current
$texto_current = Get-Content -Path $ruta_current | Select-Object -Last 1
$texto_current | Out-File $ruta_final
(Get-Content $ruta_final) | ForEach-Object { $_ -replace "CurrentVersion", "" } | Set-Content $ruta_final
(Get-Content $ruta_final) | ForEach-Object { $_ -replace ":", "" } | Set-Content $ruta_final
(Get-Content $ruta_final) | ForEach-Object { $_ -replace " ", "" } | Set-Content $ruta_final
$texto_current = Get-Content -Path $ruta_final
#Write-Host $texto_current
# Obtenemos la ruta de la version actual. Ahora ya podemos profundizar un poco mas en la ruta del registro de windows añadiendo el valor obtenido en las lineas anteriores. Vamos a realizar un proceso muy parecido al anterior, una vez obtenida la ruta almacenada en JavaHome, le hacemos una limpieza y finalmente esa ruta la dejamos en una ruta final.
$ruta_current = "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment\"+$texto_current
$ruta_java=get-ItemProperty -Path $ruta_current -name "JavaHome"
#Write-Host $ruta_java
$ruta_java | Out-File $ruta
(Get-Content -Path $ruta) | Where-Object -FilterScript {$_.Trim() -ne '' } | Set-Content -Path $ruta
$texto = Get-Content -Path $ruta | Select-Object -Last 1
$texto | Out-File $ruta_final
(Get-Content $ruta_final) | ForEach-Object { $_ -replace "JavaHome : ", "" } | Set-Content $ruta_final
$variable = Get-Content -Path $ruta_final
# Cambiamos las variables de entorno. Una vez que ya tenemos almacenada la ruta exacta, la utilizamos para actualizar la variable JAVA_HOME. Tenemos en cuenta si existe alguna que sea de usuario y la borramos, siempre utilizaremos la variable de entorno pero de máquina.
[Environment]::SetEnvironmentVariable("JAVA_HOME",$null,"User")
[Environment]::SetEnvironmentVariable("JAVA_HOME", $variable, "Machine")
$env:JAVA_HOME = $variable
A partir de aqui lo único que hace el .bat es borrar los archivos temporales.
En principio los resultados son muy buenos en equipos con Windows 7 SP1, veremos si no se estropea con alguna actualización de Java o de Windows.
SaluDOS
La idea es muy básica, aunque estuve estudiando otras posibilidades, coger del registro de Windows la versión actual de Java, y dentro de esta el valor de la variable JavaHome, donde está la ruta del JRE que queremos actualizar en la variable de sistema JAVA_HOME.
Por lo que he ido comprobando es un problema recurrente, al actualizar la versión de Java, cambia la ruta y la variable ya no apunta a donde debería. Pero claro, esto a la hora de gestionarlo en cientos de usuarios y equipos, pues no es como cuando te pasa a ti, que identificas el problema, cambias el valor de la variable y listo.
Bien, la idea es crear un archivo .bat que realizará la llamada a un powershell .ps1 y después realizará la limpieza de archivos temporales. Esto se va a integrar en el lanzamiento de la aplicación, pero esta parte ya no puedo ponerla aquí, se complicaría mucho la entrada.
Veamos el script powershell donde está el meollo de la cuestión. Este sería el archivo .bat que realiza la llama al powershell simplificado y sin los condicionantes que pondría la aplicación que utilizamos.
REM---Comienzo de script .bat---
REM version_java.bat
powershell -noprofile ".\ruta_java.ps1" C:\ruta_java_current.txt C:\ruta_java.txt C:\ruta_java_final.txt
del C:\ruta_jav*.txt
REM---Fin de script .bat---
A continuación el script powershell que realiza el proceso de identificar la versión actual de java, voy a ir poniendo comentarios que no están en el script para que se entienda a rasgos generales que hace cada parte:
#version_java.ps1
#Tomamos los argumentos que nos pasa al .ps1 el script .bat. Esos argumentos son las rutas y nombres de archivos que utilizaremos posteriormente en el script.
$ruta_current=$args[0]
$ruta=$args[1]
$ruta_final=$args[2]
# Obtenemos la version actual, accediendo a la ruta concreta del registro de windows y lo almacenamos en el primer argumento ($ruta_current). Después le hacemos una limpieza quedándonos con lo que nos interesa, que sería un valor tal que 1.8 por ejemplo.
$ruta_java=get-ItemProperty -Path "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment" -name CurrentVersion
#Write-Host $ruta_java
$ruta_java | Out-File $ruta_current
(Get-Content -Path $ruta_current) | Where-Object -FilterScript {$_.Trim() -ne '' } | Set-Content -Path $ruta_current
$texto_current = Get-Content -Path $ruta_current | Select-Object -Last 1
$texto_current | Out-File $ruta_final
(Get-Content $ruta_final) | ForEach-Object { $_ -replace "CurrentVersion", "" } | Set-Content $ruta_final
(Get-Content $ruta_final) | ForEach-Object { $_ -replace ":", "" } | Set-Content $ruta_final
(Get-Content $ruta_final) | ForEach-Object { $_ -replace " ", "" } | Set-Content $ruta_final
$texto_current = Get-Content -Path $ruta_final
#Write-Host $texto_current
# Obtenemos la ruta de la version actual. Ahora ya podemos profundizar un poco mas en la ruta del registro de windows añadiendo el valor obtenido en las lineas anteriores. Vamos a realizar un proceso muy parecido al anterior, una vez obtenida la ruta almacenada en JavaHome, le hacemos una limpieza y finalmente esa ruta la dejamos en una ruta final.
$ruta_current = "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment\"+$texto_current
$ruta_java=get-ItemProperty -Path $ruta_current -name "JavaHome"
#Write-Host $ruta_java
$ruta_java | Out-File $ruta
(Get-Content -Path $ruta) | Where-Object -FilterScript {$_.Trim() -ne '' } | Set-Content -Path $ruta
$texto = Get-Content -Path $ruta | Select-Object -Last 1
$texto | Out-File $ruta_final
(Get-Content $ruta_final) | ForEach-Object { $_ -replace "JavaHome : ", "" } | Set-Content $ruta_final
$variable = Get-Content -Path $ruta_final
# Cambiamos las variables de entorno. Una vez que ya tenemos almacenada la ruta exacta, la utilizamos para actualizar la variable JAVA_HOME. Tenemos en cuenta si existe alguna que sea de usuario y la borramos, siempre utilizaremos la variable de entorno pero de máquina.
[Environment]::SetEnvironmentVariable("JAVA_HOME",$null,"User")
[Environment]::SetEnvironmentVariable("JAVA_HOME", $variable, "Machine")
$env:JAVA_HOME = $variable
A partir de aqui lo único que hace el .bat es borrar los archivos temporales.
En principio los resultados son muy buenos en equipos con Windows 7 SP1, veremos si no se estropea con alguna actualización de Java o de Windows.
SaluDOS
miércoles, 2 de marzo de 2016
Script de powershell, impresora predeterminada
Una entrada rápida.
Tenemos de vez en cuando, en el trabajo, problemas con la desconfiguración de la impresora predeterminada. De vez en cuando pasa, la impresora predeterminada que te corresponde por usuario, por cercanía, por el motivo que sea, se cambia. Eso supone que cuando le das a imprimir, si no estás atento, tengas que ir a la impresora de otra planta o de otro edificio, el tema es gracioso.
La solución rápida que se me ha ocurrido es colocar en la carpeta inicio del usuario o de todos los usuarios, en este caso de Windows 7, los siguientes scripts:
Un archivo .bat que lanzará el script powershell, lo he llamado impresora_predeterminada.bat:
powershell.exe -noprofile ".\impresora_predeterminada.ps1" name_impresora computername
Pasamos dos argumentos, el primero es el nombre de la impresora y el segundo el del equipo. Tenemos que cambiarlo por los nombres correctos, en el caso del computername es sencillo, lo podemos mirar en Panel de control\Sistema. En el caso de la impresora, podemos lanzar un comando powershell que nos liste las impresoras y ahí podemos ver la propiedad name de cada una. En este caso tenemos que poner el Nombre del Equipo después de -ComputerName:
Get-WmiObject -Class Win32_Printer -ComputerName NombreDelEquipo
Cuando es una impresora en red, si miramos en sus propiedades aparecerá algo así como Multifuncion_Planta1 en ServidorImpresión, cuando realmente el name que veremos será \\ServidorImpresión\Multifuncion_Planta1. Es por eso que conviene usar el comando ver el name que tiene la impresora.
Por último, un archivo .ps1 que será el script de powershell, lo he llamado impresora_predeterminada.ps1
$impresora=$args[0]
$ordenador=$args[1]
(New-Object -ComObject WScript.Network).SetDefaultPrinter($impresora)
Cogemos los dos argumentos que entran al lanzar el powershell desde el .bat, el primero es el nombre de la impresora y el segundo es el nombre del equipo.
Con este script, siempre que arranquemos Windows, tendremos la impresora que configuremos en los scripts como impresora predeterminada.
SaluDOS.
Tenemos de vez en cuando, en el trabajo, problemas con la desconfiguración de la impresora predeterminada. De vez en cuando pasa, la impresora predeterminada que te corresponde por usuario, por cercanía, por el motivo que sea, se cambia. Eso supone que cuando le das a imprimir, si no estás atento, tengas que ir a la impresora de otra planta o de otro edificio, el tema es gracioso.
La solución rápida que se me ha ocurrido es colocar en la carpeta inicio del usuario o de todos los usuarios, en este caso de Windows 7, los siguientes scripts:
Un archivo .bat que lanzará el script powershell, lo he llamado impresora_predeterminada.bat:
powershell.exe -noprofile ".\impresora_predeterminada.ps1" name_impresora computername
Pasamos dos argumentos, el primero es el nombre de la impresora y el segundo el del equipo. Tenemos que cambiarlo por los nombres correctos, en el caso del computername es sencillo, lo podemos mirar en Panel de control\Sistema. En el caso de la impresora, podemos lanzar un comando powershell que nos liste las impresoras y ahí podemos ver la propiedad name de cada una. En este caso tenemos que poner el Nombre del Equipo después de -ComputerName:
Get-WmiObject -Class Win32_Printer -ComputerName NombreDelEquipo
Cuando es una impresora en red, si miramos en sus propiedades aparecerá algo así como Multifuncion_Planta1 en ServidorImpresión, cuando realmente el name que veremos será \\ServidorImpresión\Multifuncion_Planta1. Es por eso que conviene usar el comando ver el name que tiene la impresora.
Por último, un archivo .ps1 que será el script de powershell, lo he llamado impresora_predeterminada.ps1
$impresora=$args[0]
$ordenador=$args[1]
(New-Object -ComObject WScript.Network).SetDefaultPrinter($impresora)
Cogemos los dos argumentos que entran al lanzar el powershell desde el .bat, el primero es el nombre de la impresora y el segundo es el nombre del equipo.
Con este script, siempre que arranquemos Windows, tendremos la impresora que configuremos en los scripts como impresora predeterminada.
SaluDOS.
Suscribirse a:
Entradas (Atom)