Fix for the Subnet Missing Required Delegation - azure

I have a Azure Resource Group and it has a vnet. The vnet has a subnet which has two service endpoints configured namely Microsoft.keyVault and Microsoft.Storage and the subnet also has a subnet delegation to Microsoft.Web/serverFarms.
Now I want to add another service endpoint Microsoft.ServiceBus to the same vnet using Azure Powershell. I executed the below code for that.
$virtualNetwork = Get-AzVirtualNetwork -ResourceGroupName $ResourceGroupName
Set-AzVirtualNetworkSubnetConfig -Name $virtualNetwork.Subnets.Name -VirtualNetwork $virtualNetwork -AddressPrefix $virtualNetwork.Subnets.AddressPrefix -ServiceEndpoint "Microsoft.ServiceBus"
$virtualNetwork | Set-AzVirtualNetwork
But the above code is throwing error at the last line of code saying that the Subnet is missing Required Delegation
Subnet requires any of the following delegation(s) [Microsoft.Web/serverFarms] to reference service association link
StatusCode: 400
ReasonPhrase: Bad Request
ErrorCode: SubnetMissingRequiredDelegation
But in portal I see it has the required delegation. How to fix this error?

Even though i have already added these service endpoint in my specific subnet and subnet also has a subnet delegation to Microsoft.Web/serverFarms able to add another service endpoint Microsoft.ServiceBus.
I would suggest you to use the following PowerShell script:
PowerShell Script:
$subscription = "b83c1edXXXXXXX-XXX"
$subnets = #('TestSubnet')
$vnetName = "Vnet1"
$vnetRgName = "X-rasXXXX-XX"
$newEndpoint = "Microsoft.ServiceBus"
Set-AzContext -Subscription $subscription
foreach($snet in $subnets){
Write-Host "Modifying Service Endpoints for subnet: $snet" -fore red -back white
$virtualNetwork = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $vnetRgName | Get-AzVirtualNetworkSubnetConfig -Name $snet
$addrPrefix = $virtualNetwork.AddressPrefix
#Get existing service endpoints
$ServiceEndPoint = New-Object 'System.Collections.Generic.List[String]'
$virtualNetwork.ServiceEndpoints | ForEach-Object { $ServiceEndPoint.Add($_.service) }
if ($ServiceEndPoint -notcontains $newEndPoint){
$ServiceEndPoint.Add($newEndpoint)
}
$delegation=$virtualNetwork.Delegations
#Add new service endpoint
Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $vnetRgName | Set-AzVirtualNetworkSubnetConfig -Name $snet -AddressPrefix $addrPrefix -ServiceEndpoint $ServiceEndPoint -Delegation $delegation | Set-AzVirtualNetwork
}
Reference : Azure Powershell - Applying multiple service endpoints to a subnet

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.

Subnets are not getting created while using Powershell Az commands

I have below PowerShell script to create vnet and subnet in Azure
$virtualNetworkName = 'corp-northeurope-vnet'
$frontendSubnetName = 'frontendsubnet'
$vNetAddressPrefix = "10.0.0.0/26"
$SubnetAddressPrefix = "10.0.1.0/28"
$virtualNetwork = Get-AzVirtualNetwork -Name $virtualNetworkName -ResourceGroupName $rgName
if ($null -eq $virtualNetwork) {
$virtualNetwork = New-AzVirtualNetwork `
-Name $virtualNetworkName `
-ResourceGroupName $rgName `
-AddressPrefix $vNetAddressPrefix `
-Location $location
}
else {
Write-Log -Message "[$($virtualNetwork.Name)] already exists"
}
$fesubnet = Get-AzVirtualNetworkSubnetConfig -Name $frontendSubnetName -VirtualNetwork $virtualNetwork
if ($null -eq $fesubnet) {
$fesubnet = Add-AzVirtualNetworkSubnetConfig `
-Name $frontendSubnetName `
-AddressPrefix $subnetAddressPrefix `
-VirtualNetwork $virtualNetwork
$virtualNetwork | Set-AzVirtualNetwork
}
else {
Write-Log -Message "[$($fesubnet.Name)] already exists"
}
But It does not work.
Error throws here
$virtualNetwork | Set-AzVirtualNetwork
Subnet 'frontendsubnet' is not valid in virtual network 'corp-northeurope-vnet'. StatusCode: 400 ReasonPhrase: Bad Request ErrorCode: NetcfgInvalidSubnet ErrorMessage: Subnet 'frontendsubnet' is
| not valid in virtual network 'corp-northeurope-vnet'. OperationID : 06c1ed77-14f1-294d-a19a-41c2epbdd04f
Is it anything to do with IP Range ?
The IP Range of the subnet is not within the IP Range of the VNET this causes the Subnet configuration to be invalid.
So either you change the Subnet address prefix to be within the VNETs Address Prefix or you expand the VNETs address prefix so that it includes the range of the Subnet you are trying to create.
A good tool to use to plan your IP Address Prefixes is: http://jodies.de/ipcalc?host=10.0.0.0&mask1=26&mask2=
The error caused by your subnet address prefix. When your VNet address prefix is 10.0.0.0/26. Then your subnet addresses range should be less than 10.0.0.0/26. You can change the subnet prefix as 10.0.0.0/28. Then it will be no problem.
One problem is the second command line.
If you are saying you already have created a Vnet, a subnet, a Vnet IP CIDR prefix, and a Subnet IP CIDR prefix, the command for Subnet is Not $frontendSubnetName, "Frontend" is the name of the subnet included on Vnet "corp-northeurope-vnet".
$frontendSubnetName = 'frontendsubnet'
the command frontendSubnetName is the wrong, the correct should be:
$subnetConfig = 'frontendsubnet'
Try using these commands:
$virtualNetworkName = 'corp-northeurope-vnet'
$subnetConfig = 'frontendsubnet'
$vNetAddressPrefix = "10.0.0.0/26"
$SubnetAddressPrefix = "10.0.1.0/28"
Here the official documentation: https://learn.microsoft.com/en-us/azure/virtual-network/quick-create-powershell

Azure Powershell - Applying multiple service endpoints to a subnet

I have coded a powershell script to set an existing subnet to function as a service endpoint for multiple services. However, when I run the command line in the script, it doesn't add a new service endpoint, it just changes the existing one.
I am trying to parameterise this through Jenkins as well, which may be an added complication. I think if I can get the base syntax right then that shouldn't be a problem.
Syntax I am using is:
#Get vnet
$virtualnetwork = Get-AzureRmVirtualNetwork -Name $VN -ResourceGroupName $RG
#Configure service endpoint
Add-AzureRmVirtualNetworkSubnetConfig -Name $SN -AddressPrefix $SAP -
VirtualNetwork $virtualnetwork -ServiceEndpoint $EP
#Set configuration
$virtualnetwork | Set-AzureRmVirtualNetwork
You can use something like this to add as many endpoints as required:
$rgname = "amgar-dtl"
$vnName = "Dtlamgar-dtl"
$sname = "Dtlamgar-dtlSubnet"
$subnetPrefix = "10.0.0.0/20"
#Get vnet
$VirtualNetwork = Get-AzureRmVirtualNetwork -ResourceGroupName $rgname -Name $vnName | Get-AzureRmVirtualNetworkSubnetConfig -Name $sname
#Get existing service endpoints
$ServiceEndPoint = New-Object 'System.Collections.Generic.List[String]'
$VirtualNetwork.ServiceEndpoints | ForEach-Object { $ServiceEndPoint.Add($_.service) }
#Add new service endpoint
Get-AzureRmVirtualNetwork -ResourceGroupName $rgname -Name $vnName | Set-AzureRmVirtualNetworkSubnetConfig -Name $sname -AddressPrefix $subnetPrefix -ServiceEndpoint $ServiceEndPoint.Add("Microsoft.KeyVault") | Set-AzureRmVirtualNetwork
Hope this helps!
Successful syntax is:
#Vnet
$VN = "$ENV:VNET_NAME"
#Resource Group
$RG = "$ENV:RESOURCEGROUP_NAME"
#Subnet
$SN = "$ENV:SUBNET_NAME"
#Subnet Address Prexifx
$SAP = "$ENV:ADDRESS_PREFIX"
#ServiceEndpoint
$EP = "$ENV:SERVICE_ENDPOINT"
Write-Host "Importing the AzureRM module into the PowerShell session"
Import-Module AzureRM
Write-Host "Connect service principle account to Azure RM"
Connect-AzureRmAccount -ServicePrincipal -Credential $CREDS -TenantId $TID -Subscription $SID
#Get vnet
$VirtualNetwork = Get-AzureRmVirtualNetwork -ResourceGroupName $RG -Name $VN | Get-AzureRmVirtualNetworkSubnetConfig -Name $SN
#Get existing service endpoints
$ServiceEndPoint = New-Object 'System.Collections.Generic.List[String]'
$VirtualNetwork.ServiceEndpoints | ForEach-Object { $ServiceEndPoint.Add($_.service) }
$ServiceEndPoint.Add($EP)
#Add new service endpoint
Get-AzureRmVirtualNetwork -ResourceGroupName $RG -Name $VN | Set-AzureRmVirtualNetworkSubnetConfig -Name $SN -AddressPrefix $SAP -ServiceEndpoint $ServiceEndPoint | Set-AzureRmVirtualNetwork
Powershell does not appear to support the command $ServiceEndPoint.Add("Microsoft.KeyVault") with “|”. Once it was executed separately, the script worked.
Here is another version for those looking to process multiple subnets and to validate that the subnet doesn't already have the service endpoint enabled because it will error out if the same service is listed twice when modifying the subnet.
$subscription = "Enter Subscription ID here"
$subnets = #('my-subnet-1','my-subnet-2','my-subnet-3')
$vnetName = "MY-VNET"
$vnetRgName = "MY-VNET-RG"
$newEndpoint = "Microsoft.AzureCosmosDB"
Set-AzContext -Subscription $subscription
foreach($snet in $subnets){
Write-Host "Modifying Service Endpoints for subnet: $snet" -fore red -back white
$virtualNetwork = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $vnetRgName | Get-AzVirtualNetworkSubnetConfig -Name $snet
$addrPrefix = $virtualNetwork.AddressPrefix
#Get existing service endpoints
$ServiceEndPoint = New-Object 'System.Collections.Generic.List[String]'
$virtualNetwork.ServiceEndpoints | ForEach-Object { $ServiceEndPoint.Add($_.service) }
if ($ServiceEndPoint -notcontains $newEndPoint){
$ServiceEndPoint.Add($newEndpoint)
}
#Add new service endpoint
Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $vnetRgName | Set-AzVirtualNetworkSubnetConfig -Name $snet -AddressPrefix $addrPrefix -ServiceEndpoint $ServiceEndPoint | Set-AzVirtualNetwork
}

Azure webhook get VM status

I'm trying to do a runbook/webhook that return a status of machine. What I finally notices is that
Get-AzureRmVM
is only returning 2 resource groups. Where
Get-AzureRmResource
Does return many more but not all of them again!
I'm sure about my Resource Group Name but still it says resource group 'groupName' could not be found. when I try to run with specific name
Get-AzureRmVM -ResourceGroupName groupName
While my other start and stop runbook works just fine, so i'm confused I can't see the difference between the groups.
PS: I'm using Azure Run As Connection
param
(
[Parameter (Mandatory = $false)]
[object] $WebhookData
)
if ($WebhookData) {
$vms = (ConvertFrom-Json -InputObject $WebhookData.RequestBody)
Write-Output "Authenticating to Azure with service principal and certificate"
$ConnectionAssetName = "AzureRunAsConnection"
Write-Output "Get connection asset: $ConnectionAssetName"
$Conn = Get-AutomationConnection -Name $ConnectionAssetName
if ($Conn -eq $null)
{
throw "Could not retrieve connection asset: $ConnectionAssetName. Check that this asset exists in the Automation account."
}
Write-Output "Authenticating to Azure with service principal."
Add-AzureRmAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint | Write-Output
# Start each virtual machine
foreach ($vm in $vms)
{
$vmName = $vm.Name
Write-Output "Checking $vmName"
$vmstatus = Get-AzureRmVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroup -Status# | Select-Object -ExpandProperty StatusesText | ConvertFrom-Json
#select code index and convert to $vmpowerstate
$vmPowerState = $vmstatus#[1].Code
#Write-Output "Resource Group: $vmResourceGroupName", ("VM Name: " + $VM.Name), "Status: $VMStatusDetail" `n
Write-Output ("VM Name: " + $vmName), "Status: $vmPowerState" `n
}
}
else {
write-Error "This is webhook only."
}
Because your resource groups are in the different subscriptions.
As #et3rnal mentioned,
I have 2 subscriptions and Get-AzureRmVM returning 2 vms only because the rest are classics. The automation account I created this runbook at is the other one and I can see that in the overview? its the same one I use to start/stop machines in the other subscription!
Update:
If you want to get the PowerState of the VM, you could try the command below, in your case, just put it in the loop, the $PowerState is the PowerState.
$status = Get-AzureRmVM -Name <VM Name> -ResourceGroupName <Resource Group Name> -Status
$PowerState = ($status.Statuses | Where-Object {$_.Code -like "PowerState/*"}).DisplayStatus
Update2:
1.For the classic VM, we need to use azure ASM powershell module command, you could try Get-AzureVM, may be the Example 3: Display a table of virtual machine statuses in that link will help.
2.Another option is to migrate the classic VM(ASM) to ARM, then use the ARM command Get-AzureRmVM.
References:
Platform-supported migration of IaaS resources from classic to Azure Resource Manager
Migrate IaaS resources from classic to Azure Resource Manager by using Azure PowerShell

Not able to connect through Rasdial in azure ARM VPN connection

I am not able connect to VPN using powershell cmdlet. I use 'rasdial' from a build agent to connect to vpn, so that we can trigger automated tests. The whole process is automated.
Earlier same rasdial command - Rasdial "VPNName" was working perfectly fine with classic model (ASM) of vpn. But, after I migrated to ARM, I am facing this issue. However through UI i.e. clicking on buttons to connect to vpn is working fine but our need is to connect through script.
I am getting a message-
This function is not supported on this system.
NB: I am following this post- https://dzone.com/articles/deconstructing-azure-point
The same workaround worked in ASM but not woking in ARM. What can be another workaround or fix for this ?
I am using below script to create and download the VPN package. I am not sure I am missing something in my script which is causing this issue-
$VNetName = "MYVPN"
$SubName = "Subnet-1"
$GWSubName = "GatewaySubnet"
$VNetPrefix1 = "15.3.0.0/16"
$SubPrefix = "15.3.1.0/24"
$GWSubPrefix = "15.3.200.0/26"
$VPNClientAddressPool = "158.17.201.0/24"
$RG = "VMsRG"
$Location = "West Europe"
$DNS = "15.3.0.0"
$GWName = "GateWay"
$GWIPName = "GateWayIP"
$GWIPconfName = "GateWayIPConfig"
$P2SRootCertName = "XXXXX.cer"
$DeployUserName = "atf#hotmail.com"
$DeployUserPassword = "XXXXX"
$Azurepwd = ConvertTo-SecureString $DeployUserPassword -AsPlainText -Force
$AzureCredential = new-object -typename System.Management.Automation.PSCredential -argumentlist $DeployUserName, $Azurepwd
Add-AzureRmAccount -credential $AzureCredential -SubscriptionName Development
New-AzureRmResourceGroup -Name $RG -Location $Location
$fesub = New-AzureRmVirtualNetworkSubnetConfig -Name $SubName -AddressPrefix $SubPrefix
$gwsub = New-AzureRmVirtualNetworkSubnetConfig -Name $GWSubName -AddressPrefix $GWSubPrefix
New-AzureRmVirtualNetwork -Name $VNetName -ResourceGroupName $RG -Location $Location -AddressPrefix $VNetPrefix1 -Subnet $fesub, $gwsub -DnsServer $DNS
$vnet = Get-AzureRmVirtualNetwork -Name $VNetName -ResourceGroupName $RG
$subnet = Get-AzureRmVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet
$pip = New-AzureRmPublicIpAddress -Name $GWIPName -ResourceGroupName $RG -Location $Location -AllocationMethod dynamic
$ipconf = New-AzureRmVirtualNetworkGatewayIpConfig -Name $GWIPconfName -Subnet $subnet -PublicIpAddress $pip
$MyP2SRootCertPubKeyBase64 = "XXXXX"
$p2srootcert = New-AzureRmVpnClientRootCertificate -Name "P2SVNETRootCertName" -PublicCertData $MyP2SRootCertPubKeyBase64
New-AzureRmVirtualNetworkGateway -Name $GWName -ResourceGroupName $RG -Location $Location -IpConfigurations $ipconf -GatewayType Vpn -VpnType RouteBased -EnableBgp $false -GatewaySku Standard -VpnClientAddressPool $VPNClientAddressPool -VpnClientRootCertificates $p2srootcert
Get-AzureRmVpnClientPackage -ResourceGroupName $RG -VirtualNetworkGatewayName $GWName -ProcessorArchitecture Amd64
As I am able to connect using GUI. I hope script is doing it's job.
After 4 Months I got a reply from MS (as I raised a ticket for the same).
They told Rasdial is not supported by Azure VPN Client Package till date. Also, Even after deconstructing-the-azure-point-to-site-vpn lacks addition of route which should be taken care by adding the route explicitly.
So as an workaround I did the steps provided in the blog - http://www.diaryofaninja.com/blog/2013/11/27/deconstructing-the-azure-point-to-site-vpn-for-command-line-usage
However the last part of adding the route is a bit complex. So, for adding route I have created my own PS script-
$Subnet = #("10.0.1.0", "10.0.2.0","10.0.3.0")
$VPNClientAddressPool = "x.x.x"
$Mask = "255.255.0.0"
$azureIpAddress = ""
$VPNCmd = "MYVPNName"
Here x.x.x are the 3 octet that can be found in "GateWay - Point-to-site configuration" of the VPN-
$routeExists = route print | findstr $VPNClientAddressPool
if($routeExists)
{
route delete $Subnet
}
rasdial $VPNCmd > $null
$azureIPAddress = ipconfig | findstr $VPNClientAddressPool
if($azureIPAddress -ne $null)
{
$azureIpAddress = $azureIpAddress.Split(": ")
$azureIpAddress = $azureIpAddress[$azureIpAddress.Length-1]
$azureIpAddress = $azureIpAddress.Trim()
route add $Subnet MASK $Mask $azureIPAddress
}
This solved the purpose for me. Basically You just need to take care of the route add part.
Your PowerShell script seems fine (I didn't try the login and resource group pieces, but everything else works from $fesub on.) except for the third line from the bottom. The -Name tag which you currently have as "P2SVNETRootCertName" needs to be the same as your $P2SRootCertName. For more information, refer to Azure documentation: https://azure.microsoft.com/en-us/documentation/articles/vpn-gateway-howto-point-to-site-rm-ps/
As for Rasdial, another StackOverflow post has answered this: Azure Virtual Network Point-to-Site (ex. Azure Connect) autoconnect
-Bridget [MSFT]

Resources