chaining az calls in a powershell script - azure

I'm trying to build a script that sets up my Azure environment, but passing information from one call to the next is proving to be tricky. I'm not sure how to treat the data returned as an object.
# az network public-ip create output (truncated)
#{
# "publicIp": {
# "ipAddress": "1.1.1.1",
# }
#}
$staticIpCreate = (az network public-ip create --resource-group mygroup --name myipname --allocation-method static | ConvertFrom-Json)
$staticIp = ($staticIpCreate | Select-Object ipAddress)
Write-Host "Static Ip :$($staticIp)"

You do not need to combine them, here is PowerShell command to achieve the samething
$PIP = New-AzureRmPublicIpAddress -AllocationMethod Static -ResourceGroupName DDemo -Location Westus2 -Name DDemoIPTest
Write-Host "Static IP:" $PIP.IpAddress
Image

from jessehouwing's comment
Write-Debug "////// static ip"
$staticIpCreate = az network public-ip create --resource-group mygroup --name myipname --allocation-method static | ConvertFrom-Json
$staticIp = $staticIpCreate.publicIp.ipAddress
Write-Host "Static Ip :$($staticIp)"

Related

Adding vnet integration for the multiple Azure webapp slots using powershell or azure cli

I'm trying to Vnet integrate the multiple webapps and slots using powershell. Where enabling vnet integration for webapps is working fine, but in the same way for webapp slots its not working.
$RGName = "web app resource group name "
$vnetName = "yashvnet01"
$VnetRG = "vnet name"
$subnetName = "subnet name"
$Vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $VnetRG
$subnet = Get-AzVirtualNetworkSubnetConfig -Name $subnetName -VirtualNetwork $Vnet
$Vnet.Id
##Add vnet integration to the webapps in the specific Resource group
$Webapps=Get-AzWebApp -ResourceGroupName $RGname
$Webapps.Name
ForEach($webapp in $Webapps.Name)
{
Write-Host "Adding Vnet intergation to the $webapp"
az webapp vnet-integration add --resource-group $RGname --name $webapp --vnet $Vnet.Id --subnet $subnetName
Write-Host "Successfully added Vnet intergation to the $webapp"
}
How can we do the same for multiple webapp slot.
I would be glad if someone helps me on this.
Cheers
Rewanth
You can use the below script to apply v-net intergration on the webapps slots.
Connect-AzAccount
$RGName = "yourresourcegroupname"
$vnetName = "vnetname"
$VnetRG = "vnet resource group name"
$subnetName = "subnetname"
$Vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $VnetRG
$subnet = Get-AzVirtualNetworkSubnetConfig -Name $subnetName -VirtualNetwork $Vnet
$Vnet.Id
$Webapps=Get-AzWebApp -ResourceGroupName $RGname
$Webapps.Name
##Add vnet integration to the webapps slots in the specific Resource group
ForEach($webapp in $Webapps.Name)
{
#Webapp slot
$WebappsSlot = Get-AzWebAppSlot -ResourceGroupName $RGName -Name $webapp
$WebappsSlot.Name
ForEach($webappSlot in $WebappsSlot.Name) {
$s = $webappSlot -replace $webapp + "/"
Write-Host "Adding Vnet intergation to the $s"
az webapp vnet-integration add --resource-group $RGname --name $webapp --vnet $Vnet.Id --subnet $subnetName -s $s
Write-Host "Successfully added Vnet intergation to the $s"
}
}
Output for test:
Note:
Please make sure to use the updated az version while running the above code . The az cli version used for the above is 2.71.1 . You can upgrade az version using command az upgrade in powershell.

creating AKS cluster with managed identity and associated with an acr by az cli script error

I am new to power-shell scripts and I tried to run below script that will create an AKS-cluster with managed identity also associated with an ACR . But it was giving an error at "managed identity" line..
Param(
[parameter(Mandatory = $false)]
[string]$subscriptionName = "azure-subcription",
[parameter(Mandatory = $false)]
[string]$resourceGroupName = "demoRG",
[parameter(Mandatory = $false)]
[string]$resourceGroupLocaltion = "East US 2",
[parameter(Mandatory = $false)]
[string]$clusterName = "nginxCluster",
[parameter(Mandatory = $false)]
[int16]$workerNodeCount = 3,
[parameter(Mandatory = $false)]
[string]$kubernetesVersion = "1.19.3",
[parameter(Mandatory = $false)]
[string]$acrRegistryName = "ngAcrRegistrydemo"
)
# Set Azure subscription name
Write-Host "Setting Azure subscription to $subscriptionName" -ForegroundColor Yellow
az account set --subscription=$subscriptionName
$aksRgExists = az group exists --name $resourceGroupName
Write-Host "$resourceGroupName exists : $aksRgExists"
if ($aksRgExists -eq $false) {
# Create resource group name
Write-Host "Creating resource group $resourceGroupName in region $resourceGroupLocaltion" -ForegroundColor Yellow
az group create `
--name=$resourceGroupName `
--location=$resourceGroupLocaltion `
--output=jsonc
}
$aks = az aks show `
--name $clusterName `
--resource-group $resourceGroupName `
--query name | ConvertFrom-Json
$aksCLusterExists = $aks.Length -gt 0
if ($aksCLusterExists -eq $false) {
# Create AKS cluster
Write-Host "Creating AKS cluster $clusterName with resource group $resourceGroupName in region $resourceGroupLocaltion" -ForegroundColor Yellow
az aks create `
--resource-group=$resourceGroupName `
--name=$clusterName `
--node-count=$workerNodeCount `
--enable-managed-identity `
--output=jsonc `
--kubernetes-version=$kubernetesVersion `
--aks-custom-headers="CustomizedUbuntu=aks-ubuntu-1804,ContainerRuntime=containerd" `
--attach-acr=$acrRegistryName
}
# Get credentials for newly created cluster
Write-Host "Getting credentials for cluster $clusterName" -ForegroundColor Yellow
az aks get-credentials `
--resource-group=$resourceGroupName `
--name=$clusterName `
--overwrite-existing
Write-Host "Successfully created cluster $clusterName with $workerNodeCount node(s)" -ForegroundColor Green
Write-Host "Creating cluster role binding for Kubernetes dashboard" -ForegroundColor Green
# kubectl create clusterrolebinding kubernetes-dashboard `
# -n kube-system `
# --clusterrole=cluster-admin `
# --serviceaccount=kube-system:kubernetes-dashboard
Error Msg is coming like as "az: error: unrecognized arguments: --enable-managed-identity".
Please help or give suggestions on how to enable managed identity also associated with AKS-clusters.
Many Thanks,
First, there is no parameter --aks-custom-headers of the CLI command az aks create, and the other two-parameter --enable-managed-identity and --attach-acr. You can try it again without the character =, just append the value behind the parameters:
az aks create `
--resource-group $resourceGroupName `
--name $clusterName `
--node-count $workerNodeCount `
--enable-managed-identity `
--kubernetes-version $kubernetesVersion `
--attach-acr $acrRegistryName
You can take a look at the command az aks create. In addition, that's managed identity, not the service principal, so you need to use the command az identity list to get the identity of the AKS in the node group and you can get the node group through CLI command like below:
az aks show -g aksGroup -n aksCluster --query nodeResourceGroup
I updated Azure CLI (version 2.15.1 or later) by using below
https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-windows?tabs=azure-powershell
and executed aks creation ps-script as above and it working perfectly .
AKS-infrastructure are created .
Many Thanks..

Unable to deploy Azure ARM with parameters using az cli from powershell script

Trying simple deployment with parameters from a PS script:
$prefix = "xxx"
$location = "switzerlandnorth"
az deployment group create `
--name $timestamp `
--resource-group $resourceGroupName `
--mode incremental `
--verbose `
--template-file .\src\ops\scripts\arm.json `
--parameters "{ `"location`": { `"value`": `"$location`" },`"projectPrefix`": { `"value`": `"$prefix`" } }"
Response with error:
Unable to parse parameter: { location: { value: switzerlandnorth }, projectPrefix: { value: xxx } }
Running from a PS1 script.
As we can see in the error that it is unable to parse the parameters. The correct way to pass the parameters to the az deployment group create command is:
az deployment group create `
--name $timestamp `
--resource-group $resourceGroupName `
--mode "incremental" `
--verbose `
--template-file ".\src\ops\scripts\arm.json" `
--parameters '{ \"location\": { \"value\": \"switzerlandnorth\" },\"projectPrefix\": { \"value\": \"xxx\" } }'
Update:
If you want to pass the PowerShell variables in the Parameters you can do something like below -
$location = "switzerlandnorth"
$projectPrefix = "xxx"
$params = '{ \"location\": { \"value\": \" ' + $location + '\" },\"projectPrefix\": { \"value\": \"' + $projectprefix + '\" } }'
az deployment group create `
--name $timestamp `
--resource-group $resourceGroupName `
--mode "incremental" `
--verbose `
--template-file ".\src\ops\scripts\arm.json" `
--parameters $params
Hope this helps!
Another way you can think of this is using objects/hashtables in PS and then converting to JSON, e.g.
$param = #{
location = "switzerlandnorth"
prefix = "foo"
}
$paramJSON = ($param | ConvertTo-Json -Depth 30 -Compress).Replace('"', '\"') # escape quotes in order to pass the command via pwsh.exe
az deployment group create -g $resourceGroupName--template-file "azuredeploy.json" -p $paramJson
This is a similar example:
https://gist.github.com/bmoore-msft/d578c815f319af7eb20d9d97df9bf657
I'll throw in my two cents here because previous answers are slim on what we are actually doing here. In short the az deployment group create command wants the --parameters argument to be a double serialized JSON string {scoff}. In order to create a value that can be handled by az deployment group create we would need to do something like this:
$stupidlyFormattedParam = #{
someAppSetting1 = #{ value = "setting 1" }
someAppSetting2 = #{ value = "setting 2" }
} | ConvertTo-Json -Compress -Depth 10 | ConvertTo-Json
az deployment group create --name someName--resource-group someGroup --parameters $stupidlyFormattedParam --template-file .\someFile.json

Azure Powershell (Az module) get public IP address

With the new Az module for Azure, does anyone have the syntax for getting the public IP address of an Azure VM using the name?
The commandlet Get-AzPublicIpAddress has no argument for the VM name, only the IP object name
This works, but I'm not using the machine name here, it's the name of the IP object itself:
$CurrentIp = (Get-AzPublicIpAddress -ResourceGroupName 'RG1' -Name 'MyVMname-ip').IpAddress
I can't figure out how to just get it from the VM object i.e. this doesn't work:
Get-AzVM -ResourceGroupName 'RG1' -Name 'MyVMname' | Get-AzPublicIpAddress
As I know, it's impossible to get the VM public IP through just one PowerShell Get-AzPublicIpAddress with the VM name. And the public IP in Azure is an individual resource associated with the network interface, not the VM.
As you see, there no parameter for VM name to get the public IP in that document. But you can get the public IP through a PowerShell script just with the VM name and resource group name. The script shows below:
$vm = Get-AzureRmVM -ResourceGroupName yourRG -Name vmNamme
$nic = $vm.NetworkProfile.NetworkInterfaces[0].Id.Split('/') | select -Last 1
$publicIpName = (Get-AzureRmNetworkInterface -ResourceGroupName yourRG -Name $nic).IpConfigurations.PublicIpAddress.Id.Split('/') | select -Last 1
$publicIpAddress = (Get-AzureRmPublicIpAddress -ResourceGroupName yourRG -Name $publicIpName).IpAddress
Write-Output $vmName $publicIpAddress
Or just one CLI command to get the public IP like this:
az vm show -d -g yourRG -n vmName --query publicIps
I think this is a more thorough answer, as this uses PowerShell Az as the original question intended to use. In addition, it leverages Generic.List[psobject] which is useful for later playing with the data.
$rg = 'RgName'
$Ips = Get-AzNetworkInterface -ResourceGroupName $rg
$vmDetails = New-Object "System.Collections.Generic.List[psobject]"
foreach ($instance in $Ips){
$Vm = ($instance.VirtualMachine).Id.Split('/') | select -Last 1
$PrivateIp = $instance.IpConfigurations.PrivateIpAddress
$PublicIp = (Get-AzPublicIpAddress -ResourceGroupName $rg -Name ($instance.IpConfigurations.publicIpAddress.Id.Split('/') | select -Last 1)).IpAddress
$obj = New-Object psobject -Property #{
ResourceGroupName = $rg
VmName = $vm
PrivateIp = $PrivateIp
PublicIp = $PublicIp
}
$vmDetails.Add($obj)
}
Write-Output $vmDetails
This isn't as straight forward as Az CLI unfortunately but a good script to have regardless for Az modules.
Here's my take on Andrew Harris' answer, it filters out network interfaces not attached to machines and accounts for VMs that don't have a public IP:
function Get-VmIP {
<#
.SYNOPSIS
Returns the IP addresses for all VMs in the current subscription.
#>
[cmdletbinding()]
param()
$Interfaces = Get-AzNetworkInterface
foreach ($Interface in $Interfaces) {
if ($Interface.VirtualMachine) {
$VMName = $Interface.VirtualMachine.Id.split('/')[-1]
$PrivateIP = $Interface.IpConfigurations.PrivateIpAddress
$PublicIP = if ($Interface.IpConfigurations.publicIpAddress) {
Get-AzPublicIpAddress -Name ($instance.IpConfigurations.publicIpAddress.Id.Split('/')[-1]).IpAddress
}
[PSCustomObject]#{
VMName = $VMName
RGName = $Interface.ResourceGroupName
PrivateIP = $PrivateIP
PublicIP = $PublicIP
}
}
}
}
This is a corrected version of the Mark Wragg's script earlier in this thread:
function Get-VmIP {
<#
.SYNOPSIS
Returns the IP addresses for all VMs in the current subscription.
#>
[cmdletbinding()]
param()
$Interfaces = Get-AzNetworkInterface
foreach ($Interface in $Interfaces) {
if ($Interface.VirtualMachine) {
$VMName = $Interface.VirtualMachine.Id.split('/')[-1]
$PrivateIP = $Interface.IpConfigurations.PrivateIpAddress
$PublicIpAddressConfig = $Interface.IpConfigurations.publicIpAddress
$PublicIP = $null
$pconfigname = $null
if ($PublicIpAddressConfig) {
$pconfigname = $PublicIpAddressConfig.Id.Split('/')[-1]
$PublicIP = (Get-AzPublicIpAddress -Name $pconfigname).IpAddress
}
[PSCustomObject]#{
VMName = $VMName
RGName = $Interface.ResourceGroupName
PrivateIP = $PrivateIP
PublicIP = $PublicIP
}
}
}
}
The accepted answer uses AzureRM PowerShell module which is now obsoleted by Az module:
$VM = Get-AzVM -ResourceGroupName $ResourceGroupName -VMName $VMName
$NetworkInterfaceName = $VM.NetworkProfile.NetworkInterfaces[0].Id.Split('/')[-1]
$NetworkInterface = Get-AzNetworkInterface -ResourceGroupName $VM.ResourceGroupName -Name $NetworkInterfaceName
$PublicIpAddressName = $NetworkInterface.IpConfigurations.PublicIpAddress.Id.Split('/')[-1]
$PublicIpAddress = Get-AzPublicIpAddress -ResourceGroupName $VM.ResourceGroupName -Name $PublicIpAddressName
Write-Host "IP: $($PublicIpAddress.IpAddress), FQDN: $($PublicIpAddress.DnsSettings.Fqdn)"
Scope of the script is within an Azure subscription.
Below is the one-liner script which returns Name, PublicIpAllocaitonMethod(It's basically the type of the IP address whether it's a Static or Public IP) and the IpAddress properties of all the Network interfaces in a subscription.
(Get-AzNetworkInterface ).IpConfigurations.PublicIpAddress.Id | Foreach-Object -Process {$_.Split('/')| select -Last 1} | Foreach-Object -Process {Get-AzPublicIpAddress -Name $_} | Format-List Name, PublicIpAllocationMethod,IpAddress
If we remove the last statement Format-List it will display all the properties of the network interfaces that are having public IP addresses.

Easier way of retrieving an Azure VM's Public IP address

Using the name/resource group of a specific VM, I'm trying to get the VM's public IP address.
This code works but it seems unwieldy in comparison to other AzureRM cmdlets.
$VM = Get-AzureRmVM -ResourceGroupName MyResourceGroup -Name MyVMName
$NIC = $VM.NetworkProfile.NetworkInterfaces[0].Id -replace '.*\/'
$NI = Get-AzureRmNetworkInterface -Name $NIC -ResourceGroupName MyResourceGroup
$NIIC = Get-AzureRmNetworkInterfaceIpConfig -NetworkInterface $NI
$PIP = $NIIC.PublicIpAddress.Id -replace '.*\/'
$PIP = Get-AzureRmPublicIpAddress -Name $PIP -ResourceGroupName MyResourceGroup
$PIP.IpAddress
Is there a quicker/easier/shorter way of accessing this information?
As far as i know, Not Yet for PowerShell. But you can use Azure CLI
az vm list-ip-addresses -n <VMName> -g <ResourceGroup> | grep publicIpAddresses
Try the Azure CLI command:
az vm list-ip-addresses -g groupName -n vmName --query "[].virtualMachine.network.publicIpAddresses[*].ipAddress" -o tsv
Or the PowerShell command just filter with your vm name:
$ipAddress= (Get-AzureRmPublicIpAddress -ResourceGroupName groupName | Where-Object { $_.IpConfiguration.Id -like "*vmName*" }
)
$ipAddress.IpAddress
It's possible. This script will list all VMs PIP in your Azure cloud.
OLD
$VM_int = Get-AzureRmResource -ODataQuery "`$filter=resourcetype 'Microsoft.Compute/virtualMachines'"
foreach($int in $VM_int){
$vmName = $int.Name
$ipAddress= (Get-AzureRmPublicIpAddress -ResourceGroupName $int.ResourceGroupName | Where-Object { $_.IpConfiguration.Id -like "*$vmName*" })
$vmName + ' --- ' + $ipAddress.IpAddress
}
UPDATE
Unfortunately, Get-AzVM doesn't provide the Public IP address of VM, but we can scrape its Network Interface Name and make a wildcard search of it through all assigned Public IPs which NIC name are matched.
It's not fast but will provide with correct results.
$array = #()
foreach ($vm in Get-AzVM) {
$vmNicName = $vm.NetworkProfile.NetworkInterfaces.Id.Split("/")[8]
$ipAddress = Get-AzPublicIpAddress | Where-Object {$_.IpConfiguration.Id -like "*$vmNicName*"}
if ($null -ne $ipAddress) {
$pipInput = New-Object psobject -Property #{
VM = $vm.Name
PublicIP = $ipAddress.IpAddress
}
$array += $pipInput
}
}
The way i got the value for my Linux VM's was using below code.
Get-AzureRmPublicIpAddress -ResourceGroupName <yourRG> -Name <yourVMName> | Select-Object {$_.IpAddress}
This will return something of this sort:
$_.IpAddress
------------
52.170.56.60
This outputs a bit of information however the public IP address is in there.
Get-AzPublicIpAddress -ResourceGroupName MyResourceGroup | Where-Object {$_.name -like "*MyVMName*" }
Or you can do this to just get the IP address:
Get-AzPublicIpAddress -ResourceGroupName MyResourceGroup | Where-Object {$_.name -like "*MyVMName*" } | Select-Object { $_.IpAddress }
Output is like:
$_.IpAddress
--------------
13.255.162.33
You can also match the AzPublicIpAddress IpConfiguration.Id with the VM's NetworkInterfaces.Id:
Get-AzPublicIpAddress | ?{$_.IpConfiguration.Id -match "$((Get-AzVM -Name $computername).NetworkProfile.NetworkInterfaces.Id).*" }
#Get the VM object
$vm = Get-AzVM -Name $vmName -Status
#Get name of network adapter object attached to VM
$NetworkInterfaceName = $vm.NetworkProfile.NetworkInterfaces.Id.Split("/") | Select -Last 1
#Get network adaptor object attached to VM
$NetworkInterfaceObject = Get-AzNetworkInterface -Name $NetworkInterfaceName
#Get public IP Address object name attached to network adaptor object
$ipObjectName = $NetworkInterfaceObject.IpConfigurations.PublicIpAddress.Id.Split("/") | Select -Last 1
#get publivc IP Address attached to public IP Address object
$ipObject = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -Name $ipObjectName
Write-Output $ipObject.IpAddress
Yet another method from within a Linux VM.
First, install the Azure command-line tools in the VM, see Azure docs
Second, execute the following in a shell on the VM:
az network public-ip list --query "[?dnsSettings.domainNameLabel=='MY_VM']"
where MY_VM is (hopefully) the host name of your VM. The command returns a multiline JSON string which is a list. Example is shown below:
[
{
"dnsSettings": {
"domainNameLabel": "MY_VM",
"fqdn": "my_vm.westeurope.cloudapp.azure.com"
},
"etag": "W/\"some_uuid...\"",
...
"ipAddress": "AAA.BBB.CCC.DDD",
},
...
]
How to parse the FQDN and the public IP out of this is left as an exercise to the reader :-)

Resources