Una experiencia emocionante

Hola, que grato que nos veamos de nuevo, me gusta conectar con mis lectores, incluso contarles experiencias o situaciones de mi vida (nada comprometedor), pero considero que si se toman un minuto para compartir conmigo en su dia, es como si nos tomaramos un café juntos, y nos dieramos un breve saludo.

Asi las cosas, me gustaria hoy contarles que en mi niñez solia caminar hasta mi colegio de bachillerato, era una caminata de casi media hora, pero aunque mis padres me daban el dinero para que tomara el bus, yo preferia salir un poco antes, y al salir de clase comprarme una deliciosa arepa de queso callejera. Era mi recompensa por un pequeño esfuerzo como irme y regresarme caminando. En una de esas mañanas, ya en examenes de cierre de semestre, se me hizo tarde para salir, de modo que tuve que correr, con tan mala suerte (o buena suerte), que uno de estos Toyota Hardtop me piso la pierna izquierda, y me ocasiono fractura doble de tibia y peroné. La historia la traigo a colacion, porque este suceso me trajo multiples enseñanzas, tuve que aprender a caminar nuevamente, a sobreponerme ante una situacion adversa, a volver a pararme cuando estuvieron a punto de amputarme la pierna, y gracias a mi ortopedista, a las terapias, a la voluntad ferrea de mi abuela Leo que me acompaño y me ayudo mucho en esos momentos, logre no solo recuperar mi movilidad, sino que me propuse competir conmigo mismo, hacerlo mejor que ayer, si camine 1.5 km ayer, hoy caminare un poco mas. Este espiritu de competencia y mejoramiento continuo, me llevo a recuperarme muy rapido, y llegar a jugar volley con la seleccion distrital de Bogotá. Logre exponenciar mi potencial y ese tren inferior, hasta proporciones de deportista de alto desempeño. En este punto quiero compartir dos refranes de la sabiduria popular, «Es mejor perder un minuto en la vida, que la vida en un minuto», me lo enseño mi amigo Javier Cano, quien era regularmente mi compañero de recorrido hacia el colegio. Y el otro es «No por mucho madrugar, amanece mas temprano» que significa que las cosas deben hacerse en el momento apropiado, no antes, y definitivamente no despues.

Hace unos dias me logre certificar en fundamentos de AWS, y en los cursos mas escenciales de VMWare tambien, complementando mi gusto por Microsoft, pero mi apetito de conocimiento es una pasion, un gusto y un compromiso de competencia conmigo mismo, por aprender algo que no sabia ayer, y mi gusto por la lectura no para ahi, ahora resulte leyendo y escuchando libros digitales y podcast en las bibliotecas del sistema de bibliotecas publicas de Bogotá, resulte inmerso en una aplicacion que se llama Audible para escuchar los libros en el celular, y ante tanta literatura tecnica, se me volvio una especie de placer morbido tener un espacio de lectura no tecnica, asi que peliculas y series que me encantaron como el club de la pelea, farenheit 451, the sandman o game of thrones, me encantaron como obras narradas. Y el poder de la palabra tomo otro sentido, al punto que desee hacer un podcast, o al menos un estilo de conversatorio digital.

Leí comics, algunas aventuras de calabozos y dragones, y algo mas sobre robotica y arduino, pero seguia buscando algo mas… Me lei «El sutil arte de que te importe un carajo», un excelente y divertido libro, que con su narrativa fresca y descomplicada te enseña a apreciar lo que definitivamente es importante en tu vida. Cada uno de nosotros tenemos sueños, metas y definitivamente planes por los cuales nos esforzamos, y muchas veces los aplazamos por la familia, los compromisos laborales, o incluso por apariencia, y asi que resulte cayendo en el libro de James Clear, sobre los habitos atomicos, y como es posible potenciar todo lo que deseamos, y eliminar de la vida aquello que nos hace daño, cambiando los habitos, o las personas que habituamos. Este me llevo luego al club de las 5:00 AM, y estoy en esta onda de la autoayuda, de evitar la procrastinacion, de incentivar los buenos hábitos, de evitar perder tiempo y amar todo lo que hacemos, al punto de hacer las cosas con pasion, y con la determinada conviccion de que es lo que debemos estar haciendo.

En conclusion, no tenemos tiempo que perder, haber estado a punto de perder la vida, te da una perspectiva de que estamos de paso, la vida es muy corta, como para ser mala persona.

Microsoft Certified Trainer, a su servicio

Hace unos casi 20 años atrás tuve la oportunidad de conocer una comunidad maravillosa en Bogotá, que se llamaba ItPros-DC, en ese tiempo yo era aún un «sardino» en la universidad,  dicha comunidad maravillosa como comunidad al fin y al cabo, tenía mucho voluntariado, así que con algunos amigos, como Rubén Pinzón, Daniel Vargas, Mi queridísima Yohanna “Yohis” Ramírez, y hasta el coloso Edwin Garzón, empezamos en esa época a enseñar a otros, a dictar clases de sistemas operativos Windows Cliente, Windows server, a networking o incluso hasta Microsoft SQL o Exchange, y enseñando uno aprende, la forma de hacer las cosas, puede que otro las haga de diferentes maneras, y Microsoft sorprendentemente siempre tiene más de una forma de llegar al mismo punto, y enseñar me ha mostrado, que desde la humildad y la sencillez se puede liderar, inspirar, y orientar, que se puede relacionar y estrechar el vínculo con el estudiante,  y lograr una relación más clara de confianza y cercana cuando uno permite al estudiante ser su colega y su amigo.

Ayer estuve en una sesión donde estudiantes del SENA, querían presentar su examen de Azure fundamentos. Mi rol como preparador técnico, o entrenador, fue marcarles la ruta de estudio, indicarles esos tips y la manera de escalar en pequeños pasos su aprendizaje, cual era la mejor manera de fortalecer sus conocimientos y asistir a la cita con una actitud ganadora, confiados en lo que han aprendido y seguros de que un examen simplemente es una manera de evaluar los conocimientos adquiridos y las fortalezas o debilidades a mejorar.

Mi charla básicamente se centró en dirigirlos a Learn.microsoft.com y recomendarles la experiencia basada en puntos y logros, cada pequeña batalla cuenta y varias victorias suman al resultado final. comiencen abriendo una cuenta de Azure para estudiante, con las cuentas de SENA, o de cualquier institución académica deberían poder tener acceso a este beneficio de $100 dólares en créditos de Azure por 12 meses.

Mi recomendacion para ellos, y para todo aquel que lee este post es, que empiecen aprendiendo de a poco, proponganse metas ambiciosas, y hagan un plan de pequenas tareas que los vaya llevando a su objetivo. Recuerden que hay que soñar ser papa, para llegar a sacristan. Soñar no cuesta nada, pero si te quedas en la cama durmiendo, y solo soñando, nunca vas a conseguir nada, asi que lo mejor que puedes hacer, es transformar ese sueño en un proposito, un objetivo, definir tareas y hacer unos compromisos contigo mismo, poniendo fechas y estimando esfuerzo por cada tarea, iras notando el avance y registrando el progreso hacia tu meta.

En mi caso yo empece aprendiendo de sistemas operativos windows, comence con clientes, luego pase a servidores, con cada nuevo episodio venian cientos de capitulos de literatura incluida, es divertido descubrir nuevas caracteristicas y capacidades que los productos como Windows Server tienen para ofrecer, aqui en este punto aprendi algo sobre PowerShell, de ahi pase a aprender de networking, de almacenamiento, de correo, bases de datos y hasta de servidores web, para finalmente aprender sobre Sharepoint. Habiendo hecho todo este track de certificaciones y aprendizaje llegue al punto de querer aprender sobre servicios en nube, tipo SAAS como Office 365. aprendi lo suficiente del producto al punto que fui parte del equipo de soporte GIG_LATAM para Office365.

Nadie nace aprendido, todo se aprende al caminar por la senda del conocimiento, y por eso luego empece a merodear las mieles de Azure y la infraestructura como servicio o IAAS, y aqui es donde queria llegar, porque hoy en dia los examenes de Azure consisten en una gran cantidad de topicos, donde sin ser especialista ni tener un profundo conocimiento en cada tema, si se precisa al menos poder identificar que hacer con cada solucion y producto que nos presenta la nube.

Azure Precisa conocimiento en Hyper-V, para entender que una maquina esta compuesta de recursos de computo, (cpu/memoria Ram), un disco duro en formato VHD, una tarjeta de red (NIC) y en el caso de Azure se precisa de direcciones IP, Network security groups, y otras cosas como etiquetas, permisos RBAC, y configuraciones para alertas, monitoreo, autoescalamiento, y mas.. lo mas importante es que existen unos terminos, caracteristicas y limitantes de los servicios ofrecidos por Azure, donde se enfatiza en la cantidad de nucleos que se pueden asignar por suscripcion, y muchas otras cosas. Ahora bien, hay muchas empresas que nacieron en la nube, que si necesitaron un E-Commerce, lo implementaron directamente en Azure, y esto les permitio la escalabilidad y asegurar las ventas, sin incurrir en los onerosos gastos de OpEx y CapEx que ocasionaba comprar infraestructura local.

Si usted querido lector, quiere profundizar en estos temas, lo invito a una breve mirada de Azure Fundamentals y enterese de que es lo que es esa nube de la que todos hablan, y lo invito a que comparta, y compare, con otros fabricantes, como AWS, o GCP, que tambien tienen sus propias nubes.

DevOps

Muchos de los que trabajamos en el segmento de la tecnología sabemos que nuestro oficio no es como el de los artistas, pintores de obras maestras, que conciben la idea de su próximo cuadro y lo desarrollan con diferentes técnicas, colores, pinceles, y con amor, dedicacion y tiempo, más bien tenemos en tecnología una cierta similitud con los músicos de cámara, donde podemos tener especialidad o preferencia por un tipo de instrumento, viento, cuerdas o percusion, y hay quienes se dedican a componer musicalmente las partituras, quienes tienen la capacidad de interpretar, y quienes magistralmente pueden orquestar o dirigir una gran banda de músicos para que suene de cierta manera, mágica y sorprendente.

En tecnología, y sobre todo gracias a las tecnologías más recientes y a las capacidades del Cloud computing como Azure, GCP, o AWS, tenemos múltiples integraciones e interacciones entre distintas soluciones, las plataformas de bases de datos que Microsoft proporciona con SQL, ahora pueden ser muy diversas soluciones, desde un Oracle, a un MariaDB, un Postgresql con replicación citus para alta disponibilidad o hasta un Cosmos DB.

Cuando consideramos que un músico puede ser compositor e intérprete, al mismo tiempo, admitimos que también se puede ser desarrollador de aplicaciones y administrador de plataformas, lo cual converge en el convenientemente acuñado concepto de DevOps (Developer + Operations).

Si fuéramos un músico, con habilidades para tocar canciones en guitarra acústica, que sacamos al oído, pero no conocemos de partituras, ni conocemos de fundamentación musical o literatura pentagramada, pues no pasa nada, somos intérpretes del instrumento, y eso no se aprende en una noche. Al igual que se desarrollan las habilidades para poder tocar, y se garantiza que un Mi menor no es muy parecido a un Sol Mayor, en la escritura o transcripción musical se registran tiempos, silencios, notas que son más obtusas o más breves. Trabajar en nuestro desarrollo del conocimiento debe ser un apetito diario.

Mi gusto por la programación no nació de mis maestros universitarios, en realidad mi curiosidad en el mundo del Arduino, me ha llevado poco a poco a buscar mas sobre programacion en C++, la Raspberry Pi me ha ido inclinando hacia el oscuro lado de la fuerza y he descubierto Linux, y su vasto universo, y la sumatoria de estos nuevos placeres me han ido encauzando por la programación en Python. Ahora disfruto aprendiendo sobre GIT y GITHUB, sobre JavaScript, CSS y HTML, incluso hasta de WordPress he resultado tomando lecciones.

Ahora, no voy a decir que soy el más experto leyendo código, o interpretando métodos, funciones, variables, y estructuras de control, pero cada dia avanzo de a poco, en fortalecer y formar un mejor constructo mental que me permita llegar a la senda del Red Team, pues siempre he jugado en el lado azul, defendiendo infraestructuras, remediando vulnerabilidades, protegiendo servidores y los recursos Microsoft, los datos, la información, pero ahora que conozco un poco más sobre los mecanismos, técnicas, estrategias y herramientas que se usan para el ataque, puede ser más arriesgado pero más retador, lograr identificar fallos de seguridad que sanearlos.

«La paciencia es amarga, pero su fruto es dulce», me decía sabiamente mi estimado Harold Ordoñez, gerente y CEO de Glup Management group, un partner de Microsoft donde comencé a ver, y a conocer las herramientas de PowerApps, donde con facilidad se pueden crear soluciones y desarrollos a la medida, sin conocer mayormente de desarrollo o lenguajes de programación. Desde estas herramientas pase a conocer en Halliburton sobre Azure Functions y las soluciones ServerLess, que son los pilares de PowerApps. Ahora que he visto el potencial de Contenedores Docker y la capacidad de orquestación de Kubernetes, y de herramientas de gestión como Ansible o Terraform

AzureVMs y CLI

Para iniciar una máquina virtual que está apagada podemos usar el azure CLI az vm start –resource-group campohenriquezdtl –name Ubu01

Tambien es posible apagar una maquina virtual az vm stop –resource-group campohenriquezdtl –name Ubu01

Dado que no es igual apagar una maquina virtual que desalojarla, una máquina desalojada no consume recursos de procesamiento y memoria porque se entiende como que se retiran los recursos asignados, az vm deallocate –resource-group campohenriquezdtl –name Ubu01

Podemos reiniciar una maquina con az vm restart –resource-group campohenriquezdtl –name Ubu01

Es posible configurar el proceso de auto apagado a una hora específica con az vm auto-shutdown –resource-group campohenriquezdtl –name Ubu01 –time 1730

az vm extension list –resource-group campohenriquezdtl-fieldsteinlab2021-123105 –name Ubu01

az vm list-ip-addresses –resource-group campohenriquezdtl-fieldsteinlab2021-123105 –name Ubu01

az vm monitor metrics tail –resource-group campohenriquezdtl-fieldsteinlab2021-123105 –name Ubu01

az vm show –resource-group campohenriquezdtl-fieldsteinlab2021-123105 –name Ubu01

Maraton de series

Empece hace unos años con mi esposa a maratonear series, el tipico enganchado de las 11:30 p.m. entre semana, y la pregunta, ¿Que… Nos vemos el otro?

La verdad yo siempre he sido un gran consumidor de ese cine hollywodense, de accion, de drama, de fantasia, y en general de poco sentido cultural o social.- las peliculas de suspenso y terror no han sido nunca de mis favoritas, y aun asi he visto muchas, de hecho los que me conocen de hace muchos años, saben que en algun momento de mi vida, no salia de las videotiendas, alquilando peliculas en sitios como blockbuster, betatonio, o los locales de barrio. De hecho, recuerdo gratamente que con mi primo Lucho, teníamos este mismo ritual, sofá comodo, tazón de palomitas, o pote de helado, y plan peliculas todo un domingo… creo que de hecho a el le aprendí el habito de mirar los creditos, y aprenderme los nombres de actores, directores y productores. hoy en día por cierto hago uso de http://www.IMDB.com para consultar las peliculas que se han hecho, y aquellas que vienen en desarrollo, en etapa de pre-producción o incluso en fase de proyecto.

Ahora que todas las plataformas de streaming nos la ponen tan facil, Netflix, Star+, HBO max, Amazon prime, en lugar de ir al cine, disfruto ver las peliculas en la comodidad de mi casa, y que mi esposa me prepare mis palomitas de maiz con mantequilla, o con ricostilla, (las de dulce aun no aprendemos a hacerlas bien…), o con alitas de pollo y en compañia de mi hija y mi esposa, cada una a cada lado, nos adentramos en la pantalla, estando en un arrunchis comodisimo.

He visto series supremamente largas, como las de Marvel, Agentes de S.h.i.e.l.d, Luke Cage, Dare devil, Iron fist, que pueden llegar a tener 7 temporadas y hasta 23 episodios de una hora, he visto series de suspenso, crueles, e inesperadas como The Game of Thrones, La Casa de Papel, o the walking dead, donde la naturaleza humana, los valores o las decisiones reflejan unos resultados inesperados y unos giros tremendos en las historias.

He visto series que me han dejado mal de la cabeza como Mr. Robot, o Black Mirror, que dentro de todo lo que proponen, tienen un tinte de certeza, un poco de verdad bajo la trama propuesta, y eso asusta. he visto series de anime, como los caballeros del zodiaco, One Punch Man, o Konosuba, y series que se han entretejido con otras series, como las de Warner, como Flash con Arrow, y a su vez con Super Girl.

Superheroes, ficcion, y aventura son mis favoritas

En todo caso son muchisimos contenidos, almacenados en mi cabeza, seguramente si a eso le sumamos los cuentos, comics, libros, revistas, blogs, video tutoriales, los innumerables contenidos tecnicos, los videos musicales, las peliculas de cine, las telenovelas y reality shows, los noticieros, las mil repeticiones del chavo del 8 y de los cuentos de los hermanos grimm, ya tendria suficientes horas al aire para decir que ya no me caben mas contenidos. Afortunadamente la memoria humana tiene ese proceso en segundo plano que va decantando los recuerdos que se quedan y los que se olvidan, esa limpieza realmente necesaria.

Recientemente con los contenidos de tiras comicas, memes, y toda la literatura de Dungeons and Dragons he dejado de entrenar y dictar cursos para hacer actividades mas ludicas, sin embargo debo reconocer que el contacto y la interaccion social que me proporciona la docencia, ese intercambio de opiniones, los diferentes paradigmas que ofrece cada estudiante desde su propia perspectiva y experiencia, es algo que definitivamente extraño mucho de tiempos pre-pandemia.

Los invito a continuar leyendo, a continuar viendo maratones de series, y consumiendo cine.- son diferentes formas de arte, fotografia, color, sonorizacion o construcciones imaginarias, que definitivamente debemos conservar. Y a todos los productores, directores de contenidos digitales, influencers, y artistas, la invitacion es a continuar generando, creando, e inspirando a otros con sus ideas, y sus puntos de vista.

Seguridad de película? Política o imaginación?

Ayer conversando con unos amigos sobre la situación de seguridad que la alcaldía busca solucionar restringiendo los parrilleros en moto, empezamos a hablar sobre las tendencias e ideas futuristas que pintaron en las películas de antaño, las matrículas de los carros en volver en futuros partidos eran escaneadas como código de barras y teniendo La completa información en tiempo real de su propietario y dónde vivía. Por ejemplo,  y para seguir con películas de los noventas, en el quinto elemento de Bruce Willis, los autos antes de salir a rodar a la calle, tenian que solicitar autorización,  se validaba el estado del vehículo y la vigencia de la licencia del conductor, recuerdo que a Michael Corben le quedaban dos recorridos antes de la revisión del taxi. O en el demoledor de Wesley Snipes y Sly Stallone, vaticinaron con cierta precisión,  los autos eléctricos,  las armas aturdidoras eléctricas, las cámaras en cada esquina y las video llamadas con casi 30 años de anticipación,  y la pandemia de los moviles o tabletas, así como el distanciamiento social. Que habrá sentido Sandra Bullock cuando se hizo realidad esa situación de no contacto, no besos, porque todos esos germenes y virus… en fin… todo esto para volver a la identificación vehicular, los vehículos encendían con comando de voz, y tenían seguimiento satélital.  

Si la alcaldesa quiere hacer un cambio en la movilidad del 20% del país,  el ministerio de transporte,  entidad que regula a la secretaria de movilidad de Bogota,  debería hacer un cambio en la plataforma tecnológica,  que permita con algoritmos de machine learning e inteligencia artificial,  registrar los movimientos de cada vehículo,  cada vez que sea captado por cualquier cámara en la ciudad o su periferia. Para esto podríamos usar placas con QR, o con códigos de barras que rápidamente permitan identificar el automotor, su propietario y su identidad. Todo podría estar en el sistema del gobierno Colombiano,  si está al día en sus pagos de impuestos,  su seguridad social, si tiene asuntos pendientes con la ley… sus cuentas de redes sociales, su perfil sociológico, si es un potencial riesgo para la seguridad nacional.

Azure 2022

Como es costumbre en este espacio, conversaremos sobre materiales de entrenamiento, y contenidos sobre nube de Microsoft Azure, hoy les traigo para su referencia, la nueva version de la tabla periodica de Azure 2022, esta version desprente cada categoria en una columna dejandonos ver en cada vertical que productos ofrece Microsoft. https://azurecharts.com/overview

Tengo ademas la url equivalente para los servicios de Google Cloud https://googlecloudcheatsheet.withgoogle.com/ y para AWS tambien han generado una Tabla periodica similar, https://www.google.com/search?q=aws+table&client=ms-android-samsung-gs-rev1&prmd=ivn&sxsrf=APq-WBseNSN-FqeDXY-mSHVaxFiwwv89ZA:1646151765240&source=lnms&tbm=isch&sa=X&ved=2ahUKEwiuhNqZqaX2AhWhsDEKHRlpCYcQ_AUoAXoECAIQAQ&biw=1920&bih=1080&dpr=1#imgrc=mpGh3ylVfShuMM

Visual Studio Code y Azure

En este repositorio exploraremos Visual studio Code, desde una perspectiva dinamica y divertida, es como todas las historias de aventuras de D&D, o del señor de los anillos, estamos todos reunidos en la mayor comodidad, tranquilos disfrutando de la tarde, y el destino nos va a llegar nuevo un «Quest», una busqueda o reto, en este caso vamos a acompañar a este valiente explorador, de abultado vientre, y corta vista, en un terreno poco explorado, como lo es el uso de las diferentes plataformas de administracion de la nube como las lineas de comando y particularmente el vscode para gestionar plantillas ARM.

Instalacion de prerequisitos

Si usted no tiene una suscripcion de Azure haga clic aqui, necesitara un equipo con Windows 10 preferiblemente, y lo invito a que preparemos los pre-requisitos:

  • Primero que todo una enorme taza del café de su preferencia
  • El modulo de Azure para powershell, aunque se puede administrar Azure desde el portal web cual seria la gracia, este modulo AZ se puede instalar iniciando el PowerShell en modo administrador (es decir dando clic derecho sobre el icono de PowerShell), y usando los siguientes comandos:
$PSVersionTable.PSVersion #para verificar que version de Powershell se tiene con version 5.0 o superior podemos hacer uso de

Install-Module -Name Az #Esto tomara un rato, porque son varios modulos, tambien es posible que te solicite confirmacion de que confias en el repositorio de PSGallery antes de continuar.

Para mas informacion consulte aqui

  • El Azure CLI tambien vale la pena tenerlo, vamos a instalarlo desde aqui esta es otra manera de interactuar con Azure desde PowerShell como administrador ejecutaremos
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'; rm .\AzureCLI.msi
  • Es posible ingresar a la tienda de Microsoft Store, y descargar el Windows Terminal
  • Tambien puedes querer descargar el WSL (Windows Subsystem for Linux) que permite la ejecucion de un linux Ubuntu dentro de tu sistema operativo, para tener acceso por BASH y poder ejecutar herramientas propias de linux, para instalar el WSL
  • Descargue el Visual Studio Code desde aqui el instalador es muy liviano, pesa menos de 100MB. la instalacion es super simple, y vamos a ir complementandola con las extensiones para Azure a lo largo de este workshop
$VSCode = "https://code.visualstudio.com/docs/?dv=win"
New-FileDownload -SourceFile $VSCode

Guia de laboratorio

Visual Studio Code

Empecemos reconociendo el terreno,

«VS Code viene con un diseño simple e intuitivo que maximiza el espacio provisto para el editor mientras deja un amplio espacio para navegar y acceder al contexto completo de su carpeta o proyecto. La IU se divide en cinco áreas:

  • Editor: el área principal para editar sus archivos. Puede abrir tantos editores como desee, uno al lado del otro, vertical y horizontalmente.
  • Barra lateral: contiene diferentes vistas como el Explorador para ayudarlo mientras trabaja en su proyecto.
  • Barra de estado: información sobre el proyecto abierto y los archivos que edita.
  • Barra de actividad: ubicada en el extremo izquierdo, le permite cambiar de vista y le brinda indicadores adicionales específicos del contexto, como la cantidad de cambios salientes cuando Git está habilitado.
  • Paneles: puede mostrar diferentes paneles debajo de la región del editor para obtener información de salida o depuración, errores y advertencias, o un terminal integrado. El panel también se puede mover hacia la derecha para obtener más espacio vertical.» tomado de:(https://code.visualstudio.com/docs/getstarted/userinterface#_basic-layout)

ahora el Tiki-tiki

Para empezar a probar que todo nos este funcionando, usaremos la barra lateral, para crear un nuevo archivo. Quiero que lo llamemos test.ps1, esta extension hara que el Visual Studio Code identifique que estas intentando crear un Script de PowerShell, por lo que en el modulo de Extensiones te solicitara la instalacion de la extension de PowerShell, en mi escenario utilice la de «PowerShell preview»-

vamos a abrir la consola de PowerShell dentro del vscode, en la seccion inferior aparecen cuatro pestañas, «Problemas», «Salidas», «Consola de Depuracion», y «Terminal» esta ultima es la que me interesa, y vamos a validar que en la parte de la derecha aparece indicando que esta en modo PowerShell, porque tambien puede que esta consola nos funcione para bash.-

Connect-AzAccount #Aqui te pedira iniciar sesion sobre el portal de https://microsoft.com/devicelogin 
get-azresource |ft

PowerShell en 5 minutos

Write-Host #"Powershell tiene una estructura sencilla, es una composicion de un verbo en infinitivo, un guion al medio y un sustantivo singular" -ForegroundColor Yellow
Write-Host #"Por ejemplo podemos encontrar un Get-Command, un Get-Help, o un Get-Service en mas de 800 cmd-lets" -ForegroundColor Yellow
Get-Command
Write-host #"Si queremos saber que esta haciendo nuestro equipo, hacemos un get-process" -ForegroundColor Yellow
Get-process
Write-Host #"Si la informacion es muy extensa, como en este caso, podemos ordenarla" -ForegroundColor Yellow
Update-Help
get-help Get-Process
get-help Get-Process -full
get-help Get-Process -detailed
get-help Get-Process -examples
get-help Get-Process -Online
Get-Service
Get-Service -Name Spooler |Stop-Service
Get-Service M* |Format-List

Command-lets y Parametros

Get-Service M* |Format-Custom
Get-Service M* |Where-Object {$_.Status -eq "Running"}
Get-Service M* |Where-Object {$_.Status -eq "Stopped"}
Get-Service | Sort-Object Status
Get-Service | Sort-Object Status |Format-Table -GroupBy Status Name, DisplayName
Get-Service |Get-Member
Get-Process |Get-Member
Get-Service Spooler |Select-Object ServicesDependedOn
Show-Command Get-Service
Stop-Service M* -WhatIf
Stop-Service M* -Confirm

Pasando resultados con el Pipe o Piping

Get-Process |sort CPU -Descending
Get-EventLog -LogName System -EntryType Error -Newest 10
Get-EventLog -LogName System -EntryType Error -Newest 10 |fl
Get-EventLog -LogName System -EntryType Error -Newest 10 |ogv

Variables y Scripts

$var = "Hola DevOps2020"
$var
Write-host "$var" -ForegroundColor Yellow
Get-Variable 
#podemos manejar strings
$num = 123
$num
#Podemos contener listas o arrays tambien
$num = 1,2,3
$num
$var.GetType().FullName
$var.Length
$var[1]
[int[]] $var = (1,2,3)
$var[2] = "1234"
$var[2]
$v1 = "Hello "
$v2 = "world"
$v1+$v2
($var1+$var2).Length
#Comparar con -eq -ne -gt -lt -ge -le
"Juan Perez" -eq "Ramon Valdez"
#formatos
"{0:f2}" -f 12.4
"|{0,10:C}|" -f 12.4
"{0:hh:mm}" -f (get-date)
#Scripting
Get-ExecutionPolicy
Set-ExecutionPolicy Unrestricted
Get-ExecutionPolicy
runas /user:username PowerShell
##Mas info sobre seguridad en PoSh http://technet.microsoft.com/en-us/magazine/2007.09.powershell.aspx
#------------------------
#test.ps1
#Show Hello and time
"" #Blank line
"Hello"+$Env:USERNAME +"!"
"Time is" + "{0:HH}:{0:mm}" -f (get-Date)
"" #blank line
#------------------------
#Funciones
function get-soup (
    [switch] $please,
    [String] $soup = "chicken noodle"
    )
{
    if ($please){
        "Here's your $soup soup"
    }
    else {
        "No soup for you!"
    }
}
#------------------------

Entornos y modulos

#---------
$User = "fabian.campo@MiDominio.com"
$Pass = ConvertTo-SecureString "AzurePa55w.rd" -AsPlainText -Force
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Pass
Import-Module MSOnline
Connect-msolservice -Credential $Cred
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $Cred -Authentication Basic -AllowRedirection
Import-PSSession $Session
Import-Module LyncOnlineConnector
import-module microsoft.online.sharepoint.powershell
$Session = New-CsOnlinesession -Credential $Cred
Import-PSSession $Session
[string]$tenant = get-msoldomain | where {$_.name -like "*.onmicrosoft.com" -and -not($_.name -like "*mail.onmicrosoft.com")} | select name
$tenant
$tenant3 = $tenant -split("=")
[string]$tenant4 = $tenant3[1]
$tenant4
$tenant5 = $tenant4 -split(".on")
[string]$tenant6 = $tenant5[0]
$url = "https://" + $tenant6 + "-admin.sharepoint.com"
Connect-SPOService -Url $url -credential $Cred  
#---------

Registro, Certificados y otros almacenes

Get-psprovider
Get-psDrive
New-PsDrive -Name HKCS -PSProvider Registry -Root "HKEY_CLASSES_ROOT"
cd HKCS:
dir .ht*
$process = Get-WmiObject -Class win32_Process
$item.name
foreach ($item in $process)
{
    $item.name
}

Creando Maquinas virtuales en Azure

Connect-AzAccount
Get-AZSubscription | Sort SubscriptionName | Select SubscriptionName
$subscrName="Plataformas de MSDN"
Select-AzSubscription -SubscriptionName $subscrName
$rgName="Devops2020_rg"
$locName="eastus"
New-AZResourceGroup -Name $rgName -Location $locName
Get-AZStorageAccountNameAvailability "campoh1473"
$rgName="Devops2020_rg"
$saName="campoh1473"
$locName=(Get-AZResourceGroup -Name $rgName).Location
New-AZStorageAccount -Name $saName -ResourceGroupName $rgName -Type Standard_LRS -Location $locName
$rgName="Devops2020_rg"
$locName=(Get-AZResourceGroup -Name $rgName).Location
$vnetName="Vnet01"
$SubnetName="Subnet01"
$Subnet=New-AZVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix 10.0.0.0/27
New-AZVirtualNetwork -Name $vnetName -ResourceGroupName $rgName -Location $locName -AddressPrefix 10.0.0.0/24 -Subnet $Subnet -DNSServer 10.0.0.4
$rule1 = New-AZNetworkSecurityRuleConfig -Name "RDPTraffic" -Description "Allow RDP to all VMs on the subnet" -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 3389
$rule2 = New-AZNetworkSecurityRuleConfig -Name "ExchangeSecureWebTraffic" -Description "Allow HTTPS to the Exchange server" -Access Allow -Protocol Tcp -Direction Inbound -Priority 101 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix "10.0.0.5/32" -DestinationPortRange 443
$rule3 = New-AZNetworkSecurityRuleConfig -Name "SharePointSecureWebTraffic" -Description "Allow HTTPS to the SharePoint server" -Access Allow -Protocol Tcp -Direction Inbound -Priority 102 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix "10.0.0.7/32" -DestinationPortRange 80
New-AZNetworkSecurityGroup -Name $SubnetName -ResourceGroupName $rgName -Location $locName -SecurityRules $rule1, $rule2, $rule3
$vnet=Get-AZVirtualNetwork -ResourceGroupName $rgName -Name $vnetName
$nsg=Get-AZNetworkSecurityGroup -Name $SubnetName -ResourceGroupName $rgName
Set-AZVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name $SubnetName -AddressPrefix "10.0.0.0/27" -NetworkSecurityGroup $nsg
$vnet | Set-AzVirtualNetwork
$rgName="Devops2020_rg"
# Create an availability set for domain controller virtual machines
New-AZAvailabilitySet -ResourceGroupName $rgName -Name dcAvailabilitySet -Location $locName -Sku Aligned  -PlatformUpdateDomainCount 5 -PlatformFaultDomainCount 2
# Create the domain controller virtual machine
$vmName="adVM"
$vmSize="Standard_D1_v2"
$vnet=Get-AZVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$pip = New-AZPublicIpAddress -Name ($vmName + "-PIP") -ResourceGroupName $rgName -Location $locName -AllocationMethod Dynamic
$nic = New-AZNetworkInterface -Name ($vmName + "-NIC") -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -PrivateIpAddress 10.0.0.4
$avSet=Get-AZAvailabilitySet -Name dcAvailabilitySet -ResourceGroupName $rgName
$vm=New-AZVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avSet.Id
$vm=Set-AZVMOSDisk -VM $vm -Name ($vmName +"-OS") -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
$diskConfig=New-AZDiskConfig -AccountType "Standard_LRS" -Location $locName -CreateOption Empty -DiskSizeGB 20
$dataDisk1=New-AZDisk -DiskName ($vmName + "-DataDisk1") -Disk $diskConfig -ResourceGroupName $rgName
$vm=Add-AZVMDataDisk -VM $vm -Name ($vmName + "-DataDisk1") -CreateOption Attach -ManagedDiskId $dataDisk1.Id -Lun 1
$cred=Get-Credential -Message "Type the name and password of the local administrator account for adVM."
$vm=Set-AZVMOperatingSystem -VM $vm -Windows -ComputerName adVM -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AZVMSourceImage -VM $vm -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2012-R2-Datacenter -Version "latest"
$vm=Add-AZVMNetworkInterface -VM $vm -Id $nic.Id
New-AZVM -ResourceGroupName $rgName -Location $locName -VM $vm
## conecte al adVM y ejecute
$disk=Get-Disk | where {$_.PartitionStyle -eq "RAW"}
$diskNumber=$disk.Number
Initialize-Disk -Number $diskNumber
New-Partition -DiskNumber $diskNumber -UseMaximumSize -AssignDriveLetter
Format-Volume -DriveLetter F
Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
Install-ADDSForest -DomainName campoh.lab -DatabasePath "F:\NTDS" -SysvolPath "F:\SYSVOL" -LogPath "F:\Logs"
Add-WindowsFeature RSAT-ADDS-Tools
New-ADUser -SamAccountName sp_farm_db -AccountPassword (read-host "Set user password" -assecurestring) -name "sp_farm_db" -enabled $true -PasswordNeverExpires $true -ChangePasswordAtLogon $false
New-ADUser -Name EXCHSVC -GivenName EXCHSVC -UserPrincipalName EXCHSVC -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name SYSADMIN -GivenName EXCHADMIN -UserPrincipalName EXCHADMIN -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name EFlores -GivenName "Maria Elena" -surname "Flores" -UserPrincipalName EFlores -EmailAddress EFlores@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name Vgarcia -GivenName "Victor" -surname "Garcia" -UserPrincipalName Vgarcia -EmailAddress Vgarcia@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name LRodriguez -GivenName "Lourdes" -surname "Rodriguez" -UserPrincipalName LRodriguez -EmailAddress LRodriguez@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name JLSanchez -GivenName "Jorge Luis" -surname "Sanchez" -UserPrincipalName JLSanchez -EmailAddress JLSanchez@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name CZambrano -GivenName "Cecilia" -surname "Zambrano" -UserPrincipalName CZambrano -EmailAddress CZambrano@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name MSalazar -GivenName "Mariana " -surname "Salazar" -UserPrincipalName MSalazar -EmailAddress MSalazar@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name JCTorres -GivenName "Juan Carlos" -surname "Torres" -UserPrincipalName JCTorres -EmailAddress JCTorres@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name ALAndrade -GivenName "Ana Lucia" -surname "Andrade" -UserPrincipalName ALAndrade -EmailAddress ALAndrade@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name MVera -GivenName "Miguel Angel" -surname "Vera" -UserPrincipalName MVera -EmailAddress MVera@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
## Fase 2- Creamos ahora la maquina de Exchange
$vmDNSName="mail2393"
$rgName="Devops2020_rg"
$locName=(Get-AZResourceGroup -Name $rgName).Location
Test-AZDnsAvailability -DomainQualifiedName $vmDNSName -Location $locName
# Set up key variables
$subscrName="Plataformas de MSDN"
$rgName="Devops2020_rg"
$vmDNSName="mail2393"
# Set the Azure subscription
Select-AzSubscription -SubscriptionName $subscrName
# Get the Azure location and storage account names
$locName=(Get-AZResourceGroup -Name $rgName).Location
$saName=(Get-AZStorageaccount | Where {$_.ResourceGroupName -eq $rgName}).StorageAccountName
# Create an availability set for Exchange virtual machines
New-AZAvailabilitySet -ResourceGroupName $rgName -Name exAvailabilitySet -Location $locName -Sku Aligned  -PlatformUpdateDomainCount 5 -PlatformFaultDomainCount 2
# Specify the virtual machine name and size
$vmName="exVM"
$vmSize="Standard_D3_v2"
$vnet=Get-AZVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$avSet=Get-AZAvailabilitySet -Name exAvailabilitySet -ResourceGroupName $rgName
$vm=New-AZVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avSet.Id
# Create the NIC for the virtual machine
$nicName=$vmName + "-NIC"
$pipName=$vmName + "-PublicIP"
$pip=New-AZPublicIpAddress -Name $pipName -ResourceGroupName $rgName -DomainNameLabel $vmDNSName -Location $locName -AllocationMethod Dynamic
$nic=New-AZNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -PrivateIpAddress "10.0.0.5"
# Create and configure the virtual machine
$cred=Get-Credential -Message "Type the name and password of the local administrator account for exVM."
$vm=Set-AZVMOSDisk -VM $vm -Name ($vmName +"-OS") -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
$vm=Set-AZVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AZVMSourceImage -VM $vm -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2012-R2-Datacenter -Version "latest"
$vm=Add-AZVMNetworkInterface -VM $vm -Id $nic.Id
New-AZVM -ResourceGroupName $rgName -Location $locName -VM $vm
## Conectese a exVM y ejecute
Add-Computer -DomainName "campoh.lab"
Install-WindowsFeature AS-HTTP-Activation, Server-Media-Foundation, NET-Framework-45-Features, RPC-over-HTTP-proxy, RSAT-Clustering, RSAT-Clustering-CmdInterface, RSAT-Clustering-Mgmt, RSAT-Clustering-PowerShell, WAS-Process-Model, Web-Asp-Net45, Web-Basic-Auth, Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect, Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Lgcy-Mgmt-Console, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI, Windows-Identity-Foundation, RSAT-ADDS
Restart-Computer
## Configurar el Exchange
Write-Host (Get-AZPublicIpaddress -Name "40.84.58.22" -ResourceGroup $rgName).DnsSettings.Fqdn
## Desde exVM
## descarga los pre-requisitos, 
## https://go.microsoft.com/fwlink/p/?linkid=863265 ".NET Framework 4.7.2 "
## https://go.microsoft.com/fwlink/?linkid=327788 "Paquete redistribuible de Visual C++ para Visual Studio 2012"
## https://go.microsoft.com/fwlink/?linkid=2002913 "Paquete redistribuible de Visual C++ para Visual Studio 2013"
## https://go.microsoft.com/fwlink/p/?linkId=258269 "API administrada de comunicaciones unificadas de Microsoft 4.0, Core Runtime (64 bits)" 
## descarga el ISO de Exchange con el ultimo CU
e:
.\setup.exe /prepareSchema /IacceptExchangeServerLicenseTerms
.\setup.exe /prepareAD /OrganizationName:LandonHotel /IacceptExchangeServerLicenseTerms
.\setup.exe /mode:Install /role:Mailbox /OrganizationName:LandonHotel /IacceptExchangeServerLicenseTerms
Restart-Computer
$dnsName="mail1473.eastus2.cloudapp.azure.com"
$user1Name="chris@" + $dnsName
$user2Name="janet@" + $dnsName
$db=Get-MailboxDatabase
$dbName=$db.Name
$password = Read-Host "Enter password" -AsSecureString
New-Mailbox -UserPrincipalName $user1Name -Alias chris -Database $dbName -Name ChrisAshton -OrganizationalUnit Users -Password $password -FirstName Chris -LastName Ashton -DisplayName "Chris Ashton"
New-Mailbox -UserPrincipalName $user2Name -Alias janet -Database $dbName -Name JanetSchorr -OrganizationalUnit Users -Password $password -FirstName Janet -LastName Schorr -DisplayName "Janet Schorr"
## Fase 3- Creamos ahora la maquina de SQL Server
# Log in to Azure
Connect-AzAccount
# Set up key variables
$subscrName="Plataformas de MSDN"
$rgName="Devops2020_rg"
# Set the Azure subscription and location
Select-AzSubscription -SubscriptionName $subscrName
$locName=(Get-AzResourceGroup -Name $rgName).Location
# Create an availability set for SQL Server virtual machines
New-AzAvailabilitySet -ResourceGroupName $rgName -Name sqlAvailabilitySet -Location $locName -Sku Aligned  -PlatformUpdateDomainCount 5 -PlatformFaultDomainCount 2
# Create the SQL Server virtual machine
$vmName="sqlVM"
$vmSize="Standard_D3_V2"
$vnetName="Vnet01"
$vnet=Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$pip=New-AzPublicIpAddress -Name ($vmName + "-PIP") -ResourceGroupName $rgName -Location $locName -AllocationMethod Dynamic
$nic=New-AzNetworkInterface -Name ($vmName + "-NIC") -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -PrivateIpAddress "10.0.0.6"
$avSet=Get-AzAvailabilitySet -Name sqlAvailabilitySet -ResourceGroupName $rgName 
$vm=New-AzVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avSet.Id
$vm=Set-AzVMOSDisk -VM $vm -Name ($vmName +"-OS") -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
$diskSize=100
$diskConfig=New-AzDiskConfig -AccountType "Standard_LRS" -Location $locName -CreateOption Empty -DiskSizeGB $diskSize
$dataDisk1=New-AzDisk -DiskName ($vmName + "-SQLData") -Disk $diskConfig -ResourceGroupName $rgName
$vm=Add-AzVMDataDisk -VM $vm -Name ($vmName + "-SQLData") -CreateOption Attach -ManagedDiskId $dataDisk1.Id -Lun 1
$cred=Get-Credential -Message "Type the name and password of the local administrator account of the SQL Server computer." 
$vm=Set-AzVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AzVMSourceImage -VM $vm -PublisherName MicrosoftSQLServer -Offer SQL2017-WS2016 -Skus Standard -Version "latest"
$vm=Add-AzVMNetworkInterface -VM $vm -Id $nic.Id
New-AzVM -ResourceGroupName $rgName -Location $locName -VM $vm
## Connect sqlVM 
Add-Computer -DomainName "campoh.lab"
Restart-Computer
Get-Disk | Where PartitionStyle -eq "RAW" | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel "SQL Data"
md f:\Data
md f:\Log
md f:\Backup
New-NetFirewallRule -DisplayName "SQL Server ports 1433, 1434, and 5022" -Direction Inbound -Protocol TCP -LocalPort 1433,1434,5022 -Action Allow
## Fase 4- Creamos ahora la maquina de SP Server
# Set up key variables
$subscrName="Plataformas de MSDN"
$rgName="Devops2020_rg"
$dnsName="campoh1473"
# Set the Azure subscription
Select-AzSubscription -SubscriptionName $subscrName
# Get the location
$locName=(Get-AzResourceGroup -Name $rgName).Location
# Create an availability set for SharePoint virtual machines
New-AzAvailabilitySet -ResourceGroupName $rgName -Name spAvailabilitySet -Location $locName -Sku Aligned  -PlatformUpdateDomainCount 5 -PlatformFaultDomainCount 2
# Create the spVM virtual machine
$vmName="spVM"
$vmSize="Standard_D3_V2"
$vnetName="Vnet01"
$vm=New-AzVMConfig -VMName $vmName -VMSize $vmSize
$pip=New-AzPublicIpAddress -Name ($vmName + "-PIP") -ResourceGroupName $rgName -DomainNameLabel $dnsName -Location $locName -AllocationMethod Dynamic
$vnet=Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$nic=New-AzNetworkInterface -Name ($vmName + "-NIC") -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -PrivateIpAddress "10.0.0.7"
$avSet=Get-AzAvailabilitySet -Name spAvailabilitySet -ResourceGroupName $rgName 
$vm=New-AzVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avSet.Id
$vm=Set-AzVMOSDisk -VM $vm -Name ($vmName +"-OS") -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
$cred=Get-Credential -Message "Type the name and password of the local administrator account."
$vm=Set-AzVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AzVMSourceImage -VM $vm -PublisherName "MicrosoftSharePoint" -Offer "MicrosoftSharePointServer" -Skus "2019" -Version "latest"
$vm=Add-AzVMNetworkInterface -VM $vm -Id $nic.Id
New-AzVM -ResourceGroupName $rgName -Location $locName -VM $vm
## Connect spVM 
Add-Computer -DomainName "campoh.lab"
Restart-Computer
New-NetFirewallRule -DisplayName "SQL Server ports 1433, 1434, and 5022" -Direction Inbound -Protocol TCP -LocalPort 1433,1434,5022 -Action Allow
Write-Host (Get-AzPublicIpaddress -Name "13.77.127.118" -ResourceGroup $rgName).DnsSettings.Fqdn
##Desplegar un cliente
$rgName="Devops2020_rg"
$locName=(Get-AzResourceGroup -Name $rgName).Location
$vnet=Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$pip=New-AzPublicIpAddress -Name CLIENT1-PIP -ResourceGroupName $rgName -Location $locName -AllocationMethod Dynamic
$nic=New-AzNetworkInterface -Name CLIENT1-NIC -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id
$vm=New-AzVMConfig -VMName CLIENT1 -VMSize Standard_A1
$cred=Get-Credential -Message "Type the name and password of the local administrator account for CLIENT1."
$vm=Set-AzVMOperatingSystem -VM $vm -Windows -ComputerName CLIENT1 -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AzVMSourceImage -VM $vm -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2016-Datacenter -Version "latest"
$vm=Add-AzVMNetworkInterface -VM $vm -Id $nic.Id
$vm=Set-AzVMOSDisk -VM $vm -Name "CLIENT1-OS" -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
New-AzVM -ResourceGroupName $rgName -Location $locName -VM $vm
## Detener / Iniciar las maquinas virtuales
$rgName="Devops2020_rg"
Stop-AZVM -Name Client1 -ResourceGroupName $rgName -Force
Stop-AZVM -Name exVM -ResourceGroupName $rgName -Force
Stop-AzVM -Name spVM -ResourceGroupName $rgName -Force
Stop-AzVM -Name sqlVM -ResourceGroupName $rgName -Force
Stop-AZVM -Name adVM -ResourceGroupName $rgName -Force
$rgName="Devops2020_rg"
Start-AZVM -Name adVM -ResourceGroupName $rgName
Start-AZVM -Name exVM -ResourceGroupName $rgName
Start-AzVM -Name sqlVM -ResourceGroupName $rgName
Start-AzVM -Name spVM -ResourceGroupName $rgName
Start-AZVM -Name Client1 -ResourceGroupName $rgName

az-vm-parameters.json

{
«$schema»: «https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#»,
«contentVersion»: «1.0.0.0»,
«parameters»: {
«vmSize»: {
«value»: «Standard_D2s_v3»
},
«adminUsername»: {
«value»: «sysadmin»
},
«adminPassword»: {
«value»: «AzurePa55w.rd»
}
}
}

az-vm-template.json

{
«$schema»: «https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#»,
«contentVersion»: «1.0.0.0»,
«parameters»: {
«vmSize»: {
«type»: «string»,
«defaultValue»: «Standard_D2s_v3»,
«metadata»: {
«description»: «Virtual machine size»
}
},
«nameSuffix»: {
«type»: «string»,
«allowedValues»: [
«2»,
«3»
],
«metadata»: {
«description»: «Naming suffix»
}
},
«adminUsername»: {
«type»: «string»,
«metadata»: {
«description»: «Admin username»
}
},
«adminPassword»: {
«type»: «securestring»,
«metadata»: {
«description»: «Admin password»
}
}
},
«variables»: {
«vmName»: «[concat(‘az-vm’,parameters(‘nameSuffix’))]»,
«vmExtensionName»: «customScriptExtension»,
«nicName»: «[concat(‘az-nic’,parameters(‘nameSuffix’))]»,
«virtualNetworkName»: «[concat(‘az-vnet’,parameters(‘nameSuffix’))]»,
«nsgName»: «[concat(‘az-nsg’,parameters(‘nameSuffix’))]»,
«vnetIpPrefix»: «[concat(‘10.6’,parameters(‘nameSuffix’),’.0.0/22′)]»,
«subnetIpPrefix»: «[concat(‘10.6’,parameters(‘nameSuffix’),’.0.0/24′)]»,
«subnetName»: «subnet0»,
«subnetRef»: «[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, variables(‘virtualNetworkName’), variables(‘subnetName’))]»,
«computeApiVersion»: «2019-04-01»,
«networkApiVersion»: «2019-04-01»
},
«resources»: [
{
«name»: «[variables(‘vmName’)]»,
«type»: «Microsoft.Compute/virtualMachines»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«dependsOn»: [
«[variables(‘nicName’)]»
],
«properties»: {
«osProfile»: {
«computerName»: «[variables(‘vmName’)]»,
«adminUsername»: «[parameters(‘adminUsername’)]»,
«adminPassword»: «[parameters(‘adminPassword’)]»,
«windowsConfiguration»: {
«provisionVmAgent»: «true»
}
},
«hardwareProfile»: {
«vmSize»: «[parameters(‘vmSize’)]»
},
«storageProfile»: {
«imageReference»: {
«publisher»: «MicrosoftWindowsServer»,
«offer»: «WindowsServer»,
«sku»: «2019-Datacenter»,
«version»: «latest»
},
«osDisk»: {
«createOption»: «fromImage»
},
«dataDisks»: []
},
«networkProfile»: {
«networkInterfaces»: [
{
«properties»: {
«primary»: true
},
«id»: «[resourceId(‘Microsoft.Network/networkInterfaces’, variables(‘nicName’))]»
}
]
}
}
},
{
«type»: «Microsoft.Compute/virtualMachines/extensions»,
«name»: «[concat(variables(‘vmName’), ‘/’, variables(‘vmExtensionName’))]»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«dependsOn»: [
«[concat(‘Microsoft.Compute/virtualMachines/’, variables(‘vmName’))]»
],
«properties»: {
«publisher»: «Microsoft.Compute»,
«type»: «CustomScriptExtension»,
«typeHandlerVersion»: «1.7»,
«autoUpgradeMinorVersion»: true,
«settings»: {
«commandToExecute»: «powershell.exe Install-WindowsFeature -name Web-Server -IncludeManagementTools && powershell.exe remove-item ‘C:\\inetpub\\wwwroot\\iisstart.htm’ && powershell.exe Add-Content -Path ‘C:\\inetpub\\wwwroot\\iisstart.htm’ -Value $(‘Hello World from ‘ + $env:computername)»
}
}
},
{
«type»: «Microsoft.Network/virtualNetworks»,
«name»: «[variables(‘virtualNetworkName’)]»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Virtual Network»,
«properties»: {
«addressSpace»: {
«addressPrefixes»: [
«[variables(‘vnetIpPrefix’)]»
]
},
«subnets»: [
{
«name»: «[variables(‘subnetName’)]»,
«properties»: {
«addressPrefix»: «[variables(‘subnetIpPrefix’)]»
}
}
]
}
},
{
«name»: «[variables(‘nicName’)]»,
«type»: «Microsoft.Network/networkInterfaces»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Primary NIC»,
«dependsOn»: [
«[variables(‘nsgName’)]»,
«[variables(‘virtualNetworkName’)]»
],
«properties»: {
«ipConfigurations»: [
{
«name»: «ipconfig1»,
«properties»: {
«subnet»: {
«id»: «[variables(‘subnetRef’)]»
},
«privateIPAllocationMethod»: «Dynamic»
}
}
],
«networkSecurityGroup»: {
«id»: «[resourceId(‘Microsoft.Network/networkSecurityGroups’, variables(‘nsgName’))]»
}
}
},
{
«name»: «[variables(‘nsgName’)]»,
«type»: «Microsoft.Network/networkSecurityGroups»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Network Security Group (NSG) for Primary NIC»,
«properties»: {
«securityRules»: [
{
«name»: «default-allow-rdp»,
«properties»: {
«priority»: 1000,
«sourceAddressPrefix»: «*»,
«protocol»: «Tcp»,
«destinationPortRange»: «3389»,
«access»: «Allow»,
«direction»: «Inbound»,
«sourcePortRange»: «*»,
«destinationAddressPrefix»: «*»
}
},
{
«name»: «default-allow-http»,
«properties»: {
«priority»: 1100,
«sourceAddressPrefix»: «*»,
«protocol»: «Tcp»,
«destinationPortRange»: «80»,
«access»: «Allow»,
«direction»: «Inbound»,
«sourcePortRange»: «*»,
«destinationAddressPrefix»: «*»
}
}
]
}
}
],
«outputs»: {}
}

az-vms-template.json

{
«$schema»: «https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#»,
«contentVersion»: «1.0.0.0»,
«parameters»: {
«vmSize»: {
«type»: «string»,
«defaultValue»: «Standard_D2s_v3»,
«metadata»: {
«description»: «VM size»
}
},
«vm0Name»: {
«type»: «string»,
«defaultValue»: «az-vm0»,
«metadata»: {
«description»: «VM0 name»
}
},
«vm1Name»: {
«type»: «string»,
«defaultValue»: «az-vm1»,
«metadata»: {
«description»: «VM1 name»
}
},
«adminUsername»: {
«type»: «string»,
«metadata»: {
«description»: «Admin username»
}
},
«adminPassword»: {
«type»: «securestring»,
«metadata»: {
«description»: «Admin password»
}
},
«virtualNetworkName»: {
«type»: «string»,
«defaultValue»: «az-vnet01»,
«metadata»: {
«description»: «Virtual network name»
}
}
},
«variables»: {
«vm0Name»: «[parameters(‘vm0Name’)]»,
«vm1Name»: «[parameters(‘vm1Name’)]»,
«vmExtensionName»: «customScriptExtension»,
«nic0»: «az-nic0»,
«nic1»: «az-nic1»,
«virtualNetworkName»: «[parameters(‘virtualNetworkName’)]»,
«nsgName»: «az-nsg01»,
«subnet0Name»: «subnet0»,
«subnet1Name»: «subnet1»,
«subnet1Ref»: «[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, variables(‘virtualNetworkName’), variables(‘subnet0Name’))]»,
«subnet2Ref»: «[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, variables(‘virtualNetworkName’), variables(‘subnet1Name’))]»,
«computeApiVersion»: «2019-04-01»,
«networkApiVersion»: «2019-04-01»
},
«resources»: [
{
«name»: «[variables(‘vm0Name’)]»,
«type»: «Microsoft.Compute/virtualMachines»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «The first VM»,
«dependsOn»: [
«[variables(‘nic0’)]»
],
«properties»: {
«osProfile»: {
«computerName»: «[variables(‘vm0Name’)]»,
«adminUsername»: «[parameters(‘adminUsername’)]»,
«adminPassword»: «[parameters(‘adminPassword’)]»,
«windowsConfiguration»: {
«provisionVmAgent»: «true»
}
},
«hardwareProfile»: {
«vmSize»: «[parameters(‘vmSize’)]»
},
«storageProfile»: {
«imageReference»: {
«publisher»: «MicrosoftWindowsServer»,
«offer»: «WindowsServer»,
«sku»: «2019-Datacenter»,
«version»: «latest»
},
«osDisk»: {
«createOption»: «fromImage»
},
«dataDisks»: []
},
«networkProfile»: {
«networkInterfaces»: [
{
«properties»: {
«primary»: true
},
«id»: «[resourceId(‘Microsoft.Network/networkInterfaces’, variables(‘nic0’))]»
}
]
}
}
},
{
«type»: «Microsoft.Compute/virtualMachines/extensions»,
«name»: «[concat(variables(‘vm0Name’), ‘/’, variables(‘vmExtensionName’))]»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«dependsOn»: [
«[concat(‘Microsoft.Compute/virtualMachines/’, variables(‘vm0Name’))]»
],
«properties»: {
«publisher»: «Microsoft.Compute»,
«type»: «CustomScriptExtension»,
«typeHandlerVersion»: «1.7»,
«autoUpgradeMinorVersion»: true,
«settings»: {
«commandToExecute»: «powershell.exe Install-WindowsFeature -name Web-Server -IncludeManagementTools && powershell.exe remove-item ‘C:\\inetpub\\wwwroot\\iisstart.htm’ && powershell.exe Add-Content -Path ‘C:\\inetpub\\wwwroot\\iisstart.htm’ -Value $(‘Hello World from ‘ + $env:computername)»
}
}
},
{
«name»: «[variables(‘vm1Name’)]»,
«type»: «Microsoft.Compute/virtualMachines»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «The second VM»,
«dependsOn»: [
«[variables(‘nic1’)]»
],
«properties»: {
«osProfile»: {
«computerName»: «[variables(‘vm1Name’)]»,
«adminUsername»: «[parameters(‘adminUsername’)]»,
«adminPassword»: «[parameters(‘adminPassword’)]»,
«windowsConfiguration»: {
«provisionVmAgent»: «true»
}
},
«hardwareProfile»: {
«vmSize»: «[parameters(‘vmSize’)]»
},
«storageProfile»: {
«imageReference»: {
«publisher»: «MicrosoftWindowsServer»,
«offer»: «WindowsServer»,
«sku»: «2019-Datacenter»,
«version»: «latest»
},
«osDisk»: {
«createOption»: «fromImage»
},
«dataDisks»: []
},
«networkProfile»: {
«networkInterfaces»: [
{
«properties»: {
«primary»: true
},
«id»: «[resourceId(‘Microsoft.Network/networkInterfaces’, variables(‘nic1’))]»
}
]
}
}
},
{
«type»: «Microsoft.Compute/virtualMachines/extensions»,
«name»: «[concat(variables(‘vm1Name’), ‘/’, variables(‘vmExtensionName’))]»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«dependsOn»: [
«[concat(‘Microsoft.Compute/virtualMachines/’, variables(‘vm1Name’))]»
],
«properties»: {
«publisher»: «Microsoft.Compute»,
«type»: «CustomScriptExtension»,
«typeHandlerVersion»: «1.7»,
«autoUpgradeMinorVersion»: true,
«settings»: {
«commandToExecute»: «powershell.exe Install-WindowsFeature -name Web-Server -IncludeManagementTools && powershell.exe remove-item ‘C:\\inetpub\\wwwroot\\iisstart.htm’ && powershell.exe Add-Content -Path ‘C:\\inetpub\\wwwroot\\iisstart.htm’ -Value $(‘Hello World from ‘ + $env:computername)»
}
}
},
{
«type»: «Microsoft.Network/virtualNetworks»,
«name»: «[variables(‘virtualNetworkName’)]»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Virtual Network»,
«properties»: {
«addressSpace»: {
«addressPrefixes»: [
«10.60.0.0/22»
]
},
«subnets»: [
{
«name»: «[variables(‘subnet0Name’)]»,
«properties»: {
«addressPrefix»: «10.60.0.0/24»
}
},
{
«name»: «[variables(‘subnet1Name’)]»,
«properties»: {
«addressPrefix»: «10.60.1.0/24»
}
}
]
}
},
{
«name»: «[variables(‘nic0’)]»,
«type»: «Microsoft.Network/networkInterfaces»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Primary NIC»,
«dependsOn»: [
«[variables(‘nsgName’)]»,
«[concat(‘Microsoft.Network/virtualNetworks/’, variables(‘virtualNetworkName’))]»
],
«properties»: {
«ipConfigurations»: [
{
«name»: «ipconfig1»,
«properties»: {
«subnet»: {
«id»: «[variables(‘subnet1Ref’)]»
},
«privateIPAllocationMethod»: «Dynamic»
}
}
],
«networkSecurityGroup»: {
«id»: «[resourceId(‘Microsoft.Network/networkSecurityGroups’, variables(‘nsgName’))]»
}
}
},
{
«name»: «[variables(‘nic1’)]»,
«type»: «Microsoft.Network/networkInterfaces»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Primary NIC»,
«dependsOn»: [
«[variables(‘nsgName’)]»,
«[concat(‘Microsoft.Network/virtualNetworks/’, variables(‘virtualNetworkName’))]»
],
«properties»: {
«ipConfigurations»: [
{
«name»: «ipconfig1»,
«properties»: {
«subnet»: {
«id»: «[variables(‘subnet2Ref’)]»
},
«privateIPAllocationMethod»: «Dynamic»
}
}
],
«networkSecurityGroup»: {
«id»: «[resourceId(‘Microsoft.Network/networkSecurityGroups’, variables(‘nsgName’))]»
}
}
},
{
«name»: «[variables(‘nsgName’)]»,
«type»: «Microsoft.Network/networkSecurityGroups»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Network Security Group (NSG) for Primary NIC»,
«properties»: {
«securityRules»: [
{
«name»: «default-allow-rdp»,
«properties»: {
«priority»: 1000,
«sourceAddressPrefix»: «*»,
«protocol»: «Tcp»,
«destinationPortRange»: «3389»,
«access»: «Allow»,
«direction»: «Inbound»,
«sourcePortRange»: «*»,
«destinationAddressPrefix»: «*»
}
},
{
«name»: «default-allow-http»,
«properties»: {
«priority»: 1100,
«sourceAddressPrefix»: «*»,
«protocol»: «Tcp»,
«destinationPortRange»: «80»,
«access»: «Allow»,
«direction»: «Inbound»,
«sourcePortRange»: «*»,
«destinationAddressPrefix»: «*»
}
}
]
}
}
],
«outputs»: {}
}

Plantillas ARM

$location = 'eastus'
$rgName = 'az-rg1'
New-AzResourceGroup -Name $rgName -Location $location
New-AzResourceGroupDeployment `
   -ResourceGroupName $rgName `
   -TemplateFile $HOME/az-vms-template.json `
   -TemplateParameterFile $HOME/az-vm-parameters.json `
   -AsJob

$rgName = 'az-rg2'
New-AzResourceGroup -Name $rgName -Location $location

New-AzResourceGroupDeployment `
   -ResourceGroupName $rgName `
   -TemplateFile $HOME/az-vm-template.json `
   -TemplateParameterFile $HOME/az-vm-parameters.json `
   -nameSuffix 2 `
   -AsJob

$rgName = 'az-rg3'
New-AzResourceGroup -Name $rgName -Location $location

New-AzResourceGroupDeployment `
   -ResourceGroupName $rgName `
   -TemplateFile $HOME/az-vm-template.json `
   -TemplateParameterFile $HOME/az-vm-parameters.json `
   -nameSuffix 3 `
   -AsJob

$virtualNetwork1 =az-vnet01
$virtualNetwork2 =az-vnet02
$virtualNetwork3 =az-vnet03

Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork1-myVirtualNetwork2 `
  -VirtualNetwork $virtualNetwork1 `
  -RemoteVirtualNetworkId $virtualNetwork2.Id

Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork2-myVirtualNetwork1 `
  -VirtualNetwork $virtualNetwork2 `
  -RemoteVirtualNetworkId $virtualNetwork1.Id

Get-AzVirtualNetworkPeering `
  -ResourceGroupName myResourceGroup `
  -VirtualNetworkName myVirtualNetwork1 `
  | Select PeeringState

Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork2-myVirtualNetwork3 `
  -VirtualNetwork $virtualNetwork2 `
  -RemoteVirtualNetworkId $virtualNetwork3.Id

Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork3-myVirtualNetwork2 `
  -VirtualNetwork $virtualNetwork3 `
  -RemoteVirtualNetworkId $virtualNetwork2.Id

Get-AzVirtualNetworkPeering `
  -ResourceGroupName myResourceGroup `
  -VirtualNetworkName myVirtualNetwork2 `
  | Select PeeringState

$PIP=Get-AzPublicIpAddress `
  -Name az-vm0 `
  -ResourceGroupName myResourceGroup | Select IpAddress

mstsc /v:$PIP

New-NetFirewallRule –DisplayName "Allow ICMPv4-In" –Protocol ICMPv4

mstsc /v:10.1.0.4
ping 10.0.0.4

Install-WindowsFeature RemoteAccess -IncludeManagementTools
Install-WindowsFeature -Name Routing -IncludeManagementTools -IncludeAllSubFeature
Install-WindowsFeature -Name "RSAT-RemoteAccess-Powershell"
Install-RemoteAccess -VpnType RoutingOnly
Get-NetAdapter | Set-NetIPInterface -Forwarding Enabled

Contribuciones

Las solicitudes de extracción son bienvenidas. Para cambios importantes, abra primero un problema para discutir qué le gustaría cambiar.

Asegúrese de actualizar las pruebas según corresponda.

Fabian Alberto Campo Microsoft Most Valuable Professional 2018-2020 Microsoft Certified Trainer /LinkedIn Learning Author Website: [www.campohenriquez.com] LinkedIn: [https://www.linkedin.com/in/fcampo/] Twitter: [https://twitter.com/fcampo] Youtube: [https://www.youtube.com/channel/UC5_-RLpII-4R_xyF6R4CZ2Q?view_as=subscriber]