Inicio Blog Cosas útiles de PowerShell que le ayudarán a ahorrar tiempo todos los días - Parte 1

Cosas útiles de PowerShell que le ayudarán a ahorrar tiempo todos los días - Parte 1

Si usted afirma que no sabe nada de PowerShell es probable que esté equivocado. Si usted ha utilizado cualquier herramienta de línea de comandos o sistemas explorados a través de una línea de comandos, entonces usted sabe un poco de PowerShell, ya que se superpone a la línea de comandos de huesos desnudos.
Robert Waite | 6 de diciembre de 2022

Cosas útiles de PowerShell que le ayudarán a ahorrar tiempo cada día

Fundamentos de PowerShell

En esta serie de blogs, mi objetivo es convencerte para que aprendas PowerShell. Espero llegar a un público más amplio que sólo los desarrolladores con este post. Si eres un consultor ERP no desarrollador este blog también es para ti. De hecho, PowerShell no es una herramienta creada para desarrolladores, fue pensada para servir a los administradores de sistemas y consultores y permitirles automatizar las tareas de administración de TI. Pero hay un montón de poder que los desarrolladores también pueden obtener de conocer y utilizar PowerShell en el desarrollo diario.

Si usted afirma que no sabe nada de PowerShell es probable que esté equivocado. Si usted ha utilizado cualquier herramienta de línea de comandos o explorado sistemas a través de una línea de comandos, entonces usted sabe un poco de PowerShell, ya que se superpone a la línea de comandos de huesos desnudos. Así que vamos a empezar este blog con un poco de navegación fundamental del sistema de archivos y la manipulación. Vamos a utilizar un caso de uso del mundo real para automatizar la actualización de una biblioteca de referencia para volver a apuntar a una versión diferente de Acumatica Archivos

Caso práctico: Actualizar dll Carpeta de biblioteca de referencia para utilizar una versión diferente de Acumatica

Según mi experiencia de trabajo con muchos desarrolladores de Acumatica diferentes, todos tienen una forma distinta de conectar las referencias de Visual Studio a una instancia de Acumatica. Recientemente, mi compañero desarrollador MVP Stephan Belanger me ha enseñado una forma muy ingeniosa de realizar esta tarea. La estrategia es sencilla. Los archivos Dll se copian del directorio Acumatica Bin a una carpeta del proyecto de Visual Studio y las referencias apuntan a su vez a esos archivos. Lo que me ENCANTA de esta estrategia es que ahora el proyecto de VS se puede crear sin necesidad de una instancia real de Acumatica a la que apuntar. De modo que ni siquiera es necesario cargar el sitio web en la solución. Esto se prestará bien a cualquier proceso de construcción automatizado o CI/CD. Siempre y cuando los archivos dll de la versión de destino de Acumatica se encuentren en esa carpeta de biblioteca, todo estará listo. Se acabaron las referencias complicadas cada vez que quieras trabajar con una nueva versión de Acumatica. Todo lo que tienes que hacer es actualizar los archivos. Vamos a automatizar esto utilizando llamadas de línea de comandos fundamentales y luego encadenándolas en un script de PowerShell.

ISE frente a PowerShell Prompt

Hay dos formas fundamentales de utilizar PowerShell. La primera es el ISE o (Integrated Scripting Environment). O dos el prompt de PowerShell. Por lo general, utilizará el Entorno de secuencias de comandos integrado ISE para desarrollar, solucionar problemas y mantener secuencias de comandos de PowerShell. A continuación, utilizará el símbolo del sistema de PowerShell para utilizar y consumir scripts y servicios de PowerShell. Otra diferencia es que ISE tiene Intel sense y el prompt de PowerShell tiene algo similar llamado Tab. Cada uno hace lo mismo pero de maneras muy diferentes.

Cosas útiles de PowerShell que le ayudarán a ahorrar tiempo cada día

Completar pestaña

Para explorar la finalización de la pestaña vamos a abrir el símbolo del sistema PowerShell e identificar la carpeta de archivos que queremos actualizar. Abra el menú de inicio y escriba PowerShell. Usted obtendrá algo como la imagen de arriba el símbolo del sistema PowerShell es la opción sin el sufijo ISE. Vamos a abrir eso. Lo más probable es que usted sabe de la DOS comando DIR para devolver un listado de directorios. Podemos buscar nuestro objetivo escribiendo DIR y luego c:\ o la unidad que contiene el proyecto. Escribamos la primera letra del siguiente directorio y pulsemos el tabulador. Verás que aparece el primero que empieza directamente por esa letra. Si usted no ha llegado a su deseada directamente a continuación, pulse la tecla tabulador de nuevo y repita hasta llegar al siguiente directorio. Si has ido demasiado lejos y quieres ir al directorio anterior, entonces usa shift tab. Empieza a escribir la siguiente letra o dos y luego tabula hasta que llegues a la siguiente parte de la ruta. Así es como funciona el tabulador. Es esencialmente inteligencia para un sistema de línea de comandos no gráfico. Todo lo que necesitas recordar son estas dos cosas. Hay muchas cosas más allá de la navegación por el sistema de ficheros que también utilizan el completado con tabulador.

Tab = mover siguiente.

Mayús Tab = mover anterior.

 

IntelliSense en ISE

A continuación, exploraremos cómo funciona esto en el Entorno Integrado de Scripting. Desde el menú de inicio, vamos a abrir la otra opción de PowerShell que es abrir el ISE. Además del completado de Tabuladores, también verás que se abre una ventana de IntelliSense que te ayuda a navegar por el sistema de archivos. Identifiquemos ahora la carpeta de archivos.

Powershell-Parte1

Todo lo anterior es estándar de interfaz de línea de comandos cosas que PowerShell se construye en la parte superior. Ahora podemos añadir una característica que no encontrarás sólo en la línea de comandos. Es decir, podemos cargar los resultados en una variable PowerShell. Todo lo que tenemos que hacer es utilizar el carácter $ para anteponer un nombre de variable y luego utilizar el carácter = seguido de la sentencia que acabamos de ejecutar. En lugar de volver a escribir el comando agujero sólo tiene que pulsar la flecha hacia arriba para mostrar el último comando. Ahora si presionas tu tecla home para colocar tu cursor al principio de la línea. Ahora escribe $libFiles = y luego enter. Parece que no ha pasado nada pero si ahora tecleas $libFiles verás que te devuelve los resultados que antes te devolvía solo el comando DIR.

Powershell-Parte1

Ahora lo que podemos hacer con esta variable es ponerla a través de un comando foreach y luego hacer algo con cada uno de los archivos. Copiemos nuestra línea que contiene la asignación de la variable en la parte del editor de scripts del editor ISE. Después de esa línea, añadiremos el archivo foreach y simplemente devolveremos el nombre del archivo al host. Usted puede notar que usted no consigue IntelliSense como usted está escribiendo $libFile.name. Esto es porque la variable nunca ha sido inicializada. Un truco al hacer estos bucles foreach es ejecutar el bucle una vez y sólo devolver el propio archivo. Ahora si ejecuta el script (use F5 como atajo) podrá interactuar con el último objeto del bucle. Esta es una característica muy poderosa de PowerShell, que es ser capaz de interactuar con objetos mientras construyes un script. Esto se verá como lo siguiente.

Powershell-Parte1

Ahora lo que necesitamos hacer dentro de este bucle es encontrar las dlls actualizadas que necesitan reemplazar la lista cargada en nuestra variable $libFiles. Lo que necesitamos saber ahora es Dónde está la carpeta bin de los archivos fuente que necesitamos. Todo lo que necesitamos saber en este punto es el directorio de Acumatica y podemos deducir el bin de eso. En este punto, vamos a hacer que el usuario del script introduzca esa información. Para ello invocaremos el comando Read-Host.

Read-Host

Read-Host es un comando muy útil. Particularmente me gusta usarlo cuando estoy trabajando en un script inacabado y generalmente refactorizo el Read-Host fuera del script en etapas futuras del script. Esencialmente todo lo que hace Read-Host es preguntar al usuario final por un valor de cadena. Cadenas vacías o simplemente pulsando enter es una entrada aceptable. Esto también introduce un mecanismo para añadir retraso en un script para esperar la finalización de una tarea manual. Me gusta utilizar esta técnica en las primeras etapas de la automatización de un proceso mientras que yo podría conseguir un usuario humano para realizar temporalmente una tarea manual sin dejar de ser capaz de automatizar una parte del proceso. A menudo empiezo un script con sólo líneas Read-Host. Una para cada paso de un proceso que pretendemos automatizar. Algo como lo siguiente

Powershell-Parte1

En el script anterior no ocurre nada más que pedir al usuario que realice alguna tarea manual. En este momento estamos buscando automatizar el paso 6. Una vez que esté en su lugar podríamos reemplazar esa línea con nuestra secuencia de comandos de trabajo y entonces tendremos una secuencia de comandos semi-automatizada que tiene algún proceso manual, pero no obstante está ahorrando un cierto grado de tiempo sobre el número incontable de veces que este proceso tiene que ser repetido. A menudo me encuentro con que no tengo mucho tiempo para terminar un guión. Pero si tengo el hábito de hacer el script anterior ligeramente más automatizado en cada ejecución con el poco tiempo que tengo. Entonces la realidad es que a largo plazo esta automatización liberará aún más tiempo para refinar y hacer menos trabajo manual en cada iteración.

Volviendo a nuestro objetivo de automatizar la actualización de las dll's lo que haremos será añadir estas líneas al principio del script.

Powershell-Parte1

Tenemos un bloque do while donde el comando Test-Path va a validar si el valor introducido es bueno. Podemos ver que la línea Read-Host preguntará al usuario y cargará el valor en una variable. La línea siguiente formatea el valor de entrada en una cadena que debe apuntar al directorio bin. El mensaje se repetirá hasta que se introduzca una entrada válida. Esta es una forma muy fácil de obtener información de un usuario. Hay maneras más elegantes de hacer esto. Teniendo en cuenta que tenemos todo el poder de .NET dentro de PowerShell podemos incluso hacer aparecer cuadros de diálogo modales que nos ayudarán con la selección. En este blog estamos tratando sólo lo básico. Pero vamos a entrar en un tema más avanzado que incluye la concesión de entrada GUI en un futuro blog en esta serie. Tenemos lo que necesitamos así que procederemos con la siguiente parte.

Ahora que sabemos dónde están las dlls fuente podemos actualizar nuestro bucle para que haga el trabajo que buscamos. Dada la intratabilidad del prompt de PowerShell, podemos usarlo para explorar la siguiente parte. A medida que encontramos piezas que funcionan podemos utilizar la tecla de flecha hacia arriba para obtener el último comando y luego añadirlo a la parte de script. Si utilizamos el tabulador o la inteligencia en la variable $labile podemos determinar que vamos a necesitar los valores fullname y name. Vamos a cargarlos en variables como esta.

Powershell-Parte1

A continuación, podemos concatenar la carpeta de origen y destino como tal y ahora sabemos la ruta de destino y la ruta de origen del archivo que necesita ser copiado.

Powershell-Parte1

Sin volver a lo básico de la línea de comandos podemos usar el comando copy para hacer el trabajo.

Algo así:

Powershell-Parte1

Pero podemos añadir un par de nombres de parámetros PowerShell para que lo que esto está haciendo sea un poco más comprensible.

Powershell-Parte1

Una vez que probamos que esto funciona para el comando único ahora podemos usar soltar todas las líneas de trabajo en el script. En lugar de utilizar la tecla de flecha arriba para cada una de ellas, podemos utilizar Get-History o simplemente hist para obtener todos los comandos que hemos introducido en esta sesión. Get-History es otra herramienta útil cuando construimos scripts ya que eliminará la necesidad de volver a escribir cosas que hemos explorado usando el prompt de PowerShell. Basta con cortar y pegar para obtener estas líneas en el bucle foreach. Nuestro resultado final es el siguiente.

Powershell-Parte1

Vamos a ejecutar el script y ver si obtenemos los resultados que necesitamos. Si usted ve todos los archivos como la versión deseada, entonces fue un éxito.

Funciones

Podemos refinar este script un poco mejor encapsulando lo que se necesita en una función. Y en lugar de tener un directorio estático LibFiles y un prompt Read-Host, podemos configurarlos como parámetros ya que estas son las dos piezas de información necesarias para esta tarea. En la sección param() definiremos dos variables y estableceremos su tipo como System.IO.FileInfo. La magia de establecer esto como el tipo de variable en lugar de sólo la cadena por defecto es que cuando se utiliza esta función en el símbolo del sistema PowerShell sabrá que usted está buscando una ruta. A su vez, obtienes todo el IntelliSense o la maravilla de completar tabulaciones que hace las cosas más fáciles.

Powershell-Parte1

Una línea como ésta automatizará lo que antes era un proceso manual. Si este proceso se repite cientos de veces al año, el ROI en tiempo invertido en crear este script se amortizará rápidamente.

Powershell-Parte1

Resumen de lo aprendido

La intención de este blog es utilizar una herramienta común de línea de comandos "copiar" para automatizar el proceso de copiar manualmente estos archivos. Hemos aprendido que todo lo que se puede hacer en una línea de comandos se puede hacer en scripts de PowerShell. Vale la pena saber cómo hacer una tarea desde la línea de comandos porque podrías ahorrarte mucho tiempo incorporando lo que sabes sobre la línea de comandos en un script PowerShell. Aprendimos un poco sobre las dos herramientas diferentes para utilizar PowerShell, llamadas PowerShell prompt y PowerShell ISE (Integrated Scripting Environment). El prompt de lectura es una potente herramienta para introducir retardos controlados, solicitar información a los usuarios o pedirles que realicen un paso manual que más tarde se automatizará por completo. Tab Completion e IntelliSense ayudan a ahorrar pulsaciones de teclas y permiten explorar objetos de forma interactiva. Aprendimos cómo usar Test-Path para afirmar que una ruta existe y la incorporamos en un bucle do whilepara validar una entrada Read-Host. No entramos en la creación de funciones en gran detalle, pero terminamos el blog convirtiendo nuestro script en una función. Creamos parámetros del tipo System.IO.FileInfo que a su vez nos ayuda a usar el completado de tabulador e IntelliSense cuando introducimos las rutas de origen y destino necesarias.

A continuación

Vamos a automatizar aún más el proceso de inicialización de una biblioteca de extensión de Acumatica en una función. El siguiente elemento que queremos automatizar es redirigir la solución para que envíe el archivo dll de la biblioteca de extensión al directorio bin de la instancia de Acumatica de destino. Nos adentraremos en PowerShell más fundamental y cómo se puede utilizar para cargar datos de archivos CSV o XML. Nuestro objetivo será actualizar los archivos XML del proyecto y de la solución para redirigir a dónde irán las cosas durante el proceso de compilación.

¡Feliz scripting!

 

Autor del blog

Robert es el desarrollador jefe de Acumatica en APS Payments, una empresa de REPAY, proveedor líder de soluciones de pago integradas omnicanal B2B. La pasión de Robert por la programación comenzó en la escuela primaria haciendo proyectos en el Apple IIe, y sacó todos los libros de la biblioteca que pudo sobre el tema para apaciguar su voraz apetito por aprender a codificar. Robert empezó a trabajar con software de plataformas ERP en 2003, donde automatizaba tareas de distribución en una aplicación de pantalla verde llamada PICK, que más tarde sustituyó por Sage 100. Desde entonces, ha ampliado su experiencia a muchos otros sistemas ERP, incluido Acumatica. Antes de unirse a APS Payments, Robert trabajó para Accounting Systems, Inc. (ASI Focus), donde fue desarrollador de software ERP. Fuera de la programación, Robert es un apasionado del baile, donde lo encontrará pasando mucho tiempo buscando cualquier oportunidad para West Coast Swing, Hustle, Salsa, así como muchos otros estilos de baile. En su tiempo libre, le gusta soldar drones de carreras y proyectos de domótica IoT. Robert trabaja como voluntario en un espacio maker de un instituto local y ha impartido clases de programación de Arduinos y otras placas de desarrollo IoT como la Raspberry Pi.

Reciba las actualizaciones del blog en su bandeja de entrada.