How do I use Set- commands with AzureRM and Application Gateway? - azure

I am trying to run the following commands to change the settings on an existing Rule in my Azure Application Gateway:
$updatedAppGW = Set-AzureRmApplicationGatewayRequestRoutingRule -ApplicationGateway $AppGW `
-Name $ChosenSubscription.httpsRule `
-RuleType Basic `
-BackendAddressPool $backendPool `
-BackendHttpSettings $httpSettings
# Save Gateway configuration
Write-Host "[$(__LINE__)] Attempting to save changes to the Application Gateway..." -ForegroundColor Cyan
Set-AzureRmApplicationGateway -ApplicationGateway $updatedAppGW | Out-Null
The Set-AzureRmApplicationGatewayRequestRoutingRule command appears to run correctly (silently, at least).
However, when I then try to "save" the Application Gateway configuration with the command Set-AzureRmApplicationGateway I receive the error Set-AzureRmApplicationGateway : Object reference not set to an instance of an object.
I think this is because I'm not using these "Set" commands correctly.
I read online that when I run Set-AzureRmApplicationGatewayRequestRoutingRule, I'm only actually making changes to the Rule in local memory. I then have to save the changes of the Application Gateway.
Is this true? If so... how do I actually save the Application Gateway configuration in this context? Earlier in my script, when using Add-AzureRm commands (such as Add-AzureRmApplicationGatewayBackendAddressPool), I've immediately (following line) run Set-AzureRmApplicationGateway and it has worked as intended.
I have also tried altering the Set-AzureRmApplicationGateway command in the code block at the top of this post to use my original $AppGW variable instead of this $updatedAppGW variable which I think my Set-AzureRmApplicationGatewayRequestRoutingRule command is producing. Neither works - identical error.
EDIT: Additional diagnosis
Adding the following Write-Host output...
Write-Host "[$(__LINE__)] Retrieved AG Rule '$($rule.Name)'." -ForegroundColor Magenta
Write-Host "[$(__LINE__)] Attempting to change this rule to point at Backend Address Pool '$($backendPool.Name)' and HTTP Settings '$($httpSettings.Name)'..." -ForegroundColor Cyan
# Re-retrieve the Application Gateway after saving it earlier
$AppGW = Get-AzureRmApplicationGateway -Name $ChosenSubscription.appGateway -ResourceGroupName $ChosenSubscription.resourceGroup
# Re-retrieve the Backend Address Pool and HTTP Settings that we've created, for the sake of updating the rule
$backendPool = Get-AzureRmApplicationGatewayBackendAddressPool -ApplicationGateway $AppGW -Name $MaintenanceToggleBackendPool
$httpSettings = Get-AzureRmApplicationGatewayBackendHttpSettings -ApplicationGateway $AppGW -Name $MaintenanceToggleHTTPSetting
Write-Host "[$(__LINE__)] `$AppGW.Name $($AppGW.Name)" -ForegroundColor Green
Write-Host "[$(__LINE__)] `$AppGW.ProvisioningState $($AppGW.ProvisioningState)" -ForegroundColor Green
Write-Host "[$(__LINE__)] `$AppGW.OperationalState $($AppGW.OperationalState)" -ForegroundColor Green
$updatedAppGW = Set-AzureRmApplicationGatewayRequestRoutingRule -ApplicationGateway $AppGW `
-Name $ChosenSubscription.httpsRule `
-RuleType Basic `
-BackendAddressPool $backendPool `
-BackendHttpSettings $httpSettings
Write-Host "[$(__LINE__)] `$updatedAppGW.Name $($updatedAppGW.Name)" -ForegroundColor Green
Write-Host "[$(__LINE__)] `$updatedAppGW.ProvisioningState $($updatedAppGW.ProvisioningState)" -ForegroundColor Green
Write-Host "[$(__LINE__)] `$updatedAppGW.OperationalState $($updatedAppGW.OperationalState)" -ForegroundColor Green
# Save Gateway configuration
Write-Host "[$(__LINE__)] Attempting to save changes to the Application Gateway..." -ForegroundColor Cyan
Set-AzureRmApplicationGateway -ApplicationGateway $updatedAppGW | Out-Null
... gives the following console output:

OK, managed to fix the problem myself... sigh
On the Set-AzureRmApplicationGatewayRequestRoutingRule command, you must specify the -HttpListener parameter, or it will fail silently.
# Re-retrieve the Backend Address Pool and HTTP Settings that we've created, for the sake of updating the rule
$backendPool = Get-AzureRmApplicationGatewayBackendAddressPool -ApplicationGateway $AppGW -Name $MaintenanceToggleBackendPool
$httpSettings = Get-AzureRmApplicationGatewayBackendHttpSettings -ApplicationGateway $AppGW -Name $MaintenanceToggleHTTPSetting
$httpListener = Get-AzureRmApplicationGatewayHttpListener -ApplicationGateway $AppGW -Name "HttpListenerTest"
$updatedAppGW = Set-AzureRmApplicationGatewayRequestRoutingRule -ApplicationGateway $AppGW `
-Name $ChosenSubscription.httpsRule `
-RuleType Basic `
-BackendAddressPool $backendPool `
-BackendHttpSettings $httpSettings `
-HttpListener $httpListener
This is why the Set-AzureRmApplicationGateway command wasn't working properly - it had a malformed RequestRoutingRule in its memory.

Related

Azure CLI - Set Azure Application Gateway Backend settings

I have created a Powershell script that calls the Az module..."az network application-gateway probe create" - https://learn.microsoft.com/en-us/cli/azure/network/application-gateway/probe?view=azure-cli-latest#az-network-application-gateway-probe-create
I have read the documentation on the above command but can't work out how to set 'backend settings' - the field marked below by the black line as shown below - any thoughts?
The 'Backend Settings' field is a drop-down box that does list the 'http settings' I want to set the value to - remember I want to do this via; ARM or CLI not manually via the Azure Portal..
I tried to reproduce the same in my environment and got the results successfully like below:
To create the Probe and associated Backend settings, I used the below command while creating probe via CLI:
$probe = New-AzApplicationGatewayProbeConfig -Name probe01 -Protocol Http -HostName 'XXX.com' -Path '/path/path.htm' -Interval 30 -Timeout 120 -UnhealthyThreshold 8
$poolSetting = New-AzApplicationGatewayBackendHttpSettings -Name poolsetting01 -Port 80 -Protocol Http -CookieBasedAffinity Disabled -Probe $probe -RequestTimeout 80
I created the application gateway with all the required parameters like below:
$appgw = New-AzApplicationGateway -Name appgwtest -ResourceGroupName appgw-rg -Location 'West US' -BackendAddressPools $pool -Probes $probe -BackendHttpSettingsCollection $poolSetting -FrontendIpConfigurations $fipconfig -GatewayIpConfigurations $gipconfig -FrontendPorts $fp -HttpListeners $listener -RequestRoutingRules $rule -Sku $sku
In the Portal, Application Gateway created successfully with Backend settings like below:
To add a new probe to an existing application gateway and set Backend Settings, please use the below commands:
$appgw = Get-AzApplicationGateway -Name applicationgatewayname -ResourceGroupName ResourceGroupName
$probe = Add-AzApplicationGatewayProbeConfig -ApplicationGateway $appgw -Name probetest -Protocol Http -HostName 'XXX.com' -Path '/path/custompath.htm' -Interval 30 -Timeout 120 -UnhealthyThreshold 8
$appgw = Set-AzApplicationGatewayBackendHttpSettings -ApplicationGateway $appgw -Name $appgw.BackendHttpSettingsCollection.name -Port 80 -Protocol Http -CookieBasedAffinity Disabled -Probe $probe -RequestTimeout 120
Set-AzApplicationGateway -ApplicationGateway $appgw

Azure Automation Job runs fine manually but fails when triggered by webhook

I've got an Automation Account in Azure that runs a Powershell runbook.
It runs perfectly fine when I trigger it via the portal, manually specifying the inputs
I've created a webhook with the same input settings. I call it from CURL like
curl -d '' https://800b2bec-b1ae-4fa1-ba30-8c7d32096828.webhook.ae.azure-automation.net/webhooks?[redactedtoken]
The webhook shows as triggered successfully in the portal, however the job fails with no visible error.
There is no output, even though the first line in my powershell function is Write-Output "Hello"
There are no exception messages, no logs at all.
Any idea how I might get more information as to what might be going wrong?
I've updated the Az modules and enabled verbose logging in the runbook.
Full source below, if it helps.
Param(
[string]$resourceGroup,
[string]$VMName,
[string]$method,
[string]$UAMI
)
Write-Output "Hello"
$automationAccount = "AlsAutomation"
# Ensures you do not inherit an AzContext in your runbook
Disable-AzContextAutosave -Scope Process | Out-Null
# Connect using a Managed Service Identity
try {
$AzureContext = (Connect-AzAccount -Identity).context
}
catch{
Write-Output "There is no system-assigned user identity. Aborting.";
exit
}
# set and store context
$AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription `
-DefaultProfile $AzureContext
if ($method -eq "SA")
{
Write-Output "Using system-assigned managed identity"
}
elseif ($method -eq "UA")
{
Write-Output "Using user-assigned managed identity"
# Connects using the Managed Service Identity of the named user-assigned managed identity
$identity = Get-AzUserAssignedIdentity -ResourceGroupName $resourceGroup `
-Name $UAMI -DefaultProfile $AzureContext
# validates assignment only, not perms
if ((Get-AzAutomationAccount -ResourceGroupName $resourceGroup `
-Name $automationAccount `
-DefaultProfile $AzureContext).Identity.UserAssignedIdentities.Values.PrincipalId.Contains($identity.PrincipalId))
{
$AzureContext = (Connect-AzAccount -Identity -AccountId $identity.ClientId).context
# set and store context
$AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext
}
else {
Write-Output "Invalid or unassigned user-assigned managed identity"
exit
}
}
else {
Write-Output "Invalid method. Choose UA or SA."
exit
}
# Get current state of VM
$status = (Get-AzVM -ResourceGroupName $resourceGroup -Name $VMName `
-Status -DefaultProfile $AzureContext).Statuses[1].Code
Write-Output "`r`n Beginning VM status: $status `r`n"
# Start or stop VM based on current state
if($status -eq "Powerstate/deallocated")
{
Start-AzVM -Name $VMName -ResourceGroupName $resourceGroup -DefaultProfile $AzureContext
}
elseif ($status -eq "Powerstate/running")
{
Stop-AzVM -Name $VMName -ResourceGroupName $resourceGroup -DefaultProfile $AzureContext -Force
}
# Get new state of VM
$status = (Get-AzVM -ResourceGroupName $resourceGroup -Name $VMName -Status `
-DefaultProfile $AzureContext).Statuses[1].Code
Write-Output "`r`n Ending VM status: $status `r`n `r`n"
Write-Output "Account ID of current context: " $AzureContext.Account.Id
We have tested this in our local environment it is working fine, Below statements are based on the analysis.
In our local environment, We have created a Powershell runbook running with different PowerShell Versions 7.1 & Version 5.1.
Using the above share Script & webhook URI, when we are trying to invoke the runbook (PowerShell version 7.1) using the `Invoke-webRequest method it is continuously failing.
Alternatively, We have tried to invoke the runbook (PowerShell version 5.1) using the Invoke-webRequest method it is working fine.
We would suggest you to use Powershell Version 5.1 instead of 7.1 in your Runbook.
Here is the sample Output for reference:

Azure - Add http listener to existing ApplicationGateway through ps command

I am trying to add a new listener to existing Azure application gateway using powershell script. Here's the command I have used.
Add-AzApplicationGatewayHttpListener -ApplicationGateway $Appgw -Name $listenerName -FrontendIPConfiguration $fipconfig -FrontendPort $port -SslCertificate $cert -HostName $hostName -Protocol "Https" -Debug
All the variables are correctly initialized. Command executes well and return ApplicationGateway object which seems normal. However the newly added listener is not visible in Azure portal. After watching carefully the new listener in ApplicationGateway object (in powershell) it just show below resource path,
/subscriptions/<subscription-id>/resourceGroups/ResourceGroupNotSet/providers/Microsoft.Network/applicationGateways/ApplicationGatewayNameNotSet/httpListeners/<new-listener-name>
two things doesn't seem normal here,
ResourceGroupNotSet
ApplicationGatewayNameNotSet
Can anyone please suggest what could be the reason behind this? and why the listener is not shown in portal at all?
According to my test, if we want to add HTTP listener to existing Azure Application gateway with Powershell, we need to run the command Set-AzApplicationGateway -ApplicationGateway $appgw after you run the command Add-AzApplicationGatewayHttpListener. Because the command Add-AzApplicationGatewayHttpListener just will create a new HTTP listener but it will not update the application gateway.
Connect-AzAccount
$AppGWname ="stantest"
$groupName="stan"
$ipName="appGwPublicFrontendIp"
$portName="port_80"
$listenerName="test1"
$appgw= Get-AzApplicationGateway -Name $AppGWname -ResourceGroupName $groupName
$FEC= Get-AzApplicationGatewayFrontendIPConfig -Name $ipName -ApplicationGateway $appgw
Add-AzApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name $portName -Port 80
$port =Get-AzApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name $portName
Add-AzApplicationGatewayHttpListener -ApplicationGateway $appgw -Name $listenerName -FrontendIPConfiguration $FEC -FrontendPort $port -Protocol Http
Set-AzApplicationGateway -ApplicationGateway $appgw

How to add Azure Scaleset to Log Analytics

How do I add Azure Scale Set to Log analytics. From log analytics I am able to see the VM but unlike VMs the connect button is not enabled. What do I need to do. to enable this connection.
There is a MSDN post regarding this issue:
https://blogs.msdn.microsoft.com/timomta/2018/04/09/how-to-add-the-oms-client-to-a-vm-scale-set/
As mentioned in the post, we explain how to do this for VMs but not for VMSS. You can accomplish this via PowerShell and the linked blog above describes how to achieve it.
I will add the script below for users who don't want to follow the link
select-azurermsubscription -subscriptionid ‘your subscription id’
$PublicSettings = #{"workspaceId" = "your oms workspace id"}
$ProtectedSettings = #{"workspaceKey" = "your big base64 oms key"}
# Get information about the scale set
$vmss = Get-AzureRmVmss -ResourceGroupName 'VMSSRESOURCEGROUP' `
-VMScaleSetName 'VMSSNAME'
Add-AzureRmVmssExtension `
-VirtualMachineScaleSet $vmss `
-Name "Microsoft.EnterpriseCloud.Monitoring" `
-Publisher "Microsoft.EnterpriseCloud.Monitoring" `
-Type "MicrosoftMonitoringAgent" `
-TypeHandlerVersion 1.0 `
-AutoUpgradeMinorVersion $true `
-Setting $PublicSettings `
-ProtectedSetting $ProtectedSettings
# Update the scale set and apply the Custom Script Extension to the VM instances
Update-AzureRmVmss `
-ResourceGroupName $vmss.ResourceGroupName `
-Name $vmss.Name `
-VirtualMachineScaleSet $vmss
# Only needed for manual update VMSS – warning tells them all to update, so modify to suit
$jobs=#()
Get-AzureRmVmssVM -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name | foreach {
$jobs+=Update-AzureRmVmssInstance -ResourceGroupName $vmss.ResourceGroupName -Name $vmss.Name -InstanceId $_.InstanceId -AsJob
}
$jobs | Wait-Job
$jobs | Receive-Job
Kudos to the author https://social.msdn.microsoft.com/profile/Tim+Omta

Setting IP Restrictions to all slots in an AppService Web App using powershell

I have a PS script which contains something like this to set IP restrictions on a Web App. This works great, however our PROD Web App has a Staging slot. How can I set the same restrictions in all slots? Unfortunately this is not yet supported by the portal..
# Update IP restrictions if modified
$WebAppConfig.properties.ipSecurityRestrictions = $ArrayList
$WebAppConfig | Set-AzureRmResource -ResourceGroupName $ResourceGroupName -ResourceType Microsoft.Web/sites/config -ResourceName $WebApp/web -ApiVersion $APIVersion -Force | Out-Null
Huge thanks!
Try the script as below, my Webapp named joywebapp2, the slot named slot1, the script set the slot with the same IpSecurityRestrictions of the Webapp, if you have several slots, just use a loop.
$IpSecurityRestrictions = (Get-AzureRmWebApp -ResourceGroupName joywebapp -Name joywebapp2).SiteConfig.IpSecurityRestrictions
$slot = Get-AzureRmWebAppSlot -ResourceGroupName joywebapp -Name joywebapp2 -Slot slot1
$slot.SiteConfig.ipSecurityRestrictions = $IpSecurityRestrictions
$slot | Set-AzureRmWebAppSlot
Update:
If you want to use Az module, the command should be like as below.
$IpSecurityRestrictions = (Get-AzWebApp -ResourceGroupName joywebapp -Name joywebapp2).SiteConfig.IpSecurityRestrictions
$slot = Get-AzWebAppSlot -ResourceGroupName joywebapp -Name joywebapp2 -Slot slot1
$slot.SiteConfig.ipSecurityRestrictions = $IpSecurityRestrictions
$slot | Set-AzWebAppSlot

Resources