<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Sobrebits</title>
	<atom:link href="https://sobrebits.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://sobrebits.com</link>
	<description></description>
	<lastBuildDate>Wed, 30 Oct 2019 15:53:00 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.3.2</generator>
<site xmlns="com-wordpress:feed-additions:1">40052975</site>	<item>
		<title>Packer para VMware (Parte 1): Creación de plantilla de Windows automatizada</title>
		<link>https://sobrebits.com/packer-para-vmware-parte-1-creacion-de-plantilla-de-windows-automatizada/</link>
				<comments>https://sobrebits.com/packer-para-vmware-parte-1-creacion-de-plantilla-de-windows-automatizada/#respond</comments>
				<pubDate>Wed, 30 Oct 2019 16:00:33 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[Automatización]]></category>
		<category><![CDATA[Virtualización]]></category>
		<category><![CDATA[Packer]]></category>
		<category><![CDATA[VMware]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3460</guid>
				<description><![CDATA[<p>En esta entrada utilizaremos Packer para VMware,  con el que automatizaremos la creación de una plantilla de Windows Server 2016 sobre vSphere.</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/packer-para-vmware-parte-1-creacion-de-plantilla-de-windows-automatizada/">Packer para VMware (Parte 1): Creación de plantilla de Windows automatizada</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>En la entrada anterior hablamos sobre la <a rel="noreferrer noopener" aria-label="creación de plantillas automatizada con Packer (opens in a new tab)" href="https://sobrebits.com/introduccion-a-la-creacion-automatica-de-plantillas-con-packer/" target="_blank">creación de plantillas automatizada con Packer</a> y de como podía ésta ayudarnos en la automatización de nuestros despliegues. En la entrada de hoy veremos el uso de <strong>Packer para VMware</strong>, con el que desplegaremos de forma totalmente automatizada una instalación de Windows Server 2016 en una infraestructura vSphere.</p>



<ul><li><strong>Parte 0</strong>: <a rel="noreferrer noopener" aria-label="Introducción a la creación automática de plantillas con Packer (opens in a new tab)" href="https://sobrebits.com/introduccion-a-la-creacion-automatica-de-plantillas-con-packer/" target="_blank">Introducción a la creación automática de plantillas con Packer</a>.</li><li><strong><em>Parte 1</em></strong><em>: Creación de plantilla de Windows automatizada.</em></li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/10/Packer-para-VMware_-Creación-de-plantilla-de-Windows-automatizada.png" alt="Packer para VMware - Creación de plantilla de Windows automatizada" class="wp-image-3520" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/10/Packer-para-VMware_-Creación-de-plantilla-de-Windows-automatizada.png?w=520&amp;ssl=1 520w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/10/Packer-para-VMware_-Creación-de-plantilla-de-Windows-automatizada.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></div>



<h2>Escogiendo builder de Packer para VMware</h2>



<p>Como comenté en la entrada anterior, existen builders creados por Hashicorp para la gran mayoría de plataformas de virtualización y cloud del mercado. En el caso del plugin de vSphere existe <a rel="noreferrer noopener" aria-label="VMware-iso (opens in a new tab)" href="https://www.packer.io/docs/builders/vmware-iso.html" target="_blank">VMware-iso</a>, un builder que permite la creación de imágenes a través de una ISO de sistema operativo.</p>



<p>El handicap de VMware-iso es que se conecta a través de SSH para la interacción con la plataforma, y como sabemos <strong>no siempre es adecuado tener el acceso SSH abierto a nuestra infraestructura</strong> o incluso se puede dar el caso de que no dispongamos de los permisos necesarios para habilitarlo.</p>



<p>Es por eso que yo me decanto por utilizar <a rel="noreferrer noopener" aria-label="vSphere-iso (opens in a new tab)" href="https://github.com/jetbrains-infra/packer-builder-vsphere" target="_blank">vSphere-iso</a>, un builder desarrollado por <a rel="noreferrer noopener" aria-label="Jetbrains (opens in a new tab)" href="https://www.jetbrains.com/" target="_blank">Jetbrains</a> que utiliza la API nativa de vSphere para realizar todas las operaciones contra la plataforma, por lo que lo único que necesitaremos será un <strong>usuario de vSphere con suficientes privilegios</strong> para realizar las acciones que necesitemos.</p>



<h2>Antes de empezar</h2>



<p>La única infraestrucura necesaria para seguir con esta entrada será la siguiente:</p>



<ul><li>Una <strong>infraestructura vSphere</strong> sobre la que realizar el deploy de la plantilla.</li><li>Una <strong>máquina con Packer instalado</strong>, tal como vimos en la <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://sobrebits.com/introduccion-a-la-creacion-automatica-de-plantillas-con-packer/" target="_blank">anterior entrada</a> (puede ser nuestra propia máquina sin problemas).</li><li>Un <strong>servidor DHCP</strong> en la VLAN en la que vayamos a desplegar la plantilla (Packer necesita que la plantilla tenga una IP para conectarse por WinRM después de la instalación).</li></ul>



<p>En mi caso voy a ejecutar Packer desde una máquina con CentOS 7, pero el código <strong>debería funcionar independientemente de la plataforma</strong> que ejecute Packer.</p>



<p>Para hacer todo esto más fácil he creado un <a aria-label="repositorio aquí (opens in a new tab)" href="https://github.com/mmeseguer/packer-vmware-windows">repositorio en GitHub</a> con el código que vamos a utilizar en esta entrada, por lo que en algunos archivos solo resaltaré las partes más destacadas que tendremos que editar para hacerlo funcionar. Para que el ejemplo funcione deberemos respetar la estructura de carpetas del «proyecto»:</p>


<pre class="brush: bash; title: ; notranslate">
.
├── setup
│   ├── autounattend.xml
│   ├── setup.ps1
│   └── vmtools.cmd
├── template_ws2016.json
└── vars_ws2016.json
</pre>


<p><em>¡Empecemos!</em></p>



<h2>Creando el archivo de variables</h2>



<p>Como comenté en la <a rel="noreferrer noopener" aria-label="entrada anterior (opens in a new tab)" href="https://sobrebits.com/introduccion-a-la-creacion-automatica-de-plantillas-con-packer/" target="_blank">entrada anterior</a>, podemos utilizar variables en nuestras templates que nos ayudarán a crear archivos mucho más reusables y claros. Éstas variables pueden ser definidas tanto en la propia template como en un archivo externo al que llamaremos cuando vayamos a construir nuestra plantilla. Si decidís utilizar los archivos del repositorio como base para vuestra implementación éste es el archivo que más deberéis modificar.</p>



<p>Para esta entrada utilizaremos el archivo <strong><a href="https://github.com/mmeseguer/packer-vmware-windows/blob/master/vars_ws2016.json" target="_blank" rel="noreferrer noopener" aria-label="vars_ws2016.json (opens in a new tab)">vars_ws2016.json</a></strong> que podemos encontrar en el <a rel="noreferrer noopener" aria-label="repositorio de Github de la entrada (opens in a new tab)" href="https://github.com/mmeseguer/packer-vmware-windows" target="_blank">repositorio de GitHub de la entrada</a>.</p>


<pre class="brush: plain; title: ; notranslate">
{
    &quot;vsphere_server&quot;: &quot;vcsa.sobrebits.local&quot;,
    &quot;vsphere_user&quot;: &quot;packer@vsphere.local&quot;,
    &quot;vsphere_password&quot;: &quot;Vsphere.12345&quot;,
    &quot;vsphere_template_name&quot;: &quot;Template-Windows2016&quot;,
    &quot;vsphere_folder&quot;: &quot;Templates&quot;,
    &quot;vsphere_dc_name&quot;: &quot;SobrebitsDatacenter&quot;,
    &quot;vsphere_compute_cluster&quot;: &quot;SobrebitsCluster&quot;,
    &quot;vsphere_host&quot;: &quot;esxi01.sobrebits.local&quot;,
    &quot;vsphere_portgroup_name&quot;: &quot;VM Network&quot;,
    &quot;vsphere_datastore&quot;: &quot;Datastore1&quot;,
    &quot;winadmin_password&quot;: &quot;Template.12345&quot;,
    &quot;cpu_num&quot;: &quot;2&quot;,
    &quot;mem_size&quot;: &quot;4096&quot;,
    &quot;disk_size&quot;: &quot;32768&quot;,
    &quot;os_iso_path&quot;: &quot;[Datastore1]_ISOs/Windows2016.iso&quot;,
    &quot;vmtools_iso_path&quot;:&quot;[Datastore1]_ISOs/vmtools.iso&quot;
}
</pre>


<p>He intentado que los nombres de las variables sean lo más autoexplicativos posibles, pero igualmente los repasaremos por si hay dudas:</p>



<ul><li><strong>vsphere_server:</strong> Servidor vSphere al que nos conectaremos para desplegar la plantilla.</li><li><strong>vsphere_user:</strong> Usuario con el que conectaremos a vSphere.</li><li><strong>vsphere_password:</strong> Password del usuario.</li><li><strong>vsphere_template_name:</strong> Nombre que recibirá la plantilla que creemos.</li><li><strong>vsphere_folder:</strong> Carpeta de vSphere en la que crearemos la plantilla.</li><li><strong>vsphere_dc_name:</strong> Datacenter en el que se ubicará la plantilla.</li><li><strong>vsphere_compute_cluster:</strong> Cluster en el que se ubicará la plantilla.</li><li><strong>vsphere_host:</strong> Servidor que alojará la plantilla.</li><li><strong>vsphere_portgroup_name:</strong> Red (tipo portgroup) que asociaremos a la plantilla.</li><li><strong>cpu_num:</strong> Número de CPUs con los que se creará la plantilla.</li><li><strong>mem_size:</strong> Cantidad de RAM en MB con la que se creará la plantilla.</li><li><strong>disk_size:</strong> Cantidad de disco en MB con el que se creará la plantilla.</li><li><strong>os_iso_path:</strong> Ubicación de la ISO que se montará en la plantilla para la instalación del sistema operativo (un datastore que pueda ver el servidor ESXi que ejecuta la plantilla).</li><li><strong>vmtools_iso_path: </strong>Ubicación de la ISO con las VMware Tools  (un datastore que pueda ver el servidor ESXi que ejecuta la plantilla).</li></ul>



<p>Deberemos configurar el archivo de variables para adaptarse a nuestro entorno y a las configuraciones que deseemos para nuestra plantilla. Una vez tengamos las variables definidas ya podemos pasar a diseñar la plantilla de Packer que las utilizará.</p>



<h2>Diseñando la plantilla de instalación</h2>



<p>Para construir nuestra plantilla de sistema operativo, Packer utiliza un archivo de template en formato Json en el que tenemos que ajustar todas las configuraciones que querremos para la misma. Para esta parte nos centraremos en el archivo <strong><a rel="noreferrer noopener" aria-label="template_ws2016.json (opens in a new tab)" href="https://github.com/mmeseguer/packer-vmware-windows/blob/master/template_ws2016.json" target="_blank">template_ws2016.json</a></strong> del repositorio de GitHub y veremos las distintas configuraciones a aplicar.</p>



<p>Vamos a repasar por partes el archivo:</p>


<pre class="brush: plain; title: ; notranslate">
  &quot;variables&quot;: {
    &quot;vsphere_server&quot;: &quot;&quot;,
    &quot;vsphere_user&quot;: &quot;&quot;,
    &quot;vsphere_password&quot;: &quot;&quot;,
    &quot;vsphere_template_name&quot;: &quot;&quot;,
    &quot;vsphere_folder&quot;: &quot;&quot;,
    &quot;vsphere_dc_name&quot;: &quot;&quot;,
    &quot;vsphere_compute_cluster&quot;: &quot;&quot;,
    &quot;vsphere_host&quot;: &quot;&quot;,
    &quot;vsphere_portgroup_name&quot;: &quot;&quot;,
    &quot;vsphere_datastore&quot;: &quot;&quot;,
    &quot;winadmin_password&quot;: &quot;&quot;,
    &quot;cpu_num&quot;: &quot;&quot;,
    &quot;mem_size&quot;: &quot;&quot;,
    &quot;disk_size&quot;: &quot;&quot;,
    &quot;os_iso_path&quot;: &quot;&quot;,
    &quot;vmtools_iso_path&quot;:&quot;&quot;
  },
  &quot;sensitive-variables&quot;: [&quot;vsphere_password&quot;, &quot;winadmin_password&quot;],
</pre>


<p>En el primer bloque (variables) <strong>declaramos todas las variables</strong> que hemos definido en nuestro archivo y que serán necesarias para la ejecución de la plantilla. En el segundo bloque (sensitive-variables) indicamos que <em>vsphere_password</em> y <em>winadmin_password</em> tienen contenido sensible y que <strong>no queremos que se muestren sus valores por consola</strong> en el momento de la ejecución de Packer.</p>



<p>En la entrada anterior ya hablamos de los builders, que son los encargados de conectarse con nuestra infraestructura y desplegar las plantillas. Veamos como queda nuestro builder de vSphere:</p>


<pre class="brush: plain; title: ; notranslate">
  &quot;builders&quot;: [
    {
      &quot;type&quot;: &quot;vsphere-iso&quot;,

      &quot;vcenter_server&quot;:      &quot;{{user `vsphere_server`}}&quot;,
      &quot;username&quot;:            &quot;{{user `vsphere_user`}}&quot;,
      &quot;password&quot;:            &quot;{{user `vsphere_password`}}&quot;,
      &quot;insecure_connection&quot;: &quot;true&quot;,

      &quot;vm_name&quot;: &quot;{{user `vsphere_template_name`}}&quot;,
      &quot;folder&quot; : &quot;{{user `vsphere_folder`}}&quot;,
      &quot;datacenter&quot;: &quot;{{user `vsphere_dc_name`}}&quot;,
      &quot;cluster&quot;:     &quot;{{user `vsphere_compute_cluster`}}&quot;,
      &quot;host&quot;: &quot;{{user `vsphere_host`}}&quot;,
      &quot;network&quot;: &quot;{{user `vsphere_portgroup_name`}}&quot;,
      &quot;datastore&quot;: &quot;{{user `vsphere_datastore`}}&quot;,
      &quot;convert_to_template&quot;: &quot;true&quot;,
      &quot;shutdown_command&quot;: &quot;C:/Windows/System32/Sysprep/sysprep.exe /oobe /shutdown&quot;,

      &quot;guest_os_type&quot;: &quot;windows9Server64Guest&quot;,
</pre>


<p>En esta primera parte básicamente nos dedicamos a configurar todos los aspectos relacionados con la infraestructura vSphere que ya hemos explicado en variables. Algunas cosas nuevas son:</p>



<ul><li><strong>type</strong>: Aquí hemos definido nuestro builder, que para esta entrada como hemos explicado anteriormente será <strong>vsphere-iso</strong>.</li><li><strong>insecure_connection</strong>:  Indicamos que no valide el certificado SSL de nuestro vCenter (mi experiencia me dice que la gran mayoría de infraestructuras vSphere tienen certificado autofirmado).</li><li><strong>convert_to_template</strong>: Definimos que queremos que al finalizar la construcción de la plantilla la marque como template en nuestro vCenter.</li><li><strong>shutdown_command</strong>: Indicamos que para realizar el apagado del sistema operativo al finalizar la construcción de la plantilla se ejecute sysprep para sellar la misma.</li><li><strong>guest_os_type:</strong> Establecemos el tipo de sistema operativo invitado que tendrá nuestra máquina virtual (en este caso Windows Server 2016).</li></ul>



<p>Sigamos con el archivo:</p>


<pre class="brush: plain; title: ; notranslate">
      &quot;communicator&quot;: &quot;winrm&quot;,
      &quot;winrm_username&quot;: &quot;Administrador&quot;,
      &quot;winrm_password&quot;: &quot;{{user `winadmin_password`}}&quot;,
</pre>


<p>Una vez haya finalizado la instalación, Packer deberá conectarse a la máquina virtual para aplicar las configuraciones que le indiquemos. Aquí estamos definiendo que lo haga por <strong>WinRM </strong>(tal y como vimos con <a rel="noreferrer noopener" aria-label="PowerShell Remoting (opens in a new tab)" href="https://sobrebits.com/que-es-powershell-remoting/" target="_blank">PowerShell Remoting</a>) utilizando el usuario Administrador y el password definido en nuestro archivo de variables.</p>


<pre class="brush: plain; title: ; notranslate">
      &quot;CPUs&quot;:             &quot;{{user `cpu_num`}}&quot;,
      &quot;RAM&quot;:              &quot;{{user `mem_size`}}&quot;,
      &quot;firmware&quot;: &quot;bios&quot;,

      &quot;disk_controller_type&quot;:  &quot;lsilogic-sas&quot;,
      &quot;disk_size&quot;:        &quot;{{user `disk_size`}}&quot;,
      &quot;disk_thin_provisioned&quot;: true,

      &quot;network_card&quot;: &quot;vmxnet3&quot;,

      &quot;iso_paths&quot;: [
        &quot;{{user `os_iso_path`}}&quot;,
        &quot;{{user `vmtools_iso_path`}}&quot;
      ],
</pre>


<p>Aquí definimos los recursos de la máquina así como algunas configuraciones de hardware como el tipo de tarjeta, la bios o el formato thin del disco.</p>



<p>Además indicamos las rutas de las iso que se montarán en la plantilla y que ya habíamos definido en el archivo de variables: la <strong>iso de Sistema Operativo</strong> y la <strong>iso de las VMware Tools</strong>.</p>



<p>Vamos con la última parte que veremos hoy:</p>


<pre class="brush: plain; title: ; notranslate">
      &quot;floppy_files&quot;: [
        &quot;/root/packer/test/setup/autounattend.xml&quot;,
        &quot;/root/packer/test/setup/setup.ps1&quot;,
        &quot;/root/packer/test/setup/vmtools.cmd&quot;
      ]
</pre>


<p>Aquí definimos la ubicación de los achivos que pasaremos como floppy cuyo path deberemos editar para que cuadre con la ubicación de la carpeta de nuestro proyecto. Estos archivos serán los encargados de (ahí va spoiler de la próxima entrada):</p>



<ul><li>Establecer los parámetros de configuración de la instalación de Windows.</li><li>Configuración de WinRM para la ejecución de Provisioners.</li><li>Instalar las VMware Tools.</li></ul>



<h2>Conclusión</h2>



<p>Y hasta aquí la primera parte de nuestra guía de creación de plantilla de Windows automatizada con Packer. En la próxima entrada acabaremos de descubrir las distintas partes implicadas en la instalación y configuración de nuestra plantilla y descubriremos qué más cosas podremos realizar con ésta.</p>



<p>¡Espero veros por aquí!</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/packer-para-vmware-parte-1-creacion-de-plantilla-de-windows-automatizada/">Packer para VMware (Parte 1): Creación de plantilla de Windows automatizada</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/packer-para-vmware-parte-1-creacion-de-plantilla-de-windows-automatizada/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3460</post-id>	</item>
		<item>
		<title>Introducción a la creación automática de plantillas con Packer</title>
		<link>https://sobrebits.com/introduccion-a-la-creacion-automatica-de-plantillas-con-packer/</link>
				<comments>https://sobrebits.com/introduccion-a-la-creacion-automatica-de-plantillas-con-packer/#respond</comments>
				<pubDate>Wed, 02 Oct 2019 13:16:10 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[Automatización]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[IoC]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3442</guid>
				<description><![CDATA[<p>En esta entrada conoceremos a Packer, la herramienta que nos permitirá crear y personalizar plantillas de sistema operativo de forma automática.</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/introduccion-a-la-creacion-automatica-de-plantillas-con-packer/">Introducción a la creación automática de plantillas con Packer</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>Algunas de las tareas de <a rel="noreferrer noopener" aria-label="automatización (opens in a new tab)" href="https://sobrebits.com/tag/automatizacion/" target="_blank">automatización</a> que más retorno nos pueden ofrecer (siempre y cuando trabajemos en infraestructuras con mucha generación de VMs) son las que van relacionadas con el despliegue de nuevas máquinas virtuales. En esta entrada conoceremos a <a rel="noreferrer noopener" aria-label="Packer (opens in a new tab)" href="https://www.packer.io/" target="_blank">Packer</a>, la herramienta que nos permitirá crear y personalizar plantillas de sistema operativo de forma automática en multitud de plataformas y en la que nos apoyaremos en futuras entradas para acercarnos al mundo del <a rel="noreferrer noopener" aria-label="IaC (opens in a new tab)" href="https://en.wikipedia.org/wiki/Infrastructure_as_code" target="_blank">IaC</a>.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/10/Introducción-a-la-creación-automática-de-plantillas-con-Packer.png" alt="Introducción a la creación automática de plantillas con Packer" class="wp-image-3467" data-layzr-srcset="https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/10/Introducción-a-la-creación-automática-de-plantillas-con-Packer.png?w=520&amp;ssl=1 520w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/10/Introducción-a-la-creación-automática-de-plantillas-con-Packer.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></div>



<h2>¿Qué es Packer?</h2>



<p><a rel="noreferrer noopener" aria-label="Packer (opens in a new tab)" href="https://www.packer.io" target="_blank">Packer</a> es una herramienta de software libre desarrollada por <a rel="noreferrer noopener" aria-label="Hashicorp (opens in a new tab)" href="https://www.hashicorp.com/" target="_blank">Hashicorp</a> que nos permite <strong>crear imágenes de sistema operativo de forma automatizada y utilizando archivos de configuración</strong> para tal efecto.</p>



<p>Una vez creada la configuración (que veremos en próximas entradas) Packer se conectará a la infraestructura de destino, <strong>creará la máquina virtual y aplicará todas las configuraciones</strong> que hayamos definido en nuestros archivos. Todo esto mientras nos tomamos un rico café.</p>



<p>Packer incluye la funcionalidad necesaria para trabajar con las grandes plataformas del mercado sin la necesidad de instalar ningún plugin adicional:</p>



<ul><li>Aws.</li><li>Azure.</li><li>DigitalOcean.</li><li>Docker.</li><li>Google Cloud Platform.</li><li>Hyper-V.</li><li>VMware.</li></ul>



<p><em>Podéis consultar la lista completa </em><a rel="noreferrer noopener" aria-label="aquí (opens in a new tab)" href="https://www.packer.io/docs/builders/index.html" target="_blank"><em>aquí</em></a><em>.</em></p>



<p>Además, <strong>Packer funciona con todos los grandes sistemas operativos</strong> del mercado, permitiéndonos crear imágenes de cualquiera de ellos, así como la capacidad de <strong>trabajar con las herramientas de gestión de configuración</strong> más importantes como Ansible, Chef o Puppet.</p>



<p>Si queréis más información sobre esta impresionante herramienta os recomiendo que os paséis por su <a href="https://www.packer.io/" target="_blank" rel="noreferrer noopener" aria-label="sitio web (opens in a new tab)">sitio web</a> donde disponen de muchísima información al respecto.</p>



<h2>¿Qué ventajas tiene crear plantillas con Packer?</h2>



<p>La generación automatizada de plantillas con Packer puede aportarnos muchos beneficios a nuestro flujo de trabajo:</p>



<ul><li><strong>Velocidad de aprovisionado</strong>: Con Packer nuestras plantillas pueden disponer siempre de las últimas versiones de sistema operativo y de aplicaciones, con lo que podemos desplegar una plantilla siempre lista para su uso en cuestión de segundos o pocos minutos.</li><li><strong>Consistencia</strong>: Utilizando Packer nos aseguramos de que todas las máquinas virtuales que despleguemos partirán de la misma configuración.</li><li><strong>Consistencia multiplataforma</strong>: Siguiendo con el punto anterior, con Packer podemos partir de imágenes idénticas si disponemos de entornos híbridos. En todo momento estaremos seguros que nuestra instancia de Compute Engine de GCP es identica a nuestra máquina virtual de VMware vSphere.</li><li><strong>Versionado de configuración</strong>: Tener nuestras configuraciones en archivos de texto nos permite versionarlas de forma muy sencilla, por ejemplo, con <a rel="noreferrer noopener" aria-label="Git (opens in a new tab)" href="https://sobrebits.com/como-utilizar-git-con-powershell/" target="_blank">Git</a>, con lo que siempre podremos echar la vista atrás a la hora de hacer troubleshooting de nuestras máquinas.</li></ul>



<h2>Cómo funciona Packer</h2>



<p>Packer utiliza <strong>templates en formato JSON</strong> con los que definiremos las distintas configuraciones necesarias para el despliegue, configuración y post procesado de nuestras plantillas.</p>



<p>Una template de Packer dispone de los siguientes elementos de configuración (subrayados los más importantes) para generar nuestras imágenes:</p>



<ul><li><strong><span style="text-decoration: underline;">Variables (opcional)</span></strong>: Una sección de nuestra template en la que podremos definir variables que utilizaremos posteriormente en la misma. Es opcional pero más que recomendable utilizar variables para facilitar el uso de nuestra template. Las variables pueden ser definidas en un archivo separado de nuestra template.</li><li><strong>Descripción (opcional)</strong>: Un campo en el que podemos definir qué hace nuestra template.</li><li><strong><span style="text-decoration: underline;">Builders (obligatorio)</span></strong>: En esta sección definiremos los «constructores» de nuestra plantilla, esto es, la parte encargada de conectarse con la infraestructura destino (VMware, GCP, AWS&#8230;) y que construirá la plantilla.</li><li><strong>Versión mínima de packer (opcional)</strong>: Un campo en el que definiremos la mínima versión necesaria de packer necesaria para desplegar nuestra plantilla.</li><li><strong><span style="text-decoration: underline;">Provisioners (opcional)</span></strong>: La sección donde configuraremos todo lo necesario para instalar y configurar el software del sistema operativo. Aquí tenemos la opción de hacerlo mediante scripts o con una herramienta externa de gestión de configuración.</li><li><strong><span style="text-decoration: underline;">Post processors (opcional)</span></strong>: La sección encargada de definir los pasos posteriores a la creación de la imágen, como subirla a otra infraestructura, renombrar, convertir a plantilla&#8230;</li></ul>



<h2>Cómo instalar Packer</h2>



<p>Existen distintas formas de instalar Packer, podéis consultar todas ellas en su <a rel="noreferrer noopener" aria-label="documentación (opens in a new tab)" href="https://www.packer.io/intro/getting-started/install.html" target="_blank">documentación</a>.</p>



<p>De largo la forma más sencilla es <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://www.packer.io/downloads.html" target="_blank">descargar sus binarios precompilados</a> y ubicarlos en el path de nuestro usuario. Si queremos conocer las posibles ubicaciones:</p>



<ul><li><strong>Linux / MacOS</strong>: Desde un terminal ejecutamos <strong><em>echo $PATH</em></strong>.</li><li><strong>Windows</strong>: Desde PowerShell ejecutamos <em><strong>$Env:Path</strong></em>.</li></ul>



<p>Una vez copiados los ejecutables en dichas ubicaciones deberíamos ser capaces de ejecutar desde nuestra terminal el comando <strong>packer </strong>sin problemas.</p>



<h2>Conclusión</h2>



<p>Hasta aquí esta entrada introductoria sobre Packer. En próximas entradas empezaremos a construir plantillas de sistema operativo y veremos todo el potencial que oculta esta increíble herramienta.</p>



<p>¡Nos leemos en la próxima!</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/introduccion-a-la-creacion-automatica-de-plantillas-con-packer/">Introducción a la creación automática de plantillas con Packer</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/introduccion-a-la-creacion-automatica-de-plantillas-con-packer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3442</post-id>	</item>
		<item>
		<title>Cómo ocultar la barra de progreso en PowerShell y PowerCLI</title>
		<link>https://sobrebits.com/como-ocultar-la-barra-de-progreso-en-powershell-y-powercli/</link>
				<comments>https://sobrebits.com/como-ocultar-la-barra-de-progreso-en-powershell-y-powercli/#respond</comments>
				<pubDate>Wed, 18 Sep 2019 13:29:42 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerCLI]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Variables]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3433</guid>
				<description><![CDATA[<p>En esta entrada veremos un sencillo truco para ocultar la barra de progreso en PowerShell y PowerCLI para no ensuciar nuestros archivos de log.</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/como-ocultar-la-barra-de-progreso-en-powershell-y-powercli/">Cómo ocultar la barra de progreso en PowerShell y PowerCLI</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>Cuando ejecutamos un cmdlet en PowerShell de forma interactiva y éste realiza una tarea que puede ser larga es de agradecer que el mismo muestre una barra de progreso de la ejecución del mismo para ver en qué punto estamos en todo momento. No obstante, si ejecutamos un <a rel="noreferrer noopener" aria-label="script de PowerShell de forma programada (opens in a new tab)" href="https://sobrebits.com/ejecutar-un-script-de-powershell-como-tarea-programada/" target="_blank">script de PowerShell de forma programada</a> y logeamos la salida del mismo ésto hará que se nos ensucie el archivo de log de forma innecesaria. En la entrada de hoy veremos un sencillo truco para <strong>ocultar la barra de progreso en PowerShell y PowerCLI</strong>.</p>



<ul class="wp-block-gallery aligncenter columns-1 is-cropped"><li class="blocks-gallery-item"><figure><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/09/Cómo-ocultar-la-barra-de-progreso-en-PowerShell-y-PowerCLI.png" alt="Cómo ocultar la barra de progreso en PowerShell y PowerCLI" data-id="3440" data-link="http://sobrebits.com/?attachment_id=3440" class="wp-image-3440" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/09/Cómo-ocultar-la-barra-de-progreso-en-PowerShell-y-PowerCLI.png?w=520&amp;ssl=1 520w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/09/Cómo-ocultar-la-barra-de-progreso-en-PowerShell-y-PowerCLI.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></li></ul>



<h2>$ProgressPreference, la encargada de ocultar la barra de progreso en PowerShell</h2>



<p>Muchos de los comportamientos que tiene nuestra consola de PowerShell son configurables a través de las llamadas <a rel="noreferrer noopener" aria-label="preference variables (opens in a new tab)" href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables" target="_blank">preference variables</a>. Para <strong>ocultar la barra de progreso en PowerShell</strong> podremos utilizar la variable <strong>$ProgressPreference</strong>. Si mostramos el contenido de la variable en nuestra consola deberíamos ver el estado actual de la misma:</p>


<pre class="brush: powershell; title: ; notranslate">
PS C:\&gt;$ProgressPreference
Continue
</pre>


<p>El valor por defecto de la variable es <strong>Continue</strong>, pero éstos son los valores que le podemos asignar:</p>



<ul><li><strong>Stop</strong>: Para la ejecución y muestra un error en el caso de que se vaya a utilizar una barra de progreso.</li><li><strong>Inquire</strong>: No muestra la barra de progreso y pregunta al usuario si quiere continuar.</li><li><strong>Continue</strong>: Muestra la barra de progreso y continua con la ejecución.</li><li><strong>SilentlyContinue</strong>: No muestra la barra de progreso pero continua con la ejecución.</li></ul>



<p>A decir verdad no se me ocurre la utilidad de las primeras dos opciones, no obstante la que nos interesa para esta entrada es <strong>SilentlyContinue</strong>. Ahora sí, si queremos ocultar la barra de progreso en PowerShell y PowerCLI ejecutaremos en nuestra consola:</p>


<pre class="brush: powershell; title: ; notranslate">
PS C:\&gt;$ProgressPreference = 'SilentlyContinue'
</pre>


<p>Si a posteriori ejecutamos algún cmdlet que muestre barra de progreso como, por ejemplo, <a rel="noreferrer noopener" aria-label="New-Snapshot (opens in a new tab)" href="https://www.vmware.com/support/developer/PowerCLI/PowerCLI51/html/New-Snapshot.html" target="_blank">New-Snapshot</a> de PowerCLI veremos como éste ya no muestra barra de progreso.</p>



<p>Hay que tener en cuenta que si cerramos y abrimos nuestra consola la variable volverá a coger su valor por defecto, es decir, <strong>Continue</strong>. Si queremos alterar éste comportamiento podemos añadir la línea anterior a <a rel="noreferrer noopener" aria-label="nuestro perfil de PowerShell (opens in a new tab)" href="https://sobrebits.com/como-personalizar-nuestro-perfil-de-powershell/" target="_blank">nuestro perfil de PowerShell</a> como vimos en entradas anteriores, o bien si se trata de la ejecución de un script, dar el valor deseado a la variable al principio de éste.</p>



<h2>Conclusión</h2>



<p>Si bien como decía en la introducción cuando ejecutamos una sesión interactiva ver la barra de progreso nos puede ser útil, en ejecución de scripts y sobretodo si son programados es más un estorbo que otra cosa, por lo que <strong>$ProgressPreference</strong> nos puede ayudar a tener ejecuciones más limpias de nuestros scripts.</p>



<p>Espero que os sirva.</p>



<p>¡Hasta la próxima!</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/como-ocultar-la-barra-de-progreso-en-powershell-y-powercli/">Cómo ocultar la barra de progreso en PowerShell y PowerCLI</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/como-ocultar-la-barra-de-progreso-en-powershell-y-powercli/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3433</post-id>	</item>
		<item>
		<title>Primeros pasos con PowerCLI para vCloud Director</title>
		<link>https://sobrebits.com/primeros-pasos-con-powercli-para-vcloud-director/</link>
				<comments>https://sobrebits.com/primeros-pasos-con-powercli-para-vcloud-director/#respond</comments>
				<pubDate>Thu, 12 Sep 2019 12:05:35 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[PowerCLI]]></category>
		<category><![CDATA[Virtualización]]></category>
		<category><![CDATA[Automatización]]></category>
		<category><![CDATA[vCloud Director]]></category>
		<category><![CDATA[VMware]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3408</guid>
				<description><![CDATA[<p>En esta entrada exploraremos el uso de PowerCLI para vCloud Director, una herramienta útil tanto para usuarios como administradores de la plataforma.</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/primeros-pasos-con-powercli-para-vcloud-director/">Primeros pasos con PowerCLI para vCloud Director</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>Hasta hoy cuando en este blog he hablado de <a href="https://sobrebits.com/category/powercli/">PowerCLI </a>siempre lo he hecho referente a su interacción con <a rel="noreferrer noopener" aria-label="VMware vSphere (opens in a new tab)" href="https://www.vmware.com/es/products/vsphere.html" target="_blank">VMware vSphere</a> (ESXi + vCenter), pero ni mucho menos PowerCLI se limita a ejecutar acciones únicamente contra esta plataforma. En la entrada de hoy <strong>exploraremos el uso de PowerCLI para vCloud Director</strong>, una herramienta que acostumbro a usar y que si sois usuarios o administradores de la plataforma seguro os ayuda a gestionar mejor vuestras infraestructuras.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/09/Primeros-pasos-con-PowerCLI-para-vCloud-Director.png" alt="Primeros pasos con PowerCLI para vCloud Director" class="wp-image-3430" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/09/Primeros-pasos-con-PowerCLI-para-vCloud-Director.png?w=520&amp;ssl=1 520w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/09/Primeros-pasos-con-PowerCLI-para-vCloud-Director.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></div>



<h2>¿Qué es vCloud Director?</h2>



<p>Si bien a VMware se la conoce especialmente por vSphere, ésta tiene una gran cantidad de productos la mar de interesantes en el mercado (muchas apoyadas en vSpere).</p>



<p><a rel="noreferrer noopener" aria-label="vCloud Director (opens in a new tab)" href="https://www.vmware.com/es/products/vcloud-director.html" target="_blank">vCloud Director</a> es una plataforma de VMware con la que se <strong>ofrecen las características necesarias para crear un servicio de Cloud</strong>, ya sea para que un proveedor de servicios ofrezca un servicio de Cloud público como para que un cliente final ofrezca un servicio de Cloud privado para su empresa, encima de una plataforma tan conocida como VMware vSphere.</p>



<h2>Los cmdlets de PowerCLI para vCloud Director</h2>



<p>Cuando instalamos PowerCLI en nuestra máquina con el módulo <a rel="noreferrer noopener" aria-label="VMware.PowerCLi (opens in a new tab)" href="https://www.powershellgallery.com/packages/VMware.PowerCLI/11.4.0.14413515" target="_blank">VMware.PowerCLI</a> instalamos todos estos módulos:</p>



<ul><li>Windows TerminalVMware.DeployAutomation                                                                                                 </li><li>VMware.ImageBuilder</li><li>VMware.PowerCLI</li><li>VMware.Vim</li><li>VMware.VimAutomation.Cis.Core</li><li>VMware.VimAutomation.Cloud</li><li>VMware.VimAutomation.Common</li><li>VMware.VimAutomation.Core</li><li>VMware.VimAutomation.Hcx</li><li>VMware.VimAutomation.HorizonView</li><li>VMware.VimAutomation.License</li><li>VMware.VimAutomation.Nsxt</li><li>VMware.VimAutomation.Sdk</li><li>VMware.VimAutomation.Security</li><li>VMware.VimAutomation.Srm</li><li>VMware.VimAutomation.Storage</li><li>VMware.VimAutomation.StorageUtility</li><li>VMware.VimAutomation.Vds</li><li>VMware.VimAutomation.Vmc</li><li>VMware.VimAutomation.vROps</li><li>VMware.VumAutomation</li></ul>



<p>Para interactuar con vCloud Director utilizaremos el módulo <a rel="noreferrer noopener" aria-label="VMware.VimAutomation.Cloud (opens in a new tab)" href="https://www.powershellgallery.com/packages/VMware.VimAutomation.Cloud" target="_blank">VMware.VimAutomation.Cloud</a>, cuyos cmdlets podemos listar, como siempre, con <a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/get-command" target="_blank" rel="noreferrer noopener" aria-label="Get-Command (opens in a new tab)">Get-Command</a>:</p>


<pre class="brush: powershell; title: ; notranslate">
Get-Command -Module VMware.VimAutomation.Cloud
</pre>


<h2>Utilizando PowerCLI para vCloud Director como usuario</h2>



<p>Cuando interactuamos con<strong> PowerCLI para vCloud Director</strong> en modo usuario podremos realizar tareas relacionadas con la administración de nuestras máquinas virtuales, vApps, Edge Gateways&#8230;</p>



<p>Lo primero que deberemos hacer será conectarnos a nuestra organización. Para ello utilizaremos el cmdlet <a rel="noreferrer noopener" aria-label="Connect-CIServer (opens in a new tab)" href="https://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.powercli.cmdletref.doc%2FConnect-CIServer.html" target="_blank">Connect-CIServer</a>, que tiene un uso muy similar al mítico <a href="https://www.vmware.com/support/developer/windowstoolkit/wintk40u1/html/Connect-VIServer.html" target="_blank" rel="noreferrer noopener" aria-label="Connect-VIServer (opens in a new tab)">Connect-VIServer</a>:</p>


<pre class="brush: powershell; title: ; notranslate">
# Conectamos a la infraestructura
Connect-CIServer -Server vcloud.sobrebits.com -Org sobrebits_Org

# Cuando hemos acabado las respectivas acciones desconectamos
Disconnect-CIServer -Server vcloud.sobrebits.com -Confirm:$false
</pre>


<p>Lo importante aquí es tener en cuenta que será necesario especificar siempre el parámetro <strong>-Org</strong> para entrar en modo usuario.</p>



<p>Ahora que ya tenemos conexión contra nuestra organización podemos realizar toda clase de operativa directamente desde nuestra consola favorita. Veamos algunos de los cmdlets más interesantes:</p>



<ul><li>Trabajar con nuestras vApps y VMs:</li></ul>


<pre class="brush: powershell; title: ; notranslate">
# Listar, crear, parar o eliminar vApps
Get-CIVApp
New-CIVApp
Stop-CIVApp
Remove-CIVApp

# Listar, crear, parar o eliminar VMs 
Get-CIVM
New-CIVM
Stop-CIVM
Remove-CIVM
</pre>


<ul><li>Interactuar con catálogos, plantillas y medios:</li></ul>


<pre class="brush: powershell; title: ; notranslate">
# Listar catálogos
Get-Catalog

# Listar, crear o eliminar plantillas de vApp
Get-CIVAppTemplate
New-CIVAppTemplate
Remove-CIVAppTemplate

# Listar archivos de medios
Get-Media
</pre>


<ul><li>Interactuar con nuestros firewalls virtuales y redes:</li></ul>


<pre class="brush: powershell; title: ; notranslate">
# Listar nuestros Edge Gateways
Get-EdgeGateway

# Listar, crear, modificar o eliminar Org Networks
Get-OrgVdcNetwork
New-OrgVdcNetwork
Set-OrgVdcNetwork
Remove-OrgVdcNetwork
</pre>


<h2>Utilizándolo como administrador</h2>



<p>Cuando utilizamos vCloud Director como administrador encontramos dos diferencias básicas respecto a la interacción como usuario:</p>



<ul><li>Tenemos <strong>visibilidad sobre todos los recursos</strong> de la plataforma: Esto quiere decir que si, por ejemplo, utilizamos <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://www.vmware.com/support/developer/PowerCLIforTenants/PowerCLIforTenants55/html/Get-CIVApp.html" target="_blank">Get-CIVApp</a> en este modo podremos listar las vApps de todas las organizaciones de la infraestructura.</li><li>Podremos interactuar contra <strong>elementos de la infraestructura que no son visibles</strong> para el usuario.</li></ul>



<p>Aquí van algunas de las cosas interesantes que podemos hacer:</p>


<pre class="brush: powershell; title: ; notranslate">
# Listar los detalles del Provider VDC
Get-ProviderVDC

# Listar y añadir Datastores
Get-CIDatastore
Add-CIDatastore

# Hacer búsquedas avanzadas sobre la infraestructura
Search-Cloud
Get-CIView
</pre>


<h2>Conclusión</h2>



<p>Muchas de las cosas que hemos visto sobre <a rel="noreferrer noopener" aria-label="PowerCLI en el blog (opens in a new tab)" href="https://sobrebits.com/category/powercli/" target="_blank">PowerCLI en el blog</a> pueden ser traducidas a <strong>PowerCLI para vCloud Director</strong>, espero que con esta entrada introductoria y con lo visto en anteriores entradas os ayude a llevar también la automatización a ésta plataforma. Os recomiendo que tanto si sois usuarios como administradores de la misma le deis una oportunidad.</p>



<p>¡Nos leemos en la próxima!</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/primeros-pasos-con-powercli-para-vcloud-director/">Primeros pasos con PowerCLI para vCloud Director</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/primeros-pasos-con-powercli-para-vcloud-director/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3408</post-id>	</item>
		<item>
		<title>Parar VMs con PowerCLI de forma masiva y programada</title>
		<link>https://sobrebits.com/parar-vms-con-powercli-de-forma-masiva-y-programada/</link>
				<comments>https://sobrebits.com/parar-vms-con-powercli-de-forma-masiva-y-programada/#respond</comments>
				<pubDate>Thu, 05 Sep 2019 13:04:16 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[Automatización]]></category>
		<category><![CDATA[PowerCLI]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3394</guid>
				<description><![CDATA[<p>En esta entrada veremos cómo parar VMs con PowerCLI masivamente y de forma programada como ayuda a las tareas de mantenimiento de vSphere.</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/parar-vms-con-powercli-de-forma-masiva-y-programada/">Parar VMs con PowerCLI de forma masiva y programada</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>Con PowerCLI se pueden hacer multitud de cosas contra una infraestructura vSphere. Yo partifcularmente disfruto especialmente con las que me ayudan a <strong>lograr que la infraestructura se mantenga controlada</strong> a lo largo de los meses puesto que, como he dicho muchas veces por aquí, conseguirlo se vuelve cada vez más difícil según vas sumando manos que la administren u operen con ella. En anteriores entradas hemos visto, por ejemplo, cómo controlar las <a href="https://sobrebits.com/powercli-maquinas-virtuales-sin-vmware-tools/">VMs sin VMware Tools</a> o con <a rel="noreferrer noopener" aria-label="snapshots antiguos (opens in a new tab)" href="https://sobrebits.com/listar-maquinas-virtuales-con-snapshots-antiguos-con-powercli/" target="_blank">snapshots antiguos</a>, y en la entrada de hoy veremos <strong>cómo parar VMs con PowerCLI</strong> que se supone que no deberían estar corriendo de forma perpetua.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/08/Parar-VMs-con-PowerCLI-de-forma-masiva-y-programada.png" alt="Parar VMs con PowerCLI" class="wp-image-3404" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/08/Parar-VMs-con-PowerCLI-de-forma-masiva-y-programada.png?w=520&amp;ssl=1 520w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/08/Parar-VMs-con-PowerCLI-de-forma-masiva-y-programada.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></div>



<h2>¿Por qué parar VMs con PowerCLI?</h2>



<p>Existen varios motivos por los que querríamos automatizar la parada de VMs con PowerCLI:</p>



<ul><li>Asegurarnos de que VMs no productivas no consuman los recursos de las que sí lo son.</li><li>Parar VMs que no se utilizan durante todas las franjas horarias.</li><li>Controlar el gasto de nuestra infraestructura de pago por uso generado por nuestras máquinas de test.</li></ul>



<p>En nuestro caso fue la última de las opciones la que nos hizo implementar esta medida, puesto que tenemos una <a href="https://sobrebits.com/exportar-carpetas-de-vcenter-con-powercli/" target="_blank" rel="noreferrer noopener" aria-label="carpeta de vSphere (opens in a new tab)">carpeta de vSphere</a> de test donde muy frecuentemente las <strong>máquinas quedaban encendidas después de su último uso durante semanas o meses</strong>, incurriendo en costes de licenciamiento en nuestra infraestructura absolutamente innecesarios.</p>



<h2>Cmdlets implicados</h2>



<p>Realizar esta automatización nos llevará muy pocas líneas de código. Para parar las máquinas virtuales nos valdremos de dos cmdlets de PowerCLI:</p>



<ul><li><a rel="noreferrer noopener" aria-label="Shutdown-VMGuest (opens in a new tab)" href="https://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.powercli.cmdletref.doc%2FShutdown-VMGuest.html" target="_blank">Shutdown-VMGuest</a>: Para parar máquinas virtuales con VMware Tools «de forma amigable».</li><li><a rel="noreferrer noopener" aria-label="Stop-VM (opens in a new tab)" href="https://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.powercli.cmdletref.doc%2FStop-VM.html" target="_blank">Stop-VM</a>: Para parar máquinas virtuales sin VMware Tools, en este caso de forma un poco más «agresiva».</li></ul>



<h2>Manos a la obra</h2>



<p>Ya podemos empezar a construir el script. Primero definiremos un área de configuración:</p>


<pre class="brush: powershell; title: ; notranslate">
#### Configuración ####
# Conexión a vCenter
$VcenterIp = &quot;192.168.168.168&quot;
$VcenterCreds = Import-Clixml -Path &quot;$PSScriptRoot\Credenciales\VMware.xml&quot;
# Carpetas con VMs de pruebas
$VmFolders = 'Test','Pruebas'
</pre>


<p>Nada que no hayamos hecho varias veces en entradas del blog, pero vamos a repasarlo:</p>



<ul><li><strong>Líneas 3-4</strong>: Definimos los parámetros de conexión a vCenter, IP del servidor y las credenciales tal como vimos en <a rel="noreferrer noopener" aria-label="entradas anteriores (opens in a new tab)" href="https://sobrebits.com/como-gestionar-las-credenciales-de-un-script-de-powershell/" target="_blank">entradas anteriores</a>.</li><li><strong>6</strong>: Definimos las distintas carpetas de vSphere que querremos parar.</li></ul>



<p>Y ahora podemos pasar a la acción:</p>


<pre class="brush: powershell; title: ; notranslate">
#### Cuerpo ####
# Conectamos al vCenter
Connect-VIServer -Server $VcenterIp -Credential $VcenterCreds -WarningAction SilentlyContinue | Out-Null

# Recorremos las carpetas
ForEach ($VmFolder in $VmFolders) {
    # Obtenemos las VMs encendidas
    $VMs = Get-Folder $VmFolder | Get-VM | Where-Object PowerState -eq 'PoweredOn'
    # Recorremos las VMs
    ForEach ($VM in $VMs) {
        # Obtenemos el estado de las tools
        $VmTools = $VM.ExtensionData.config.tools.toolsVersion

        # Apagamos forzosamente si no hay tools o amigablemente si sí que hay
        If ($VmTools -eq 0) {
            $VM | Stop-VM -Confirm:$false
        }
        Else {
            $VM | Shutdown-VMGuest -Confirm:$false
        }
    }
}

# Desconectamos del vCenter
Disconnect-VIServer -Confirm:$false
</pre>


<p>Aquí ya tenemos algo más que explicar:</p>



<ul><li><strong>Línea 3</strong>: Conectamos a la infraestructura vSphere con los datos de la sección de configuración.</li><li><strong>6-22</strong>: Recorremos las carpetas de VMs definidas en la sección de configuración.<ul><li><strong>8</strong>: Obtenemos todas las VMs encendidas de la carpeta.</li><li><strong>10-20</strong>: Recorremos las VMs una a una.<ul><li><strong>12</strong>: Obtenemos el <a rel="noreferrer noopener" aria-label="estado de las VMware Tools (opens in a new tab)" href="https://sobrebits.com/powercli-maquinas-virtuales-sin-vmware-tools/" target="_blank">estado de las VMware Tools</a>.</li><li><strong>15-17</strong>: Si la VM no tiene VMware Tools la paramos de forma forzosa con <a rel="noreferrer noopener" aria-label="Stop-VM (opens in a new tab)" href="https://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.powercli.cmdletref.doc%2FStop-VM.html" target="_blank">Stop-VM</a>.</li><li><strong>18-20</strong>: Si la VM sí que tiene VMware Tools la paramos de forma amigable con <a href="https://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.powercli.cmdletref.doc%2FShutdown-VMGuest.html">Shutdown-VMGuest</a>.</li></ul></li></ul></li><li><strong>25</strong>: Desconectamos de la infraestructura.</li></ul>



<p>Como siempre, <a rel="noreferrer noopener" aria-label="programaremos la ejecución del script de PowerShell (opens in a new tab)" href="https://sobrebits.com/ejecutar-un-script-de-powershell-como-tarea-programada/" target="_blank">programaremos la ejecución del script de PowerShell</a> como habitualmente y lo ajustaremos a la periodicidad con la que queremos que se apaguen las VMs, en el caso de las VMs de test <strong>nosotros las apagamos cada noche</strong>.</p>



<h2>Conclusión</h2>



<p>A partir del script que os propongo <strong>podéis realizar las modificaciones</strong> que a vosotros os vengan bien, apagando VMs concretas y no carpetas, apagando todas las VMs de un servidor&#8230; Como siempre el límite es nuestra imaginación.</p>



<p>Espero que el script os sea de ayuda. ¡Hasta la próxima!</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/parar-vms-con-powercli-de-forma-masiva-y-programada/">Parar VMs con PowerCLI de forma masiva y programada</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/parar-vms-con-powercli-de-forma-masiva-y-programada/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3394</post-id>	</item>
		<item>
		<title>Listar máquinas virtuales con snapshots antiguos con PowerCLI</title>
		<link>https://sobrebits.com/listar-maquinas-virtuales-con-snapshots-antiguos-con-powercli/</link>
				<comments>https://sobrebits.com/listar-maquinas-virtuales-con-snapshots-antiguos-con-powercli/#respond</comments>
				<pubDate>Wed, 22 May 2019 12:33:03 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[PowerCLI]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Snapshot]]></category>
		<category><![CDATA[VMware]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3342</guid>
				<description><![CDATA[<p>En esta entrada veremos cómo sacar un reporte maquinas virtuales con snapshots antiguos con PowerCLI de forma automatizada.</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/listar-maquinas-virtuales-con-snapshots-antiguos-con-powercli/">Listar máquinas virtuales con snapshots antiguos con PowerCLI</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>Como administradores de sistemas vSphere una de las cosas que siempre deberíamos tener controlada en nuestra infraestructura es <strong>la existencia de máquinas virtuales con snapshots no utilizados</strong>. Como siempre digo en esta clase de entradas, hacer esto a mano en una infraestructura pequeña con pocas manos administrándola es algo viable, pero es una solución que no escala para nada bien. Es por ello que en esta entrada veremos cómo listar <strong>maquinas virtuales con snapshots antiguos con PowerCLI</strong>.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/05/Listar-máquinas-virtuales-con-snapshots-antiguos-con-PowerCLI.png" alt="Listar máquinas virtuales con snapshots antiguos con PowerCLI" class="wp-image-3356" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/05/Listar-máquinas-virtuales-con-snapshots-antiguos-con-PowerCLI.png?w=520&amp;ssl=1 520w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/05/Listar-máquinas-virtuales-con-snapshots-antiguos-con-PowerCLI.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></div>



<h2>¿Por qué hay que eliminar snapshots antiguos en VMware?</h2>



<p>En vSphere los snapshots pueden suponer una herramenta increíblemente útil en nuestro día a día o una pesadilla dependiendo del uso que le demos. VMware facilita una serie de <a rel="noreferrer noopener" aria-label="buenas prácticas en ésta entrada (opens in a new tab)" href="https://kb.vmware.com/s/article/1025279" target="_blank">buenas prácticas en ésta entrada</a>.</p>



<p>Como indica VMware,<strong> no debereíamos tener snapshots más antiguos de 72 horas</strong> o podemos incurrir en:</p>



<ul><li>Llenado del storage por culpa de que el snapshot no para de crecer.</li><li>Bajada de rendimiento en el sistema.</li></ul>



<p><em>Yo por mi parte añadiría que eliminar un snapshot de varios cientos de GB o de más de 1TB no es la mejor de las experiencias <img src="https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f926-200d-2642-fe0f.png" alt="🤦‍♂️" class="wp-smiley" style="height: 1em; max-height: 1em;" />.</em></p>



<h2>Listando snapshots antiguos con PowerCLI</h2>



<p>Vamos a ver el pequeño script que nos ayudará a mantener a raya los snapshots antiguos con PowerCLI: </p>



<p><em><strong>Spoiler</strong>: si únicamente quieres el one-liner para obtener las VMs puedes dirigirte directamente a las líneas resaltadas del script</em></p>


<pre class="brush: powershell; highlight: [22,23]; title: ; notranslate">
#### Variables ####
# Conexión a vCenter
$VcenterIP = &quot;192.168.168.168&quot;
$VcenterCreds = Import-Clixml -Path &quot;$PSScriptRoot\Credenciales\VMware_rw.xml&quot;

# Antigüedad snapshot
$Days = 3

# Configuración del correo
$Body = &quot;Snapshots con más de $Days días: `n`n&quot;
$From = &quot;monitorizacion@sobrebits.com&quot;
$To = &quot;admin@sobrebits.com&quot;
$Subject = &quot;VMs con Snapshot anterior a $Days días&quot;
$SmtpServer = &quot;mailserver.sobrebits.com&quot;
$SmtpPort = 25

#### Cuerpo del script ####

# Conectamos al vCenter
Connect-VIServer -Server $VcenterIP -Credential $VcenterCreds -WarningAction SilentlyContinue | Out-Null

# Recuperamos todas las VMs con snapshot antiguos
$Vms = (Get-VM | Get-Snapshot | Where-Object {$_.Created -lt (Get-Date).AddDays(-$Days)}).VM.Name | Sort-Object

# Enviamos correo con el listado (en caso de que hubiera alguna VM con snapshot antiguo)
if ($Vms) {
    $Body += $Vms -join &quot;`n&quot;
    Send-MailMessage -From $From -To $To -Subject $Subject -Body $Body -SmtpServer $SmtpServer -Port $SmtpPort
}

# Desconectamos del vCenter
Disconnect-VIServer -Confirm:$false
</pre>


<p>Veamos qué hemos hecho aquí:</p>



<ul><li><strong>Líneas 3-4</strong>: Declaramos la IP y las credenciales del servidor vCenter.<ul><li>Para las credenciales utilizamos lo que vimos en la entrada: <a rel="noreferrer noopener" aria-label="Cómo gestionar las credenciales de un script de PowerShell (opens in a new tab)" href="https://sobrebits.com/como-gestionar-las-credenciales-de-un-script-de-powershell/" target="_blank">Cómo gestionar las credenciales de un script de PowerShell</a>.</li></ul></li><li><strong>7</strong>: Declaramos la cantidad de días de antigüedad del snapshot. En nuestro caso seguimos las <span style="text-decoration: underline;">buenas prácticas de VMware</span> y configuramos 3.</li><li><strong>10-15</strong>: Configuramos los parámetros para el envío de correo.<ul><li>Más sobre esto en: <a rel="noreferrer noopener" aria-label="Enviar correo desde PowerShell (opens in a new tab)" href="https://sobrebits.com/enviar-correo-desde-powershell/" target="_blank">Enviar correo desde PowerShell</a>.</li></ul></li><li><strong>20</strong>: Conectamos a vCenter.</li><li><strong>23</strong>: Aquí está la «chicha» del script, donde obtenemos todas las máquinas virtuales con snapshot anterior a 3 días:<ul><li><strong>Get-VM</strong>: Obtenemos todas las máquinas virtuales.</li><li><strong>Get-Snapshot</strong>: Obtenemos todos los snapshots de las máquinas virtuales.</li><li><strong>Where-Object {$_.Created -lt (Get-Date).AddDays(-$Days)}</strong>: Nos quedamos únicamente con los snapshots cuya fecha de creación ($_.Created) sea anterior (-lt) a la fecha actual menos 3 días ((Get-Date).AddDays(-$Days)).</li><li><strong>.VM.Name</strong>: Seleccionamos únicamente el nombre de la VM a la que pertenece dicho snapshot.</li></ul></li><li><strong>26-29</strong>: Si existen máquinas dentro de <strong>$Vms</strong> enviamos el correo con el listado de las máquinas virtuales.</li><li><strong>32</strong>: Desconectamos del vCenter.</li></ul>



<p>Resumiendo, cada vez que el script se ejecute revisará todas las máquinas vituales del entorno y <strong>revisará si contienen snapshots y si éstos son anteriores a 3 días</strong>. De existir alguno <strong>nos enviará un resumen de las máquinas virtuales</strong> afectadas directamente a nuestra bandeja de correo para que seamos nosotros mismos los que gestionemos el caso.</p>



<h2>Conclusión</h2>



<p>Si utilizamos la <a rel="noreferrer noopener" aria-label="ejecución programada de scripts de PowerShell (opens in a new tab)" href="https://sobrebits.com/ejecutar-un-script-de-powershell-como-tarea-programada/" target="_blank">ejecución programada de scripts de PowerShell</a> para realizar este check de forma diaria nos vamos a asegurar de tener siempre controlada la existencia de snapshots antiguos con PowerCLI, con lo que tendremos una infraestructura más optimizada.</p>



<p>Para los más atrevidos, podríamos modificar el script para que, en vez de enviar un correo, ejecutara <a rel="noreferrer noopener" aria-label="Remove-Snapshot (opens in a new tab)" href="https://pubs.vmware.com/vsphere-6-0/index.jsp?topic=%2Fcom.vmware.powercli.cmdletref.doc%2FRemove-Snapshot.html" target="_blank">Remove-Snapshot</a> para eliminar directamente sin preguntar los snapshots antiguos.</p>



<p>¡Nos leemos en la próxima!</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/listar-maquinas-virtuales-con-snapshots-antiguos-con-powercli/">Listar máquinas virtuales con snapshots antiguos con PowerCLI</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/listar-maquinas-virtuales-con-snapshots-antiguos-con-powercli/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3342</post-id>	</item>
		<item>
		<title>Active Directory: Gestionar permisos de OU con PowerShell</title>
		<link>https://sobrebits.com/active-directory-gestionar-permisos-de-ou-con-powershell/</link>
				<comments>https://sobrebits.com/active-directory-gestionar-permisos-de-ou-con-powershell/#respond</comments>
				<pubDate>Thu, 02 May 2019 12:27:02 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[Automatización]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[Permisos]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Seguridad]]></category>
		<category><![CDATA[Unidades Organizativas]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3314</guid>
				<description><![CDATA[<p>En esta entrada veremos cómo gestionar permisos de OU con PowerShell, un proceso algo más complicado de lo que nos podríamos imaginar al ponernos a ello.</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/active-directory-gestionar-permisos-de-ou-con-powershell/">Active Directory: Gestionar permisos de OU con PowerShell</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>Si gestionáis un entorno de Active Directory <em>«multitenant»</em> o un directorio muy grande, es posible que más pronto que tarde os toque editar los permisos de las Unidades Organizativas para aseguraros de que no todo el mundo puede verlo todo. En la entrada de hoy veremos <strong>cómo gestionar permisos de OU con PowerShell</strong>, un proceso algo más complicado de lo que nos podríamos imaginar al ponernos a ello.</p>



<p>Para ver las distintas funciones que podemos realizar de una forma práctica en esta entrada crearemos un script que:</p>



<ul><li> Crea una OU con PowerShell.</li><li>Rompe la herencia de la OU.</li><li>Elimina los permisos autogenerados en dicha OU.</li><li>Añade permisos personalizados. </li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/05/Active-Directory_-Gestionar-permisos-de-OU-con-PowerShell.png" alt="Active Directory: Gestionar permisos de OU con PowerShell" class="wp-image-3338" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/05/Active-Directory_-Gestionar-permisos-de-OU-con-PowerShell.png?w=520&amp;ssl=1 520w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/05/Active-Directory_-Gestionar-permisos-de-OU-con-PowerShell.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></div>



<h2>Antes de empezar</h2>



<p>Para entender mejor el contenido de esta entrada es conveniente que tengas <strong>una base sobre cómo funcionan los permisos en Windows</strong> y, específicamente, sobre los permisos en Active Directory. Durante la entrada me referiré a dos terminos de forma constante:</p>



<ul><li><a href="https://msdn.microsoft.com/library/windows/desktop/ms721532#-security-access-control-list-gly">ACL</a>: La Access Control List, es decir, la lista de permisos completa que está asociada al objeto (en esta entrada a una OU).</li><li><a href="https://docs.microsoft.com/en-us/windows/desktop/secauthz/access-control-entries">ACE</a>: La Access Control Entry, es decir, un permiso conceto dentro de la ACL.</li></ul>



<p>¡Con esto dicho ya podemos empezar!</p>



<h2>Crear Unidad Organizativa con PowerShell</h2>



<p>Para poder hacer nuestras pruebas de modificación de permisos de OU con PowerShell lo primero que necesitaremos será una OU de prueba que, como no, crearemos con PowerShell. </p>



<p><em>Como siempre os recomiendo que hagáis siempre vuestros desarrollos sobre un </em><a rel="noreferrer noopener" aria-label="entorno de prueba (opens in a new tab)" href="https://sobrebits.com/como-crear-un-entorno-de-prueba-para-powercli-con-govcsim/" target="_blank"><em>entorno de prueba</em></a><em> ya que es muy fácil que acabemos liando una gorda, y nadie quiere recrear permisos a mano sobre un árbol de Active Directory.</em><br></p>


<pre class="brush: powershell; title: ; notranslate">
# Definimos el path donde crear nuestra OU de prueba
$OuPath = 'DC=sobrebits,DC=local'

# Creamos la OU &quot;OUTest&quot; en la ubicación definida
New-ADOrganizationalUnit -Name 'OUTest' -Path $OuPath
</pre>


<p>En primer lugar hemos definido <strong>el path de la OU</strong> que vamos a crear con PowerShell. Después utilizamos <a rel="noreferrer noopener" aria-label="New-ADOrganizationalUnit (opens in a new tab)" href="https://docs.microsoft.com/en-us/powershell/module/addsadministration/new-adorganizationalunit" target="_blank">New-ADOrganizationalUnit</a> para crear una OU con el nombre <em>OUTest</em>.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/05/imagen-1.png" alt="Crear OU con PowerShell" class="wp-image-3322" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-1.png?w=362&amp;ssl=1 362w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-1.png?resize=300%2C239&amp;ssl=1 300w" sizes="(max-width: 362px) 100vw, 362px" /></figure></div>



<h2>Romper la herencia de OU con PowerShell</h2>



<p>Ahora que tenemos nuestra Unidad Organizativa creada es momento de trastear con sus permisos. Justo después de crear la OU podemos ver como existen multitud de permisos heredados del nivel superior:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/05/imagen-2.png" alt="Permisos de OU heredados" class="wp-image-3323" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-2.png?w=748&amp;ssl=1 748w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-2.png?resize=300%2C178&amp;ssl=1 300w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Lo primero que haremos para asegurarnos de que podemos juguetear con todos ellos será <strong>romper la herencia de permisos</strong> de OU:</p>


<pre class="brush: powershell; title: ; notranslate">
# Generamos el Path completo de la OU creada
$OuPath = &quot;OU=OUTest,$OuPath&quot;

# Obtenemos las ACL de nuestra OU
$Acl = Get-Acl &quot;AD:\\$OuPath&quot;

# Rompemos la herencia preservando las ACLs heredadas
$Acl.SetAccessRuleProtection($True,$True)

# Escribimos la ACL en la OU
Set-Acl &quot;AD:\\$OuPath&quot; -AclObject $Acl
</pre>


<p>Lo que hemos hecho ha sido obtener un objeto que representa todas las entradas de permisos de nuestra OU, lo hemos modificado para que deje de heredar permisos (copiando los que ya tenía heredados) y escribiendo éste objeto modificado en la ACL de la OU. Veamos línea a línea cómo lo hemos hecho:</p>



<ul><li><strong>Línea 2</strong>: Construimos el path completo de la OU que acabamos de generar para operar con ella en futuras líneas mediante <strong>$OuPath</strong>.</li><li><strong>5</strong>: Utilizamos el cmdlet <a rel="noreferrer noopener" aria-label="Get-Acl (opens in a new tab)" href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/get-acl" target="_blank">Get-Acl</a> para obtener los permisos (ACL) de la OU de Active Directory.<ul><li><strong>AD:\\</strong> es un <a rel="noreferrer noopener" aria-label="PSDrive (opens in a new tab)" href="https://docs.microsoft.com/es-es/powershell/scripting/samples/managing-windows-powershell-drives?view=powershell-6" target="_blank">PSDrive</a> que apunta a la raíz del directorio.</li></ul></li><li><strong>8</strong>: Utilizamos el método <a href="https://docs.microsoft.com/es-es/dotnet/api/system.security.accesscontrol.objectsecurity.setaccessruleprotection?view=netframework-4.8">SetAccessRuleProtection</a> de nuestro objeto de ACL (<a href="https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectorysecurity?view=netframework-4.8">System.DirectoryServices.ActiveDirectorySecurity</a>) con el que podemos modificar el comportamiento de la heréncia.</li><li><strong>11</strong>: Con <a rel="noreferrer noopener" aria-label="Set-Acl (opens in a new tab)" href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-acl" target="_blank">Set-Acl</a> escribimos la ACL modificada en el comando anterior utilizando el parámetro <strong>-AclObject</strong> junto con el objeto modificado.</li></ul>



<p>Si comprobamos ahora los permisos de nuestra OU de prueba veremos como tiene los mismos permisos que anteriormente pero éstos ya no son heredados del nivel superior:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/05/imagen-3.png" alt="Romper herencia de OU con PowerShell" class="wp-image-3326" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-3.png?w=748&amp;ssl=1 748w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-3.png?resize=300%2C178&amp;ssl=1 300w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<h2>Eliminar permisos de OU con PowerShell</h2>



<p>Lo siguiente que vamos a ver será cómo eliminar estos permisos. El procedimiento es muy parecido: obtenemos la ACL actual, eliminamos los permisos (ACE) uno a uno del objeto y escribimos nuestra ACL modificada en la OU:</p>


<pre class="brush: powershell; title: ; notranslate">
# Volvemos a obtener las ACLs de nuestra OU
$Acl = Get-ACL &quot;AD:\\$OuPath&quot;

# Recorremos las ACLs y las eliminamos una a una
ForEach ($Ace in $Acl.Access) {
        $Acl.RemoveAccessRule($Ace) | Out-Null
    }

# Escribimos la ACL de nuevo en nuestra OU
Set-Acl &quot;AD:\\$OuPath&quot; -AclObject $Acl
</pre>


<p>Veamos paso por paso:</p>



<ul><li><strong>Línea 2</strong>: Obtenemos las ACL de la OU de nuevo.<ul><li>Debemos tener en cuenta que tras cada modificación de los permisos de la OU deberemos «refrescar» nuestro objeto <strong>$Acl</strong> para que tenga la versión actualizada de los permisos.</li></ul></li><li><strong>5</strong>: Recorremos todas las ACL contenidas en la propiedad <em>«Access»</em> de nuestro objeto <strong>$Acl</strong>.<ul><li><strong>6</strong>: Utilizamos el método <strong>RemoveAccessRule</strong> del objeto $Acl para eliminar la ACE.</li></ul></li><li> <strong>10</strong>: Con <a rel="noreferrer noopener" href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-acl" target="_blank">Set-Acl</a> escribimos la ACL modificada en el comando anterior utilizando el parámetro <strong>-AclObject</strong> junto con el objeto modificado. </li></ul>



<p>Después de eso, si volvemos a revisar los permisos de la OU veremos como no existe ninguno:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/05/imagen-4.png" alt="Eliminar permisos de OU con PowerShell" class="wp-image-3328" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-4.png?w=749&amp;ssl=1 749w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-4.png?resize=300%2C179&amp;ssl=1 300w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<h2>Añadir permisos de OU con PowerShell</h2>



<p>Con nuestra ACL limpia llega el momento de añadir permisos a la Unidad Organizativa. Esta es quizás la parte más compleja, puesto que deberemos construir a mano un objeto <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://docs.microsoft.com/es-es/dotnet/api/system.directoryservices.activedirectoryaccessrule" target="_blank">ActiveDirectoryAccessRule</a>, es decir, deberemos crear la ACE de forma manual. Vamos a ver cómo sería la cosa:</p>


<pre class="brush: powershell; title: ; notranslate">
# Volvemos a obtener las ACLs de nuestra OU
$Acl = Get-ACL &quot;AD:\\$OuPath&quot;

# Construimos la ACE para el usuario Marc
$User = (Get-ADUser 'Marc')
$Sid = [System.Security.Principal.SecurityIdentifier]$User.Sid
$Identity = [System.Security.Principal.IdentityReference]$Sid
$Rights = [System.DirectoryServices.ActiveDirectoryRights]&quot;GenericRead&quot;
$Type = [System.Security.AccessControl.AccessControlType]&quot;Allow&quot;
$Inheritance = [System.DirectoryServices.ActiveDirectorySecurityInheritance]&quot;All&quot;
$Ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity,$Rights,$Type,$Inheritance

# Añadimos la ACE a la ACL
$Acl.AddAccessRule($Ace)

# Escribimos la ACL de nuevo en nuestra OU
Set-Acl &quot;AD:\\$OuPath&quot; -AclObject $Acl
</pre>


<p>Repasemos paso por paso:</p>



<ul><li><strong>Línea 2</strong>:  Obtenemos las ACL de la OU de nuevo. </li><li><strong>5-10</strong>: Obtenemos todas las propiedades que necesitamos para construir nuestro objeto <a rel="noreferrer noopener" href="https://docs.microsoft.com/es-es/dotnet/api/system.directoryservices.activedirectoryaccessrule" target="_blank">ActiveDirectoryAccessRule</a>.<ul><li><strong>5</strong>: Obtenemos el usuario a añadir en la ACE.</li><li><strong>6</strong>: Sacamos el <a rel="noreferrer noopener" aria-label="SID (opens in a new tab)" href="https://docs.microsoft.com/es-es/dotnet/api/system.security.principal.securityidentifier" target="_blank">SID</a> (identificador de seguridad) del usuario.</li><li><strong>7</strong>: Mediante el SID obtenemos el <a rel="noreferrer noopener" aria-label="identificador del usuario (opens in a new tab)" href="https://docs.microsoft.com/es-es/dotnet/api/system.security.principal.identityreference" target="_blank">identificador del usuario</a>, necesario para construir el objeto.</li><li><strong>8</strong>: Creamos un <a rel="noreferrer noopener" aria-label="objeto de permisos (opens in a new tab)" href="https://docs.microsoft.com/es-es/dotnet/api/system.directoryservices.activedirectoryrights" target="_blank">objeto de permisos</a> de Active Directory con permisos de lectura. Podéis obtener todos los valores disponibles <a rel="noreferrer noopener" aria-label="objeto de permisos (opens in a new tab)" href="https://docs.microsoft.com/es-es/dotnet/api/system.directoryservices.activedirectoryrights" target="_blank">aquí</a>.</li><li><strong>9</strong>: Determinamos el <a rel="noreferrer noopener" aria-label="tipo de permiso (opens in a new tab)" href="https://docs.microsoft.com/es-es/dotnet/api/system.security.accesscontrol.accesscontroltype" target="_blank">tipo de permiso</a> en «permitir».</li><li><strong>10</strong>: Aplicamos la <a rel="noreferrer noopener" aria-label="herencia de permisos (opens in a new tab)" href="http://System.DirectoryServices.ActiveDirectorySecurityInheritance" target="_blank">herencia de permisos</a> a todos los objetos «descendientes».</li></ul></li><li><strong>11</strong>: Mediante las propiedades definidas en el bloque anterior creamos un nuevo objeto de ACE mediante <a rel="noreferrer noopener" aria-label="New-Object (opens in a new tab)" href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-object" target="_blank">New-Object</a>.</li><li><strong>14</strong>: Añadimos la ACE generada a la ACL que hemos obtenido en la línea 2.</li><li><strong>17</strong>:  Con <a rel="noreferrer noopener" href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-acl" target="_blank">Set-Acl</a> escribimos la ACL modificada en el comando anterior utilizando el parámetro <strong>-AclObject</strong> junto con el objeto modificado.</li></ul>



<p>Si ahora vemos la ACL de la OU podemos ver como se ha añadido la entrada:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/05/imagen-5.png" alt="Añadir permisos de OU con PowerShell" class="wp-image-3334" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-5.png?w=750&amp;ssl=1 750w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/05/imagen-5.png?resize=300%2C178&amp;ssl=1 300w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>A partir de aquí, si queremos añadir más permisos a la ACL únicamente tendremos que generar tantas ACE como sea preciso y añadirlas a nuestra ACL mediante <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-acl" target="_blank">Set-Acl</a>.</p>



<p>El resultado final del script sería este:</p>


<pre class="brush: powershell; title: ; notranslate">
# Definimos el path donde crear nuestra OU de prueba
$OuPath = 'DC=sobrebits,DC=local'

# Creamos la OU &quot;OUTest&quot; en la ubicación definida
New-ADOrganizationalUnit -Name 'OUTest' -Path $OuPath

# Generamos el Path completo de la OU creada
$OuPath = &quot;OU=OUTest,$OuPath&quot;

# Obtenemos las ACL de nuestra OU
$Acl = Get-Acl &quot;AD:\\$OuPath&quot;

# Rompemos la herencia preservando las ACLs heredadas
$Acl.SetAccessRuleProtection($True,$True)

# Escribimos la ACL en la OU
Set-Acl &quot;AD:\\$OuPath&quot; -AclObject $Acl

# Volvemos a obtener las ACLs de nuestra OU
$Acl = Get-ACL &quot;AD:\\$OuPath&quot;

# Recorremos las ACLs y las eliminamos una a una
ForEach ($Ace in $Acl.Access) {
        $Acl.RemoveAccessRule($Ace) | Out-Null
    }

# Escribimos la ACL de nuevo en nuestra OU
Set-Acl &quot;AD:\\$OuPath&quot; -AclObject $Acl

# Volvemos a obtener las ACLs de nuestra OU
$Acl = Get-ACL &quot;AD:\\$OuPath&quot;

# Construimos la ACE para el usuario Marc
$User = (Get-ADUser 'Marc')
$Sid = [System.Security.Principal.SecurityIdentifier]$User.Sid
$Identity = [System.Security.Principal.IdentityReference]$Sid
$Rights = [System.DirectoryServices.ActiveDirectoryRights]&quot;GenericRead&quot;
$Type = [System.Security.AccessControl.AccessControlType]&quot;Allow&quot;
$Inheritance = [System.DirectoryServices.ActiveDirectorySecurityInheritance]&quot;All&quot;
$Ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity,$Rights,$Type,$Inheritance

# Añadimos la ACE a la ACL
$Acl.AddAccessRule($Ace)

# Escribimos la ACL de nuevo en nuestra OU
Set-Acl &quot;AD:\\$OuPath&quot; -AclObject $Acl
</pre>


<h2>Bola extra: Copiar los permisos de una OU a otra con PowerShell</h2>



<p>Es posible que después de este último punto hayas pensado que escribir una ACL compleja puede hacer que te quede un script extremadamente largo <em>(algo que muchas veces se ve como algo bueno cuando no debería serlo)</em>, y razón no te falta. Un truco si vas a estar recreando los mismos permisos muchas veces es el siguiente:</p>



<ul><li>Creas una OU y le asignas permisos que necesites a mano (no siempre hay que hacerlo todo desde la línea de comandos).</li><li>Haces que el script copie esos permisos en tu nueva OU.</li></ul>



<p>Lo mejor de éste método es que lo puedes implementar en dos líneas:</p>


<pre class="brush: powershell; title: ; notranslate">
# Obtenemos las ACL de la OU plantilla
$Acl = Get-ACL &quot;AD:\\OU=PlantillaPermisos,DC=sobrebits,DC=local&quot;

# Escribimos la ACL en la nueva OU
Set-Acl &quot;AD:\\$OuPath&quot; -AclObject $Acl
</pre>


<h2>Conclusión</h2>



<p>Mediante esta forma de asignación de permisos en OUs con PowerShell podremos automatizar un paso más en nuestros procesos de creación de usuarios, algo que puede ahorrarnos una gran cantidad de horas.</p>



<p>¡Espero que os sea útil!<br></p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/active-directory-gestionar-permisos-de-ou-con-powershell/">Active Directory: Gestionar permisos de OU con PowerShell</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/active-directory-gestionar-permisos-de-ou-con-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3314</post-id>	</item>
		<item>
		<title>Serverless y PS &#8211; Ejecutar PowerShell en Azure Functions</title>
		<link>https://sobrebits.com/serverless-y-ps-ejecutar-powershell-en-azure-functions/</link>
				<comments>https://sobrebits.com/serverless-y-ps-ejecutar-powershell-en-azure-functions/#respond</comments>
				<pubDate>Wed, 24 Apr 2019 13:05:48 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Azure Functions]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Serverless]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3267</guid>
				<description><![CDATA[<p>En esta entrada de veremos cómo ejecutar PowerShell en Azure Functions, la plataforma serverless de Microsoft.</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/serverless-y-ps-ejecutar-powershell-en-azure-functions/">Serverless y PS &#8211; Ejecutar PowerShell en Azure Functions</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>Sin duda la palabra <em>serverless</em> (una palabra un poco controvertida) está pegando fuerte en los últimos tiempos y parece que ha llegado para quedarse. Si bien este concepto está muy ligado a la parte del desarrollo, desde de sistemas también podemos sacarle mucho jugo. En la entrada de hoy veremos <strong>cómo ejecutar PowerShell en Azure Functions</strong>, la plataforma <em>serverless</em> de Microsoft.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/Ejecutar-PowerShell-en-Azure-Functions.png" alt="Ejecutar PowerShell en Azure Functions" class="wp-image-3308" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/Ejecutar-PowerShell-en-Azure-Functions.png?w=520&amp;ssl=1 520w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/Ejecutar-PowerShell-en-Azure-Functions.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></div>



<h2>Conociendo serverless y Azure Functions</h2>



<p>Antes de empezar con el how-to propiamente dicho creo que es importante que tengamos clara la base de todo esto.</p>



<p><strong>Serverless</strong> es el <em>«palabro»</em> elegido por la industria para definir un servicio en el que <strong>el desarrollador se desentiende del servidor donde se ejecuta su código</strong>. En un servicio serverless el desarrollador simplemente copia su código y el proveedor de servicios es el encargado de aprovisionar la infraestructura necesaria para que éste funcione, escale y se mantenga disponible. </p>



<p>No me gusta particularmente la palabra serverless pues puede llevar al error de pensar que realmente no existe un <em>«servidor»</em> que ejecute el código. Lo que nos tiene que quedar claro es que éste no desaparece, sino que <strong>pasa a ser transparente para el usuario</strong>.</p>



<p><a href="https://azure.microsoft.com/es-es/services/functions/">Azure Functions</a> es el servicio serverless de Microsoft, un servicio que nos va a permitir ejecutar funciones o scripts de PowerShell en «la nube» de forma muy sencilla sin tener que desplegar un servidor para ello.</p>



<h2>Creando la Azure Function</h2>



<p>Ahora que ya conocemos un poco más de serverless y de las Azure Functions vamos a explorar un poco el servicio creando una función de prueba.</p>



<h5>Accediendo a Azure</h5>



<p>Lo primero que deberemos hacer para empezar con Azure Functions será entrar en nuestra cuenta de <a href="https://azure.microsoft.com/es-es/">Azure</a>. Si no dispones de una puedes crearla de forma gratuita desde <a rel="noreferrer noopener" aria-label="su página web (opens in a new tab)" href="https://azure.microsoft.com/es-es/" target="_blank">su página web</a>. Con tu nueva cuenta dispondrás de:</p>



<ul><li>12 meses de algunos servicios de forma gratuita.</li><li>170€ de crédito para usar con cualquier servicio.</li><li>Muchos servicios de forma gratuita siempre.</li></ul>



<p>En nuestro caso con Azure Functions nos valdremos de su <a rel="noreferrer noopener" aria-label="tier gratuito (opens in a new tab)" href="https://azure.microsoft.com/en-us/pricing/details/functions/" target="_blank">tier gratuito</a>, que es más que suficiente para hacer toda clase de pruebas con él.</p>



<h5>Creando nuestra primera Azure Function App</h5>



<p>Una vez logeados en nuestra cuenta de Azure podemos proceder a crear nuestra Azure Function App (el contenedor que hospedará nuestras funciones). Para ello nos dirigiremos a su respectivo apartado en el menú lateral izquierdo:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen.png" alt="Function App en Azure" class="wp-image-3279" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen.png?w=764&amp;ssl=1 764w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen.png?resize=300%2C140&amp;ssl=1 300w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Posteriormente pulsaremos sobre el botón Crear Function App y rellenaremos sus campos:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-1-1024x703.png" alt="Configuración de Function App" class="wp-image-3280" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-1.png?resize=1024%2C703&amp;ssl=1 1024w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-1.png?resize=300%2C206&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-1.png?resize=768%2C527&amp;ssl=1 768w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-1.png?w=1079&amp;ssl=1 1079w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Repasemos los campos configurados:</p>



<ul><li><strong>Nombre de la aplicación</strong>: El nombre de la aplicación, que a su vez definirá la URL de la misma.</li><li><strong>Suscripción</strong>: Seleccionar cuál de nuestros planes de suscripción utilizaremos. Como esta es una cuenta nueva utilizamos la Evaluación gratuita.</li><li><strong>Grupo de recursos</strong>: Dejamos que nos genere un nuevo grupo de recursos para la aplicación (más sobre los grupos de recursos <a rel="noreferrer noopener" aria-label="aquí (opens in a new tab)" href="https://docs.microsoft.com/es-es/azure/azure-resource-manager/resource-group-overview#resource-groups" target="_blank">aquí</a>).</li><li><strong>OS</strong>: Seleccionamos Windows.</li><li><strong>Plan de hospedaje</strong>: Dejamos marcado plan de consumo para utilizar el pago por ejecución <em>(no vamos a pagar nada puesto que utilizaremos el <a rel="noreferrer noopener" aria-label="tier gratuito (opens in a new tab)" href="https://azure.microsoft.com/en-us/pricing/details/functions/" target="_blank">tier gratuito</a>)</em>.</li><li><strong>Ubicación</strong>: Seleccionamos una ubicación cercana a nosotros.</li><li><strong>Pila de tiempo de ejecución</strong>: Elegimos .NET para ejecutar PowerShell.</li><li><strong>Storage</strong>: Marcamos la creación de un storage nuevo para nuestra aplicación.</li></ul>



<p>Después de rellenar los campos pulsaremos sobre el botón <strong>Crear</strong> y esperaremos hasta que la aplicación se cree. Una vez creada deberíamos ver algo así en el apartado Function App:</p>



<figure class="wp-block-image"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-2-1024x204.png" alt="Function App creada" class="wp-image-3282" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-2.png?resize=1024%2C204&amp;ssl=1 1024w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-2.png?resize=300%2C60&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-2.png?resize=768%2C153&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-2.png?w=1434&amp;ssl=1 1434w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-2.png?w=1360 1360w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<p>Por último, antes de pasar a crear la función en si, deberemos <strong>cambiar a la versión 1</strong> el runtime de nuestra Funcion App, puesto que <a rel="noreferrer noopener" aria-label="la versión 2 no lo soporta (opens in a new tab)" href="https://docs.microsoft.com/es-es/azure/azure-functions/functions-versions#languages" target="_blank">la versión 2 no soporta la ejecución de PowerShell</a>. Para ello pincharemos sobre el nombre de nuestra Function App y posteriormente en <strong>Configuración de Function App</strong>.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-3-1024x557.png" alt="Configuración de Function App" class="wp-image-3285" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-3.png?resize=1024%2C557&amp;ssl=1 1024w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-3.png?resize=300%2C163&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-3.png?resize=768%2C418&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-3.png?w=1205&amp;ssl=1 1205w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Y en <strong>Versión en tiempo de ejecución</strong> marcaremos <strong>~1</strong>.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-4-1024x459.png" alt="Versión de Function App" class="wp-image-3286" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-4.png?resize=1024%2C459&amp;ssl=1 1024w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-4.png?resize=300%2C135&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-4.png?resize=768%2C345&amp;ssl=1 768w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-4.png?w=1090&amp;ssl=1 1090w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<h5 id="mce_10">Creando nuestra función de PowerShell en Azure Functions</h5>



<p>Ahora que tenemos el entorno de ejecución creado y configurado podemos pasar a crear la función en si. Para ello pincharemos sobre el botón <strong>+</strong> de al lado de <strong>Funciones</strong> y posteriormente pulsaremos sobre <strong>Crear su propia función personalizada</strong>.</p>



<figure class="wp-block-image"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-5-1024x439.png" alt="Crear nueva Azure Function" class="wp-image-3290" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-5.png?resize=1024%2C439&amp;ssl=1 1024w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-5.png?resize=300%2C128&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-5.png?resize=768%2C329&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-5.png?w=1408&amp;ssl=1 1408w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<p>En Elegir una plantilla a continuación:</p>



<ul><li>Habilitamos la <strong>Compatibilidad de lenguaje experimental</strong> para poder utilizar PowerShell. <em>(PowerShell en Azure Functions se encuentra en estado experimental, por lo que no se deberían poner cargas críticas en éste servicio)</em></li><li>Seleccionamos <strong>HTTP trigger</strong> como modo de ejecución de nuestra función para esta prueba.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-7-1024x339.png" alt="Configuración de Azure Function" class="wp-image-3292" data-layzr-srcset="https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-7.png?resize=1024%2C339&amp;ssl=1 1024w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-7.png?resize=300%2C99&amp;ssl=1 300w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-7.png?resize=768%2C254&amp;ssl=1 768w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-7.png?w=1558&amp;ssl=1 1558w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-7.png?w=1360 1360w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>En el menú de creación de la función seleccionamos PowerShell como lenguaje y le damos nombre a la función.</p>



<div class="wp-block-image"><figure class="aligncenter is-resized"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-8.png" alt="Configuración de Azure Function 2" class="wp-image-3293" width="269" height="363" data-layzr-srcset="https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-8.png?w=492&amp;ssl=1 492w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-8.png?resize=222%2C300&amp;ssl=1 222w" sizes="(max-width: 269px) 100vw, 269px" /></figure></div>



<p>Una vez finalizada la creación ya deberíamos ver nuestra flamante nueva función de prueba:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-9-1024x500.png" alt="Azure Function creada" class="wp-image-3296" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-9.png?resize=1024%2C500&amp;ssl=1 1024w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-9.png?resize=300%2C146&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-9.png?resize=768%2C375&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-9.png?w=1155&amp;ssl=1 1155w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<h2>Entendiendo el script de prueba</h2>



<p>El script de prueba que se nos proporciona nos puede ayudar a entender de una forma fácil algunas de las <strong>particularidades de la ejecución de PowerShell en Azure Functions</strong>. </p>



<p>Básicamente lo que hace este pequeño script será buscar un parámetro Name en nuestra petición (tanto si es GET como si es POST) y devolvernos un string con <em>Hello <strong>$name</strong></em>. Vamos a examinarlo:</p>


<pre class="brush: powershell; title: ; notranslate">
# POST method: $req
$requestBody = Get-Content $req -Raw | ConvertFrom-Json
$name = $requestBody.name

# GET method: each querystring parameter is its own variable
if ($req_query_name) 
{
    $name = $req_query_name 
}

Out-File -Encoding Ascii -FilePath $res -inputObject &quot;Hello $name&quot;
</pre>


<ul><li><strong>Líneas 1-3</strong>: Parte del script orientada a <strong>peticiones POST</strong>.<ul><li><strong>2</strong>: Obtenemos el cuerpo de la petición contenido en la variable <strong>$req</strong> y lo convertimos de json a un objeto. En Azure Functions el cuerpo de la petición POST siempre vendrá contenido en esta variable.</li><li><strong>3</strong>: Obtenemos la propiedad name de la petición.</li></ul></li><li><strong>Líneas 5-9</strong>: Parte del script orientada a <strong>peticiones GET</strong>.<ul><li><strong>6</strong>: Determinamos si existe la variable <strong>$req_query_name</strong>. <ul><li>En Azure Functions las propiedades que pasemos mediante GET generan una <strong>variable automática</strong> $req_query_nombrepropiedad. Esto quiere decir que si lanzamos una query con una propiedad «blog» ésta será accesible en nuestro script con $req_query_blog.</li></ul></li><li><strong>8</strong>: De existir la variable la almacenamos en <strong>$name</strong> para posteriormente devolverla en nuestra string.</li></ul></li><li><strong>Línea 11</strong>: Devolvemos nuestra string añadiendo su contenido al archivo de salida ubicado en la ruta de la variable <strong>$res</strong>.<ul><li>En Azure Functions <strong>$res</strong> es una variable especial que apunta al archivo utilizado para la salida de nuestra función.</li></ul></li></ul>



<p>Todo esto puede parecer muchas cosas a tener en cuenta pero básicamente hablamos de 3:</p>



<ul><li>Si queremos procesar <strong>solicitudes POST nos valdremos de $req</strong> para obtener los parámetros.</li><li>En caso de querer procesar <strong>solicitudes GET nos valdremos de $req_query_nombredelparametro</strong> para obtener el parámetro.</li><li>Siempre devolveremos el resultado de nuestro script mediante <strong>$res</strong>.</li></ul>



<h2>Ejecutando PowerShell en Azure Functions<br></h2>



<p>Por último, ahora que ya tenemos nuestra Function App y nuestra función de PowerShell podemos probarla. Para ello nos valdremos de <a rel="noreferrer noopener" aria-label="Invoke-RestMethod (opens in a new tab)" href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod" target="_blank">Invoke-RestMethod</a>, el cmdlet de referencia para <strong>interactuar con APIs REST desde PowerShell</strong>.</p>



<p>El primer paso será <strong>obtener la URI completa</strong> desde la que invocar nuestra función. Desde la vista de nuestra función pulsaremos sobre <strong>&lt;/&gt; Obtener la dirección URL de la función</strong>:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-10.png" alt="URI de la función" class="wp-image-3302" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-10.png?w=977&amp;ssl=1 977w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-10.png?resize=300%2C135&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-10.png?resize=768%2C346&amp;ssl=1 768w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Una vez copiada lo primero que haremos será guardarla en una variable:</p>


<pre class="brush: powershell; title: ; notranslate">
$Funcion = &quot;https://sobrebitstest.azurewebsites.net/api/PSSobrebits?code=dKFWt5Ew...&quot;
</pre>


<p>Y ahora vamos a hacer algunas consultas sobre ella:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/imagen-11.png" alt="Invocar script de PowerShell en Azure Functions" class="wp-image-3305" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-11.png?w=558&amp;ssl=1 558w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/imagen-11.png?resize=300%2C63&amp;ssl=1 300w" sizes="(max-width: 558px) 100vw, 558px" /></figure></div>



<p>Repasemos el resultado de los comandos:</p>



<ul><li>En la primera ejecución no añadimos a la URI ningún parámetro, con lo que nuestro script no puede concatenar ningún nombre a «Hello».</li><li>En la segunda ejecución añadimos un nombre a la petición añadiéndolo a la URI y, esta vez sí, se concatena a «Hello».</li><li>En la tercera ejecución vemos como para este script el funcionamiento es el mismo tanto con POST como con GET.</li></ul>



<h2>Resumen</h2>



<p>En la entrada de hoy hemos podido ver como sin desplegar ningún tipo de servidor tenemos <strong>código de PowerShell ejecutándose bajo demanda en Azure</strong>. Los usos que le podemos dar son muchos y en próximas entradas espero traeros alguno.</p>



<p>Os invito a que exploréis esta forma de ejecutar PowerShell puesto que abre un abanico inmenso de posibilidades y, sin duda, es una forma sencilla de acercarnos al serverless desde una tecnología que todos conocemos.</p>



<p>¡Nos leemos pronto!</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/serverless-y-ps-ejecutar-powershell-en-azure-functions/">Serverless y PS &#8211; Ejecutar PowerShell en Azure Functions</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/serverless-y-ps-ejecutar-powershell-en-azure-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3267</post-id>	</item>
		<item>
		<title>Cómo utilizar Git con PowerShell (Parte 2): Git en Visual Studio Code</title>
		<link>https://sobrebits.com/git-en-visual-studio-code/</link>
				<comments>https://sobrebits.com/git-en-visual-studio-code/#respond</comments>
				<pubDate>Wed, 03 Apr 2019 13:53:47 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Visual Studio Code]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3228</guid>
				<description><![CDATA[<p>En esta entrada veremos cómo configurar y utilizar Git en Visual Studio Code orientado al desarrollo de scripts en PowerShell.</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/git-en-visual-studio-code/">Cómo utilizar Git con PowerShell (Parte 2): Git en Visual Studio Code</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>En la primera parte de esta entrada vimos <a rel="noreferrer noopener" aria-label="cómo utilizar Git con PowerShell (opens in a new tab)" href="https://sobrebits.com/como-utilizar-git-con-powershell/" target="_blank">cómo utilizar Git con PowerShell</a> mediante el uso del fantástico módulo <a rel="noreferrer noopener" aria-label="posh-git (opens in a new tab)" href="https://github.com/dahlbyk/posh-git" target="_blank">posh-git</a>. Si bien esta forma de utilizar Git nos puede resultar muy útil en muchos casos, la realidad es que cuando más necesitaremos el uso de un control de versiones será cuando estemos <strong>realizando nuestros desarrollos en un editor</strong>. Es por eso que en esta segunda parte nos centraremos en el <strong>uso de Git en Visual Studio Code</strong> que, con permiso de PowerShell ISE, es el editor por excelencia de PowerShell.</p>



<ul><li><a rel="noreferrer noopener" aria-label="Cómo utilizar Git con PowerShell (Parte 1): posh-git (opens in a new tab)" href="https://sobrebits.com/como-utilizar-git-con-powershell/" target="_blank">Cómo utilizar Git con PowerShell (Parte 1): posh-git</a>.</li><li><em>Cómo utilizar Git con PowerShell (Parte 2): Git en Visual Studio Code.</em></li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/04/Git-con-PowerShell-parte-2_-Git-en-Visual-Studio-Code.png" alt="Git con PowerShell: Git en Visual Studio Code" class="wp-image-3264" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/Git-con-PowerShell-parte-2_-Git-en-Visual-Studio-Code.png?w=520&amp;ssl=1 520w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/04/Git-con-PowerShell-parte-2_-Git-en-Visual-Studio-Code.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></div>



<h2>Qué necesitas antes de empezar</h2>



<p>Como ni el <a rel="noreferrer noopener" aria-label="uso de Visual Studio Code en PowerShell (opens in a new tab)" href="https://sobrebits.com/primeros-pasos-con-visual-studio-code-para-powershell/" target="_blank">uso de Visual Studio Code en PowerShell</a> es la primera vez que aparece en este blog ni evidentemente el <a href="https://sobrebits.com/como-utilizar-git-con-powershell/">uso de Git en PowerShell</a> tampoco, reciclaremos parte de lo visto en éstas entradas para sentar las bases de ésta (sería un poco incoherente que me gustara tanto la automatización y repetir el mismo trabajo en cada entrada, ¿no?). </p>



<p>Para continuar necesitaremos:</p>



<ul><li>Una <a rel="noreferrer noopener" aria-label="instalación de Visual Studio Code (opens in a new tab)" href="https://sobrebits.com/primeros-pasos-con-visual-studio-code-para-powershell/" target="_blank">instalación de Visual Studio Code</a> con el complemento de PowerShell instalado (ésto último si queremos resaltado de sintaxis para PowerShell).</li><li>Una <a rel="noreferrer noopener" aria-label="instalación de Git para Windows (opens in a new tab)" href="https://sobrebits.com/como-utilizar-git-con-powershell/" target="_blank">instalación de Git para Windows</a> (no es necesario el módulo posh-git).</li></ul>



<h2>Inicializando un repositorio de Git desde Visual Studio Code</h2>



<p>Tal y como hicimos en la primera parte lo primero que deberemos hacer será <strong>crear nuestro repositorio de código</strong> para empezar a juguetear con Git. </p>



<p>Lo primero que haremos será crear la carpeta de nuestro <em>&#8216;proyecto&#8217;</em>:</p>



<ul><li>Abrimos Visual Studio Code.</li><li>Nos dirigimos a <strong>Explorer</strong> y pulsamos en <strong>Open Folder</strong>.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-18-1024x273.png" alt="Abrir una carpeta en Visual Studio Code" class="wp-image-3232" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-18.png?resize=1024%2C273&amp;ssl=1 1024w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-18.png?resize=300%2C80&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-18.png?resize=768%2C205&amp;ssl=1 768w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-18.png?w=1046&amp;ssl=1 1046w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<ul><li>Creamos la carpeta y pulsamos en <strong>Seleccionar carpeta</strong>.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-19.png" alt="Abrir área de trabajo en VSCode" class="wp-image-3233" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-19.png?w=940&amp;ssl=1 940w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-19.png?resize=300%2C227&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-19.png?resize=768%2C580&amp;ssl=1 768w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Como podemos ver nuestra ventana de trabajo de Visual Studio Code ha cambiado ligeramente:</p>



<ul><li>En la parte superior aparece el nombre del área de trabajo (Sobrebits-VSCode-Git).</li><li>Y en el explorador también vemos el área de trabajo sin archivos dentro.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-20-1024x245.png" alt="Área de trabajo en VSCode" class="wp-image-3234" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-20.png?resize=1024%2C245&amp;ssl=1 1024w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-20.png?resize=300%2C72&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-20.png?resize=768%2C183&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-20.png?w=1193&amp;ssl=1 1193w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Con nuestra área de trabajo abierta podemos dirigirnos a <strong>Source Control</strong>, que debería indicar que no hay proveedores de control de código registrados:</p>



<div class="wp-block-image"><figure class="aligncenter is-resized"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-21.png" alt="Source Control en Visual Studio Code" class="wp-image-3235" width="461" height="153" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-21.png?w=841&amp;ssl=1 841w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-21.png?resize=300%2C100&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-21.png?resize=768%2C256&amp;ssl=1 768w" sizes="(max-width: 461px) 100vw, 461px" /></figure></div>



<p>Ésto puede inducir a error ya que parece indicar que no disponemos de Git en nuestra máquina, pero lo que realmente indica es que nuestro repositorio no está inicializado. Para inicializarlo deberemos:</p>



<ul><li>Pulsar sobre el botón con el logo de Git al lado de <strong>SOURCE CONTROL</strong>.</li><li>Lo que abrirá la paleta de comandos en la que <strong>seleccionaremos nuestra área de trabajo</strong>.</li></ul>



<figure class="wp-block-image"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-22.png?fit=680%2C107&amp;ssl=1" alt="" class="wp-image-3237" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-22.png?w=1195&amp;ssl=1 1195w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-22.png?resize=300%2C47&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-22.png?resize=768%2C121&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-22.png?resize=1024%2C161&amp;ssl=1 1024w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<p>Después de ello podremos ver como el error ha desaparecido y ya empezamos a disponer de <strong>opciones relacionadas con Git</strong> en Visual Studio Code:</p>



<div class="wp-block-image"><figure class="aligncenter is-resized"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="https://sobrebits.com/wp-content/uploads/2019/03/imagen-23.png" alt="" class="wp-image-3239" width="395" height="188" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-23.png?w=570&amp;ssl=1 570w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-23.png?resize=300%2C143&amp;ssl=1 300w" sizes="(max-width: 395px) 100vw, 395px" /></figure></div>



<h2>Utilizando Git en Visual Studio Code</h2>



<p>Ahora sí que ya lo tenemos todo listo para empezar utilizar Git desde nuestro editor. Para probar ésta funcionalidad haremos lo siguiente en nuestro recién creado repositorio:</p>



<ul><li>Añadir un archivo.</li><li>Realizar un commit del mismo. </li><li>Crear una nueva rama.</li><li></li><li>Hacer un merge de la rama a master.</li></ul>



<h5>Añadir un archivo</h5>



<p>Lo primero que haremos en el repositorio será crear un archivo para que tenga contenido. Para ello:</p>



<ul><li>Nos dirigimos a <strong>Explorer</strong>.</li><li>Pulsamos sobre el botón <strong>New File</strong>.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-26.png" alt="Crear archivo en Git con VSCode" class="wp-image-3245" data-layzr-srcset="https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-26.png?w=1017&amp;ssl=1 1017w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-26.png?resize=300%2C82&amp;ssl=1 300w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-26.png?resize=768%2C211&amp;ssl=1 768w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<ul><li>Damos nombre al archivo y pulsamos Enter.</li></ul>



<h5>Realizar un commit</h5>



<p>Después de crear nuestro archivo podemos ver varias cosas interesantes:</p>



<figure class="wp-block-image"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-27.png?fit=680%2C175&amp;ssl=1" alt="" class="wp-image-3246" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-27.png?w=1047&amp;ssl=1 1047w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-27.png?resize=300%2C77&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-27.png?resize=768%2C197&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-27.png?resize=1024%2C263&amp;ssl=1 1024w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<ul><li>El nombre del archivo aparece en color verde y con una U a su derecha.</li><li>El icono de <strong>Source Control</strong> tiene un 1.</li></ul>



<p>Lo que se nos está indicando es que existe un archivo en estado <em>&#8216;untracked&#8217;</em> (la U) y que hay un cambio pendiente (el 1).</p>



<p>Antes de realizar nuestro commit deberemos poner nuestro archivo en estado tracked, es decir, bajo el <a rel="noreferrer noopener" aria-label="rastreo de Git (opens in a new tab)" href="https://git-scm.com/book/es/v2/Fundamentos-de-Git-Guardando-cambios-en-el-Repositorio" target="_blank">rastreo de Git</a>:</p>



<ul><li>Pulsamos sobre el icono de <strong>Source Control</strong>.</li><li>Hacemos clic sobre el icono <em>&#8216;+&#8217;</em> al lado del nombre, lo que <strong>añadirá el archivo a nuestra staging area</strong>.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-28-1024x276.png" alt="Añadir archivo a staging con VSCode" class="wp-image-3247" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-28.png?resize=1024%2C276&amp;ssl=1 1024w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-28.png?resize=300%2C81&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-28.png?resize=768%2C207&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-28.png?w=1048&amp;ssl=1 1048w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>El archivo ahora pasará al apartado de <strong>STAGED CHANGES</strong>, indicando que nuestro archivo está preparado para ser commiteado.</p>



<p>Para crear nuestro primer commit lo único que deberemos hacer será rellenar el mensaje del commit y pulsar sobre el check de encima del campo de texto:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-29-1024x261.png" alt="Commit en Visual Studio Code" class="wp-image-3251" data-layzr-srcset="https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-29.png?resize=1024%2C261&amp;ssl=1 1024w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-29.png?resize=300%2C77&amp;ssl=1 300w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-29.png?resize=768%2C196&amp;ssl=1 768w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-29.png?w=1047&amp;ssl=1 1047w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Después de realizar el commit la interfaz vuelve a mostrarse como antes de añadir el archivo, indicando que <strong>no hay cambios pendientes</strong>.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-30-1024x259.png" alt="Interfaz después del primer commit." class="wp-image-3252" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-30.png?resize=1024%2C259&amp;ssl=1 1024w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-30.png?resize=300%2C76&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-30.png?resize=768%2C195&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-30.png?w=1046&amp;ssl=1 1046w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<h5>Crear una nueva rama</h5>



<p>Para crear una nueva rama utilizaremos la <a rel="noreferrer noopener" aria-label="paleta de comandos (opens in a new tab)" href="https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette" target="_blank">paleta de comandos</a>, una de las funcionalidades más importantes de Visual Studio Code. Desde ella podemos acceder a toda la funcionalidad del editor.</p>



<ul><li>Abrimos la paleta de comandos de una de estas formas:<ul><li>View &gt; Command Palette.</li><li>Con la combinación de teclas Ctrl+Shift+P.</li></ul></li><li>Escribimos en la paleta <em>&#8216;git branch&#8217;</em> para mostrar todas las opciones relacionadas con las ramas de git.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-24.png" alt="Crear rama Git en Visual Studio Code" class="wp-image-3243" data-layzr-srcset="https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-24.png?w=947&amp;ssl=1 947w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-24.png?resize=300%2C88&amp;ssl=1 300w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-24.png?resize=768%2C225&amp;ssl=1 768w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<ul><li>Seleccionamos <strong>Git: Create Branch&#8230;</strong></li><li>Escribimos el nombre de la rama y pulsamos Enter.</li><li></li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-25.png" alt="Nombre de rama Git en Visual Studio Code" class="wp-image-3244" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-25.png?w=944&amp;ssl=1 944w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-25.png?resize=300%2C62&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-25.png?resize=768%2C158&amp;ssl=1 768w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<ul><li>Seleccionamos el puntero HEAD que nos indica la rama actual.</li></ul>



<p>Después de esto nuestra rama ya estará creada y nosotros estaremos situados en ella. En la esquina inferior izquierda podremos ver sobre la rama que nos encontramos:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-31.png" alt="Rama actual en VSCode" class="wp-image-3254" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-31.png?w=905&amp;ssl=1 905w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-31.png?resize=300%2C55&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-31.png?resize=768%2C141&amp;ssl=1 768w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Si pulsamos sobre el nombre de la misma aparecerá en nuestra paleta de comandos las ramas existentes y la posibilidad de cambiar entre ellas:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-32.png" alt="Ramas disponibles en VSCode" class="wp-image-3255" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-32.png?w=943&amp;ssl=1 943w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-32.png?resize=300%2C67&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-32.png?resize=768%2C173&amp;ssl=1 768w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<h5>Hacer merge de una rama a master</h5>



<p>Por último vamos a realizar un merge de nuestra rama a master. Para ello lo primero que haremos será realizar algún cambio en la rama:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-33-1024x221.png" alt="Archivo modificado en VSCode con Git" class="wp-image-3256" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-33.png?resize=1024%2C221&amp;ssl=1 1024w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-33.png?resize=300%2C65&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-33.png?resize=768%2C166&amp;ssl=1 768w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-33.png?w=1233&amp;ssl=1 1233w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Como vemos ahora tanto el color como la letra al lado del nombre del archivo han cambiado. Lo que nos están mostrando en esta ocasión es que el archivo ha sido modificado.</p>



<p>Añadimos la modificación a la staging area y realizamos un commit igual que lo hemos hecho en nuestro primer commit.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-34-1024x228.png" alt="Commit en nueva rama en VSCode" class="wp-image-3257" data-layzr-srcset="https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-34.png?resize=1024%2C228&amp;ssl=1 1024w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-34.png?resize=300%2C67&amp;ssl=1 300w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-34.png?resize=768%2C171&amp;ssl=1 768w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-34.png?w=1217&amp;ssl=1 1217w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Con nuestra modificación ya hecha podemos pasar a realizar el merge:</p>



<ul><li>Cambiamos a la rama master.</li><li>Abrimos la paleta de comandos de una de estas formas:<ul><li>View &gt; Command Palette.</li><li>Con la combinación de teclas Ctrl+Shift+P. </li></ul></li><li>Escribimos git merge y seleccionamos la opción: <strong>Git: Merge Branch&#8230;</strong></li><li>Seleccionamos la rama que hemos creado como origen del merge.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-35-1024x183.png" alt="Rama desde la que realizar merge" class="wp-image-3258" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-35.png?resize=1024%2C183&amp;ssl=1 1024w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-35.png?resize=300%2C54&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-35.png?resize=768%2C137&amp;ssl=1 768w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-35.png?w=1064&amp;ssl=1 1064w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Después de esto podemos ver como los cambios realizados en nuestro archivo en la rama Test-git ya aparecen en la rama master:</p>



<figure class="wp-block-image"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-36.png?fit=680%2C570&amp;ssl=1" alt="" class="wp-image-3259" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-36.png?w=1212&amp;ssl=1 1212w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-36.png?resize=300%2C251&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-36.png?resize=768%2C644&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-36.png?resize=1024%2C858&amp;ssl=1 1024w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-36.png?resize=70%2C60&amp;ssl=1 70w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<h2>Conclusión</h2>



<p>Y hasta aquí esta entrada doble en la que hemos podido ver dos de las <strong>mejores formas de disfrutar de Git en PowerShell</strong>. Sin duda la opción que hemos visto en esta entrada es la más sencilla de las dos, puesto que Visual Studio Code nos abstrae de los comandos de Git para centrarnos simplemente en producir.</p>



<p>Mi recomendación es que si no estáis utilizando ya Git para vuestros desarrollos de PowerShell <strong>lo empecéis a utilizar cuanto antes</strong>, te cambia la forma de desarrollar para bien.</p>



<p>¡Nos vemos en la próxima</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/git-en-visual-studio-code/">Cómo utilizar Git con PowerShell (Parte 2): Git en Visual Studio Code</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/git-en-visual-studio-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3228</post-id>	</item>
		<item>
		<title>Cómo utilizar Git con PowerShell (Parte 1): posh-git</title>
		<link>https://sobrebits.com/como-utilizar-git-con-powershell/</link>
				<comments>https://sobrebits.com/como-utilizar-git-con-powershell/#respond</comments>
				<pubDate>Wed, 27 Mar 2019 15:30:34 +0000</pubDate>
		<dc:creator><![CDATA[Marc Meseguer]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Descubriendo módulos]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://sobrebits.com/?p=3174</guid>
				<description><![CDATA[<p>Una de las mejores ideas que podemos tener cuando empezamos a pasar de utilizar PowerShell únicamente como consola de comandos y scripting básico a desarrollos algo más serios es involucrar una herramienta de control de versiones en la ecuación. Sin duda la herramienta de control de versiones de código más extendida en la actualidad es Git, por lo que en la entrada de hoy vamos a ver de qué manera podemos utilizar Git con PowerShell para nuestros desarrollos. Antes de empezar&#8230; En esta entrada voy a suponer que ya dispones de cierta base acerca del funcionamiento de Git. De no </p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/como-utilizar-git-con-powershell/">Cómo utilizar Git con PowerShell (Parte 1): posh-git</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></description>
								<content:encoded><![CDATA[
<p>Una de las mejores ideas que podemos tener cuando empezamos a pasar de utilizar PowerShell únicamente como consola de comandos y scripting básico a desarrollos algo más serios es <strong>involucrar una herramienta de control de versiones</strong> en la ecuación. Sin duda la herramienta de control de versiones de código más extendida en la actualidad es Git, por lo que en la entrada de hoy vamos a ver de qué manera podemos <strong>utilizar Git con PowerShell para nuestros desarrollos</strong>.</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/Git-con-PowerShell-parte-1_-posh-git.png" alt="Git con PowerShell: posh-git" class="wp-image-3223" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/Git-con-PowerShell-parte-1_-posh-git.png?w=520&amp;ssl=1 520w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/Git-con-PowerShell-parte-1_-posh-git.png?resize=300%2C133&amp;ssl=1 300w" sizes="(max-width: 520px) 100vw, 520px" /></figure></div>



<h2>Antes de empezar&#8230;</h2>



<p>En esta entrada voy a suponer que ya dispones de cierta base acerca del funcionamiento de Git. De no ser así te recomiendo que <strong>antes de entrar en la parte práctica te empapes un poco del funcionamiento de Git</strong>, existen multitud de recursos tanto online como offline para ello. Te aseguro que cada minuto que emplees en ello será un minuto aprovechado.</p>



<h2>Insalar Git en Windows</h2>



<p>Sea cual sea la forma en la que queramos consumir <strong>Git en PowerShell</strong> lo primero que deberemos hacer será instalar el cliente de <a rel="noreferrer noopener" aria-label="Git para Windows (opens in a new tab)" href="https://git-scm.com/download/win" target="_blank">Git para Windows</a>. Para ello descargaremos la aplicación con nuestro navegador <a rel="noreferrer noopener" aria-label="Git para Windows (opens in a new tab)" href="https://git-scm.com/download/win" target="_blank">desde ésta URL</a>.</p>



<p>La instalación básicamente es un <em>siguiente &gt; siguiente</em>, pero vamos a verla paso por paso por si nos interesa cambiar algo:</p>



<ul><li><strong>Information</strong>: Aceptamos los terminos y condiciones.</li><li><strong>Select destionation location</strong>: Elegimos la ruta de instalación del cliente.</li><li><strong>Select components</strong>: Para una instalación básica dejamos los componentes marcados por defecto.<ul><li>Si no queremos añadir entradas en el menú del explorador podemos desmarcar las opciones de <em>Windows Explorer integration</em>.</li><li>Puede resultar interesante marcar el checkeo automático de las actualizaciones para mantener Git siempre al día.</li></ul></li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-7.png" alt="Elegir componentes de Git" class="wp-image-3178" data-layzr-srcset="https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-7.png?w=748&amp;ssl=1 748w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-7.png?resize=300%2C226&amp;ssl=1 300w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-7.png?resize=320%2C240&amp;ssl=1 320w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<ul><li><strong>Select Start Menu Folder</strong>: Dejamos por defecto.</li><li><strong>Choosing the default editor used by Git</strong>: Aquí podemos elegir el editor que utilizará Git por defecto. Yo siempre utilizo Vim puesto que es el que utilizo en GNU/Linux, pero tenemos multitud de opciones a nuestra disposición:</li></ul>



<figure class="wp-block-image"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-8.png" alt="Elegir editor de Git" class="wp-image-3179" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-8.png?w=748&amp;ssl=1 748w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-8.png?resize=300%2C226&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-8.png?resize=320%2C240&amp;ssl=1 320w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<ul><li><strong>Adjusting your PATH environment</strong>: Aquí podemos empezar a ver algo de PowerShell en la opción por defecto. Dejando la opción por defecto nos permitirá invocar comandos de Git desde Git Bash (la consola por defecto de Git) así como en cmd o nuestra querida PowerShell.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-9.png" alt="Path de Git en Windows" class="wp-image-3180" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-9.png?w=748&amp;ssl=1 748w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-9.png?resize=300%2C226&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-9.png?resize=320%2C240&amp;ssl=1 320w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<ul><li><strong>Choosing HTTPS transport backend</strong>: Aquí podemos elegir la opción que pefiramos. Si en vez de marcar la opción por defecto marcamos la segunda utilizaremos nuestro almacén de certificados de Windows y podremos validar contra las CA root de nuestro dominio. A gusto del consumidor.</li><li><strong>Configuring the line ending conversions</strong>: Dejamos la opción por defecto puesto que será la que nos asegurará mayor compatibilidad si realizamos desarrollos multiplataforma en los saltos de línea (para poder utilizar PowerShell Core para GNU/Linux sin problema).</li><li><strong>Configuring the terminal emulator to use with Git Bash</strong>: Dejamos la opción por defecto puesto que nos dejará redimensionarla sin problemas en versiones anteriores a Windows 10. No es una opción que nos interese mucho puesto que la idea es utilizar la propia PowerShell con Git.</li><li><strong>Configuring extra options</strong>: Otra vez podemos dejar los settings por defecto para una instalación básica.</li></ul>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-10.png" alt="Instalación finalizada de Git para Windows" class="wp-image-3182" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-10.png?w=748&amp;ssl=1 748w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-10.png?resize=300%2C226&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-10.png?resize=320%2C240&amp;ssl=1 320w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<p>Como podéis ver es un instalador con muchas pantallas pero que si no deseamos ningún tipo de personalización podremos pasar a base de siguientes.</p>



<p>Ahora que ya tenemos la instalación finalizada podríamos abri la consola Git bash para empezar a trabajar con Git:</p>



<div class="wp-block-image"><figure class="aligncenter"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-11.png" alt="Git bash para Windows" class="wp-image-3186" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-11.png?w=910&amp;ssl=1 910w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-11.png?resize=300%2C174&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-11.png?resize=768%2C446&amp;ssl=1 768w" sizes="(max-width: 680px) 100vw, 680px" /></figure></div>



<h2>Instalación de posh-git</h2>



<p>Ahora que ya tenemos el requisito fundamental para trabajar en Git con PowerShell nos falta el módulo que va a complementar la consola para convertirla en una herramienta completa para el uso de Git. El módulo es <a rel="noreferrer noopener" aria-label="posh-git (opens in a new tab)" href="https://github.com/dahlbyk/posh-git" target="_blank">posh-git</a>, un módulo muy popular que podemos encontrar <a rel="noreferrer noopener" aria-label="dentro de la PowerShell Gallery (opens in a new tab)" href="https://www.powershellgallery.com/packages/posh-git" target="_blank">dentro de la PowerShell Gallery</a>, y que nos ofrece la siguiente funcionalidad:</p>



<ul><li>Personalización del prompt al más puro estilo Git en el que podemos ver <strong>la rama en la que nos encontramos y los cambios realizados</strong> en la misma.</li><li><strong>Autocompletado de comandos de Git</strong> así como de nombres de las ramas.</li></ul>



<p>Para instalar el módulo como siempre nos valdremos de <a href="https://docs.microsoft.com/en-us/powershell/module/powershellget/install-module" target="_blank" rel="noreferrer noopener" aria-label="Install-Module (opens in a new tab)">Install-Module</a>:</p>


<pre class="brush: powershell; title: ; notranslate">
Install-Module posh-git -Scope CurrentUser -Force
</pre>


<p>Una vez instalado el módulo lo importaremos con <strong>Import-Module</strong> o utilizaremos la función <strong>Add-PoshGitToProfile</strong> que añadirá dicho Import-Module a nuestro <a rel="noreferrer noopener" aria-label="perfil de PowerShell (opens in a new tab)" href="https://sobrebits.com/como-personalizar-nuestro-perfil-de-powershell/" target="_blank">perfil de PowerShell</a></p>


<pre class="brush: powershell; title: ; notranslate">
# Opción 1: Importamos manualmente el módulo
Import-Module posh-git

# Opción 2: Modificamos nuestro perfil de PowerShell para que cargue automáticamente 
# (cerramos y abrimos la consola para que cargue el módulo)
Add-PoshToGitProfile
</pre>


<h2>Utilizando Git con PowerShell mediante posh-git </h2>



<p>Con <a rel="noreferrer noopener" aria-label="posh-git (opens in a new tab)" href="https://github.com/dahlbyk/posh-git" target="_blank">posh-git</a> ya instalado y cargado podemos empezar a trastear con Git. Para probar su funcionamiento vamos a hacer lo siguiente:</p>



<ul><li>Crear una nueva carpeta (nuestro «proyecto»).</li><li>Inicializar un repositorio de git en ella.</li><li>Añadir un archivo.</li><li>Realizar un commit.</li></ul>



<p>Antes de empezar configuraremos en Git nuestro correo y nuestro email (algo necesario para poder realizar nuestros commits):</p>


<pre class="brush: powershell; title: ; notranslate">
C:\Scripts&gt; git config --global user.email &quot;marc@sobrebits.com&quot;
C:\Scripts&gt; git config --global user.name &quot;Marc&quot;
</pre>


<p>Con esto hecho podemos empezar con los primeros dos puntos:</p>



<figure class="wp-block-image"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-16.png" alt="Inicializando un repositorio con posh-git" class="wp-image-3208" data-layzr-srcset="https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-16.png?w=999&amp;ssl=1 999w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-16.png?resize=300%2C113&amp;ssl=1 300w, https://i2.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-16.png?resize=768%2C289&amp;ssl=1 768w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<p></p>



<p>En esta captura vemos un par de cosas interesantes:</p>



<ul><li><strong>Los comandos de Git están disponibles en PowerShell</strong> gracias a la configuración del instalador en la pantalla <em>«Adjusting your path environment»</em>.</li><li>Una vez inicializado el repositorio nuestro prompt cambia <strong>indicando la rama en la que estamos</strong> (master) así como el título de la ventana que <strong>nos indica tanto el repositorio (Sobrebits-Git) como la rama</strong>.</li></ul>



<p>Si ahora creamos un nuevo archivo en el repositorio veremos nuevos cambios en nuestro prompt:</p>



<figure class="wp-block-image"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-15-1024x252.png" alt="Nuevo archivo en posh-git" class="wp-image-3206" data-layzr-srcset="https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-15.png?resize=1024%2C252&amp;ssl=1 1024w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-15.png?resize=300%2C74&amp;ssl=1 300w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-15.png?resize=768%2C189&amp;ssl=1 768w, https://i0.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-15.png?w=1071&amp;ssl=1 1071w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<p>Como podemos observar han aparecido unos números en rojo que nos vienen a indicar unas cuantas cosas:</p>



<ul><li><strong>+1</strong>: Se ha creado un archivo nuevo en el repositorio.</li><li><strong>~0</strong>: No se ha modificado ningún archivo.</li><li><strong>-0</strong>: No se ha eliminado ningún archivo.</li><li><strong>!</strong>: Existen archivos en el repositorio no trackeados.</li></ul>



<p>Por último vamos a añadir nuestro nuevo archivo a la staging area y a crear nuestro primer commit:</p>



<figure class="wp-block-image"><img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-layzr="http://sobrebits.com/wp-content/uploads/2019/03/imagen-17-1024x131.png" alt="Primer commit con git-posh" class="wp-image-3211" data-layzr-srcset="https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-17.png?resize=1024%2C131&amp;ssl=1 1024w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-17.png?resize=300%2C39&amp;ssl=1 300w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-17.png?resize=768%2C99&amp;ssl=1 768w, https://i1.wp.com/sobrebits.com/wp-content/uploads/2019/03/imagen-17.png?w=1083&amp;ssl=1 1083w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<ul><li>Al añadir nuestro nuevo archivo a la staging area vemos como la <em>«!»</em> del final se cambia por una <em>«~»</em>, que nos indica que <strong>tenemos archivos pendientes de ser </strong><em><strong>commiteados</strong></em>.</li><li>Al hacer commit el prompt vuelve a su estado original.</li></ul>



<p>Para más información sobre los cambios en el prompt te recomiendo que revises el <a href="https://github.com/dahlbyk/posh-git" target="_blank" rel="noreferrer noopener" aria-label="README.md del proyecto en GitHub (opens in a new tab)">README.md del proyecto en GitHub</a>.</p>



<h2>Conclusión</h2>



<p>Con posh-git disponemos de la capacidad de usar<strong> Git con PowerShell sin depender de otras terminales</strong> en las que realizar nuestras operaciones de versionado.</p>



<p>En la segunda parte veremos <strong>cómo utilizar Git con PowerShell desde Visual Studio Code</strong>, el editor de preferencia de muchos para éste lenguaje.</p>



<p>¡Nos vemos en la próxima!</p>
<p>La entrada <a rel="nofollow" href="https://sobrebits.com/como-utilizar-git-con-powershell/">Cómo utilizar Git con PowerShell (Parte 1): posh-git</a> aparece primero en <a rel="nofollow" href="https://sobrebits.com">Sobrebits</a>.</p>
]]></content:encoded>
							<wfw:commentRss>https://sobrebits.com/como-utilizar-git-con-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
						<post-id xmlns="com-wordpress:feed-additions:1">3174</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.w3-edge.com/products/

Almacenamiento en caché de objetos 4/405 objetos que utilizan disk
Page Caching using disk (Page is feed) 

Served from: sobrebits.com @ 2020-05-09 23:31:24 by W3 Total Cache
-->