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]

Reflexiones relativas

En la palabra de hoy Dios hace referencia a un fin de los tiempos, donde «el cielo y las estrellas pasaran, pero su palabra no pasara y sera eterna». pero aquellos que con sus buenas obras y su buena actitud de servicio, su vocacion y dedicacion les va haciendo ganar «DiviPoints» o «GodPoints», estaran ahorrando en una moneda eterna, y eterea, pero sobre todo habran de ser recordados por sus buenas acciones, Yo he sido un mal inversionista por lo general, un apostador que toma muchos riesgos y que ha amado incondicionalmente, que por amor he hecho muchas cosas desafiantes o que representaban un gran reto, un gran esfuerzo o una ambicion mas alla de lo debido, también he sido una persona desprendida del dinero y siempre me ha gustado darme lujos y vivir cómodamente.

Hay diferentes tipos de ahorros que he aprendido con el tiempo, y como bien dicen, nunca es suficiente, ni en el sexo, ni en el amor, ni en el dinero, pero sobretodo hay que aprender a ser ahorrativos y buenos administradores en cuanto al tiempo, la salud, y lo espiritual. Todo es cuestion de habitos, si tenemos un espiritu competitivo, o combativo, estamos dejando de ser compasivos y serviciales. hay que vivir en un balance, en armonia, buscando un equilibrio, como el yin y el yan, sin pecados no hay virtudes, sin maldad no hay bondad, sin oscuridad no hay luz, pero debemos procurar por vivir mas inclinados hacia la luz, y reflexionar constantemente si nuestras acciones nos hacen daño, o nos hacen un bien… puede que comernos una hamburguesa no nos haga daño, pero realmente nos esta haciendo un bien?

Hacer una alimentación consciente, donde practiques la buena y regular hidratacion, al menos unos dos litros de agua diariamente es una forma de ahorrar.  Si tu reduces un litro a vasos de 250 CC, son 4 vasitos, así que tienes 4 horas en la mañana, y 4 horas en la tarde para tomarte 8 vasitos de agua, esto se te empieza a notar de inmediato pues ayudas a tu cuerpo a eliminar azúcares, grasas, y aquellas sustancias que potencialmente pueden a la larga afectar tu cuerpo, y ayuda a que tus riñones y tu hígado puedan cumplir su misión depuradora. Vuelvo a la reflexion, tomarme 2 litros de agua me hace daño, o me hace mas daño tomarme 8 cafe americanos?

La alimentación consiste también en consumir más calorías durante el día pero no dulces ni energizantes, sino frutas como el melón la papaya o la sandía que además de ser muy ricas, te dan una sensación de saciedad por su alto contenido de agua, su dulce sabor y su textura. Cuando aumentas el consumo de frutas, reduces la cantidad de espacio disponible para comer chatarras como papitas de paquete, ponquesitos y galletas, mi visión del ahorro en este enfoque es que con cada galleta de chocochispas tu cuerpo está ingiriendo muchas más calorías de las que va a requerir, incluso en una sesión de entrenamiento funcional. Mientras que consumiendo frutas, estas alimentándote más sano y seguramente una fruta te cuesta lo mismo que un tente en pie de panadería o de paquete. Una manzana, un banano, una granadilla o una pera, puedes llevarla en tu mochila incluso hasta puedes hacer chips de manzana si es que extrañas la sensación de las papitas de paquete.

Alimentándose bien estas haciendo un ahorro para que tu salud a largo plazo sea mejor. Tener que procesar demasiadas harinas como panes, arroz y otras similares solo harán que tu páncreas se desgaste y que llegues a tener que usar insulina. asi que me pregunto si cervezas y licores, bebidas gaseosas, azucaradas y energizantes nos hacen realmente bien?

Otra forma de ahorrar está relacionada con los dientes, porque tener el buen hábito de lavar tus dientes después de comer, suena a demasiado rígido, pero a la larga permitirá que disfrutes tu dentadura original por muchos más años, sin los padecimientos de usar implantes o prótesis dentales. Muchas veces por nuestros trabajos apenas si sacamos tiempo para comer algo, pero si no respetamos los hábitos como el cepillado de dientes, la factura no se hace esperar y la placa se acumula, se producen caries y finalmente dolores de muelas mortales.

Otra forma de ahorro que incluí en mi vida es el ahorrar tiempo. La producción de tiempo es imposible así que diariamente tenemos una carrera contra el reloj, nuevos 86000 segundos, recortarle tiempo al sueño te pasa facturas increíbles a tu salud mental, así que pagarte un día productivo con una jornada de reposo y recuperación de energías completa de ocho horas es lo menos que puedes hacer, por eso hay que aprovechar el tiempo del día, para no restarle horas al sueño. Tener el buen hábito del sueño te garantiza tener energía al día siguiente, tener un buen estado de ánimo, y cuando trasnochas eres más proclive a comer más, y a tener pensamientos tristes y conflictivos, descansar bien es un ahorro, pues puedes disfrutar de un nuevo día desde temprano, ver nuevos destinos, salir a caminar, a conocer, pero si has dormido poco o muy mal, no vas a tener ganas ni de pararte al medio día..  el sueño no se recupera, no es cierto el dicho de «ya descansaré cuando me muera!» En realidad ese tiempo de sueño no se recupera jamás.

Organizar el día con listas de pendientes, calendario en mano para estar con pleno uso de conciencia de las actividades y tareas del día es mi manera de aprovechar el tiempo productivo del día. Se que pendientes tengo, que entrega debo cumplir y de que espacio dentro de mi tiempo dispongo, desde que adquiri este hábito, tomo unos minutos al día en planear el día, organizar y visualizar a que hora me estaré desocupando. Gracias a herramientas como el calendario de mi celular, o los manejadores de tareas, se puede organizar a que destinos planeas ir durante el día, tiempos de recorrido y disponibilidad de los recursos. No planear las cosas puede hacerte perder mucho tiempo, ir a hacer diligencias sin llevar los documentos necesarios te hará perder la cita, la fila y sobretodo tu tiempo.

Acostumbra dedicar unos minutos diariamente a organizar tus ideas, tus pensamientos y actividades pendientes. Esto te dará claridad de las cosas que debes hacer, los pagos del día, los compromisos, y tus resposabilidades, pero sobre todo lo que tu quieres, lo unico que importa al final del dia es lo que tu quieres, aquello que deseas de corazon, eso que te motiva. Tambien te ayudara a identificar si estas viviendo con balance positivo o si por el contrario estas restandote vida con tu comportamiento desenfrenado e inmediatista. vivir el presente, atender lo que la vida te presenta en el momento es una vida de Bombero, que requiere que siempre estes alerta, y siempre estes preparado para casi cualquier evento, porque cuando te toca atender una inundacion no puedes ir con el equipo que se atiende un incendio. esto te obliga a vivir bajo un enorme estres, y vivir bajo estres no es una vida de calidad. para entrar en control debes tener la posibilidad de pensar lo que viene, preveer y prepararte.

El estudio es otra de esas cosas que considero un ahorro, uno que capitalizas porque lo conviertes en experiencia para tu vida laboral o para tus relaciones personales. En donde se aprende, que tipo de experiencia adquieres y sobretodo con que personas compartes el conocimiento es parte crucial de tu desarrollo y se va ahorrando dia por dia, con el tiempo que te dedicas a aprender, a reflexionar y a desarrollar tus habilidades. es como hacer ejercicio, pero para tus neuronas, considerando que dejar de ejercitarlas te lleva a un deterioro del conocimiento y a un olvido de lo aprendido.

Reputation points

Recuerdo que hace mucho, mucho tiempo atras, cuando aun existia la Microsoft TechNet, las personas que activamente aportabamos, participabamos de foros, preguntas, y validabamos respuestas obteniamos unos puntos de reconocimiento, y veo que para la nueva plataforma de Q&A que integraron a la pagina de documentacion de Microsoft, https://docs.microsoft.com/en-us/answers/products/ empezaron a valer tambien un modelo similar, donde por tu participacion seras reconocido y entre mas logres interactuar mas puntos de reconocimiento en la comunidad conseguiras. Lamentablemente los puntos obtenidos en la vieja TechNet no fueron migrados, asi como el historial de cursos de la extinta Microsoft Virtual Academy, simplemente se trato de un nuevo borron y cuenta nueva. Al parecer la misma mecanica aplicara para las certificaciones que no se renueven anualmente, pues Microsoft ahora considera necesario validar anualmente los conocimientos en soluciones evergreen como Microsoft365 y Azure, que como tienen semanalmente releases de nuevas funcionalidades, es preciso refrendar y actualizar los conocimientos. Desde mi punto de vista como Trainer Certificado, esto le ofrece una dinamica, que mantendra girando la cadena del entrenamiento, incorporando los materiales de fundamentacion en Microsoft Learn, y los cursos de especializacion presenciales o virtuales con los centros de entrenamiento, los laboratorios ahora ya no dependen de las maquinas que anteriormente preparabamos especialmente para cada estudiante en cada curso, ahora son via escritorio remoto, y los examenes que ahora tambien se pueden presentar desde tu propio computador complementan este modelo de entrenamiento donde el que quiere estudiar, preparar sus examenes, y mejorar sus habilidades y competencias laborales ahora tiene todo en la yema de los dedos, al alcance de sus manos, y en la disponibilidad de tiempo que se permita para estudiar. Como participante activo, como autor de contenidos y como Ingeniero curioso que soy, los invito a esta comunidad, a participar colectivamente, siempre con la conciencia de lo colectivo, pensando que a otras personas les puede estar pasando la misma situacion y que la documentacion responsable, la investigacion diligente, y la solucion de problemas son nuestro diario que hacer en la informatica aplicada a resolver problemas de la humanidad. Tengan presente que si nuestro comentario es SPAM, o el moderador considera ofensivo o un contenido no apropiado, restara de nuestro puntaje 10 puntos.

ActivityPoints earned
You sign in into Microsoft Q&A for the first time1
Your feedback gets approved50
One of the feedback you voted for gets approved5
You have content reported for moderation-10
You had content reported for moderation and the moderator found it was not spam10
You received a vote to a question, answer, comment, or feedback5
You accepted an answer on a question you posted20
A user accepted your answer75
https://docs.microsoft.com/en-us/answers/support/reputation-points