Toggle an Application Gateway WAF to Prevention/Detection mode - azure-powershell

Goal:
Toggle an application Gateway WAF between prevention and detection mode via code.
Configuration Details:
App GW SKU: WAFv2
Application Gateway WAF deployed
Custom rules and managed policies are implemented
WAF is Associated to Application Gateway
Pre-requisite Commands:
$policyName = *Input*
$appGWName = *Input*
$appGWRG = *Input*
$location = *Input*
$gw = Get-AzApplicationGateway -Name $appGWName -ResourceGroupName $appGWRG
$policy = Get-AzApplicationGatewayFirewallPolicy -Name $policyName -ResourceGroupName $appGWRG
What I've attempted:
Manually I am able to switch from prevention to detection. (Successful)
Using a Powershell command I'm able to update the WAF policy setting directly, but it does not replicate to the resource itself.
$policy.PolicySettings.Mode = "Prevention"
$policy.PolicySettings.Mode = "Detection"
Using Powershell command I'm able to update the WAF policy via the Appliction gateway, but it doesn't replicate to the WAF or Application gateway.
Set-AzApplicationGatewayWebApplicationFirewallConfiguration -FirewallMode Detection -ApplicationGateway $gw -Enabled $true
Getting the following error:
quoteSet-AzApplicationGateway: WebApplicationFirewallConfiguration cannot be changed when there is a WAF Policy /subscriptions/7bba5d50-5df8-49be-b59d-b737e7663335/resourceGroups/pbolkun-RG/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/WafPolicyProdEusAgw associated with it.
I've also tried Set-AzApplicationGateway -ApplicationGateway $gw at the end of each implementation which again, doesn't work..
I'd like a programmatic way so that I can utilize IaC to the max. I'd prefer to avoid deploying an ARM template each time I want to switch between the two for testing.
Thank you in advanced!

I tested the same in my environment by creating a App Gateway & WAF Policy and associating the policy to the App Gateway.
Then I used the below code to change the Firewall Policy Setting and update the application gateway :
param
(
[string] $policyName = "ansumanwafpolicy",
[string]$appGWName = "appansumangw",
[string]$appGWRG = "ansumantest",
[string]$location = "West US 2",
[string] $policyMode = "Detection"
)
$gw = Get-AzApplicationGateway -Name $appGWName -ResourceGroupName $appGWRG
$policy= Get-AzApplicationGatewayFirewallPolicy -Name $policyName -ResourceGroupName $appGWRG
$update = #{
Mode = $policyMode
State = $policy.PolicySettings.State
RequestBodyCheck = $policy.PolicySettings.RequestBodyCheck
MaxRequestBodySizeInKb = $policy.PolicySettings.MaxRequestBodySizeInKb
FileUploadLimitInMb = $policy.PolicySettings.FileUploadLimitInMb
}
$UpdatePolicy = Set-AzApplicationGatewayFirewallPolicy -Name $policyName -ResourceGroupName $appGWRG -PolicySetting $update
$UpdateAPPGW = Set-AzApplicationGatewayWebApplicationFirewallConfiguration -FirewallMode $policyMode -ApplicationGateway $gw -Enabled $gw.WebApplicationFirewallConfiguration.Enabled -RuleSetType $gw.WebApplicationFirewallConfiguration.RuleSetType -RuleSetVersion $gw.WebApplicationFirewallConfiguration.RuleSetVersion
Output:
It doesn't reflect immediately but running the get appgw command after few mins it shows the change like below:

Related

Is there a way to determine AWS SES service availability in a region?

Is there a way to determine if ses has a local region available using AWS SDK?
After registering e-mail service with Core Middleware services.AddAWSService<IAmazonSimpleEmailService>() I want to find and assign the SES local region to e-mail service if there is one available. Using .Net Core 2.1 and AWS SDK. Thank you!
I believe this link contains information you are interested in - https://aws.amazon.com/blogs/aws/new-query-for-aws-regions-endpoints-and-more-using-aws-systems-manager-parameter-store/
Here’s how to get the list of regions where a service (Amazon Athena,
in this case) is available:
$ aws ssm get-parameters-by-path \
--path /aws/service/global-infrastructure/services/athena/regions --output json | \
jq .Parameters[].Value
"ap-northeast-2"
"ap-south-1"
"ap-southeast-2"
"ca-central-1"
"eu-central-1"
"eu-west-1"
"eu-west-2"
"us-east-1"
"us-east-2"
"us-gov-west-1"
"ap-northeast-1"
"ap-southeast-1"
"us-west-2"
https://www.nuget.org/packages/AWSSDK.SimpleSystemsManagement/ NuGet package can be used to achieve same via .NET SDK. For your example the code to get the set of regions where SES is available can look like
var client = new AmazonSimpleSystemsManagementClient(...);
var path = "/aws/service/global-infrastructure/services/ses/regions";
var response = await client.GetParametersByPathAsync(new GetParametersByPathRequest
{
Path = path
}).ConfigureAwait(false);
var regions = new HashSet<string>(response.Parameters.Select(x => x.Value));
while (!string.IsNullOrWhiteSpace(response.NextToken))
{
response = await client.GetParametersByPathAsync(new GetParametersByPathRequest
{
Path = path,
NextToken = response.NextToken
}).ConfigureAwait(false);
foreach (var parameter in response.Parameters) regions.Add(parameter.Value);
}

enable / disable scaling on Azure VMSS with powershell

Is there a way to enable or disable scaling for an Azure VMSS without providing all the rules and profiles to Add-AzureRmAutoscaleSetting
According to this there is the -DisableSetting switch which you can use to achieve what you want
Done it using the following powershell:
$myResourceGroup = 'my_rsg'
$myLocation = 'West Europe'
$myScaleName = 'scalename'
$scale = Get-AzureRmAutoscaleSetting -ResourceGroupName $myResourceGroup -Name $myScaleName
Add-AzureRmAutoscaleSetting -AutoscaleProfile $scale.Profiles `
-Location $myLocation `
-Name $scale.Name `
-ResourceGroupName $myResourceGroup `
-TargetResourceId $scale.TargetResourceUri `
-DisableSetting

Azure automation - credentials delivered by Get-PSAutomationCredential don't work with Add-AzureAccount?

I'm modifying a gallery runbook that copies a live database to a test database on a schedule. It's failing at the first hurdle; authenticating and selecting the relevatn azure subscription
The runbook looks like this:
$Cred = Get-AutomationPSCredential -Name 'automationCredential'
Write-Output "UN: $($Cred.Username)"
Add-AzureAccount -Credential $Cred
I've used the portal credentials blade to create a credential named "automationCredential". For the username and password I supplied the username/pw that I log into the azure portal with. Note: this is NOT a school/work microsoft account, but a personal one
I can tell the call to Get-PSAutomationCredential is working out, because the Write-Ouput call shows the correct value
Add-AzureAccount however, delivers the following error:
Add-AzureAccount : unknown_user_type: Unknown User Type At
Set-DailyDatabaseRestore:22 char:22 CategoryInfo :
CloseError: (:) [Add-AzureAccount], AadAuthenticationFailedException
FullyQualifiedErrorId :
Microsoft.WindowsAzure.Commands.Profile.AddAzureAccount
Any pointers how to get a working credential?
According to your description, it seems that your account is a Microsoft account(such as *#outlook.com, *#hotmail.com). Microsoft does not support non-interactive login. It is also unsafe for you to use your account to login your subscription directly. For a runbook, you could use the following codes to logon.
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
In above code, you need use connection AzureRunAsConnection, it is created by Azure default, you could use it directly, you could check this connection, it includes your subscription information.
Also, you could create a new connection, please refer to this link.
Have you tried using the resource manager version off the login cmdlet (Add-AzureRmAccount)?

Create point-to-site connection for all web apps slots using powershell

I'm following the tutorial from here https://azure.microsoft.com/pl-pl/documentation/articles/app-service-vnet-integration-powershell/
where I've a script which allows me to connect multiple web apps with VNet.
The issue is our web apps have few deployment slots and when this script is run it only updates currently used slot.
I wasn't able to get web app from different slot by the name, also I don't see any parameter which would apply my configuration to all slots.
Script for the reference:
function ConnectWebAppWithVNet()
{
param(
$SubscriptionId,
$VNetResourceGroupName,
$AppResourceGroupName,
$WebAppName,
$VNetName,
$GatewayName,
$P2SRootCertName2,
$MyP2SCertPubKeyBase64_2
)
$webApp = Get-AzureRmResource -ResourceName $WebAppName -ResourceType "Microsoft.Web/sites" -ApiVersion 2015-08-01 -ResourceGroupName $AppResourceGroupName
$location = $webApp.Location
$vnet = Get-AzureRmVirtualNetwork -name $VNetName -ResourceGroupName $VNetResourceGroupName
$gateway = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $vnet.ResourceGroupName -Name $GatewayName
# validate gateway types, etc.
if($gateway.GatewayType -ne "Vpn")
{
Write-Error "This gateway is not of the Vpn type. It cannot be joined to an App."
return
}
if($gateway.VpnType -ne "RouteBased")
{
Write-Error "This gateways Vpn type is not RouteBased. It cannot be joined to an App."
return
}
if($gateway.VpnClientConfiguration -eq $null -or $gateway.VpnClientConfiguration.VpnClientAddressPool -eq $null)
{
Write-Host "This gateway does not have a Point-to-site Address Range. Please specify one in CIDR notation, e.g. 10.0.0.0/8"
return
}
Write-Host "Creating App association to VNET"
$propertiesObject = #{
"vnetResourceId" = "/subscriptions/$($subscriptionId)/resourceGroups/$($vnet.ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($vnetName)"
}
$virtualNetwork = New-AzureRmResource -Location $location -Properties $propertiesObject -ResourceName "$($webAppName)/$($vnet.Name)" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" -ApiVersion 2015-08-01 -ResourceGroupName $AppResourceGroupName -Force
# We need to check if the certificate here exists in the gateway.
$certificates = $gateway.VpnClientConfiguration.VpnClientRootCertificates
$certFound = $false
foreach($certificate in $certificates)
{
if($certificate.PublicCertData -eq $virtualNetwork.Properties.CertBlob)
{
$certFound = $true
break
}
}
if(-not $certFound)
{
Write-Host "Adding certificate"
Add-AzureRmVpnClientRootCertificate -ResourceGroupName $VNetResourceGroupName -VpnClientRootCertificateName "AppServiceCertificate.cer" -PublicCertData $virtualNetwork.Properties.CertBlob -VirtualNetworkGatewayName $gateway.Name
}
# Now finish joining by getting the VPN package and giving it to the App
Write-Host "Retrieving VPN Package and supplying to App"
$packageUri = Get-AzureRmVpnClientPackage -ResourceGroupName $vnet.ResourceGroupName -VirtualNetworkGatewayName $gateway.Name -ProcessorArchitecture Amd64
# Put the VPN client configuration package onto the App
$PropertiesObject = #{
"vnetName" = $vnet.Name; "vpnPackageUri" = $packageUri
}
New-AzureRmResource -Location $location -Properties $propertiesObject -ResourceName "$($webAppName)/$($vnet.Name)/primary" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections/gateways" -ApiVersion 2015-08-01 -ResourceGroupName $AppResourceGroupName -Force
Write-Host "Finished!"
}
If your web app is already connected to VPN there is a way to connect also its slot.
$webAppName = "name_of_app_service"
$resourceGroup = "name_of_resource_group"
$vnetName = "name_of_vnet"
$slotName = "staging"
$resName = $webAppName + "/" + $slotName
$WebAppConfig = Get-AzureRmResource -ResourceGroupName $resourceGroup -ResourceType Microsoft.Web/sites/slots/config -ResourceName $resName -ApiVersion 2016-08-01
$WebAppConfig.Properties.vnetName = $vnetName
Set-AzureRmResource -ResourceId $WebAppConfig.ResourceId -Properties $WebAppConfig.Properties -ApiVersion 2016-08-01 # -Force
I've manged to get help from Azure support and we've found out the problem:
I've created secondary slot without cloning the configuration
settings from main slot. If this setting would be selected,
secondary slot would be connected automatically. In my case I couldn't recreate slot so I needed to manually
connect secondary slot after swapping.

Azure database backup to blob using Powershell

We need to backup the azure database and store it on blob so that it can be restored. I've seen this blog but it uses the third party cmdlets.
http://weblogs.thinktecture.com/cweyer/2011/01/automating-backup-of-a-sql-azure-database-to-azure-blob-storage-with-the-help-of-powershell-and-task-scheduler.html
Could someone please guide/help how above can be achieved using powershell.
Backing up to WA Blob Store is not supported from Azure DB, rather the service does automatic backups for you with PITR capability. You'll find the following documentation useful:
http://msdn.microsoft.com/en-us/library/azure/hh852669.aspx
http://msdn.microsoft.com/en-us/library/azure/jj650016.aspx
Hope this helps.
Here is my powershell script
https://gist.github.com/voxon2/be29a3fd6dabbb9155ca
Here is an article describing many different approaches other than powershell
http://blogs.msdn.com/b/mast/archive/2013/03/04/different-ways-to-backup-your-windows-azure-sql-database.aspx
First get your Azure Automation Settings done (see here).
Edit the blow script and save it as .ps1 file. When you run it for
the first time, it will ask you both your azure automation account and
your database credentials. During this process, it will save your
credentials in a local file securely (see here how it is done). After this time on wards, it uses the saved credentials.
The .psl file and the encrypted credential files should be stored in one
directory
Once you are happy you can schedule it to run in task scheduler.
function Get-MyCredential
{
param(
$CredPath,
[switch]$Help
)
$HelpText = #"
Get-MyCredential
Usage:
Get-MyCredential -CredPath `$CredPath
If a credential is stored in $CredPath, it will be used.
If no credential is found, Export-Credential will start and offer to
Store a credential at the location specified.
"#
if($Help -or (!($CredPath))){write-host $Helptext; Break}
if (!(Test-Path -Path $CredPath -PathType Leaf)) {
Export-Credential (Get-Credential) $CredPath
}
$cred = Import-Clixml $CredPath
$cred.Password = $cred.Password | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PsCredential($cred.UserName, $cred.Password)
Return $Credential
}
function Export-Credential($cred, $path) {
$cred = $cred | Select-Object *
$cred.password = $cred.Password | ConvertFrom-SecureString
$cred | Export-Clixml $path
}
#Create a directory with you azure server name to isolate configurations
$FileRootPath = "C:\PowerShellScripts\AzureServerName"
Write-Host "Getting Azure credentials"
$AzureCred = Get-MyCredential ($FileRootPath + "AzureSyncred.txt")
#Use Azure Automation Account
#(If You do not have it will not work with other accounts)
Add-AzureAccount -Credential $AzureCred
Select-AzureSubscription -SubscriptionId "myAzureSubscriptionId"
#DO NOT use tcp:myServerName.database.windows.net,1433 but only myServerName
$ServerName = "myServerName"
$Date = Get-Date -format "yyyy-MM-dd-HH-mm"
$DatabaseName = "myTargetDatabaseName"
$BlobName = $Date + "-" + $DatabaseName.bacpac"
$StorageName = "myStorageAccountName"
$ContainerName = "myContainerNameToStoreBacpacFiles"
$StorageKey = "myStorageAccountKey"
Write-Host "Getting database user credential"
#DO NOT use myDatabaseUsername#myServerName but only myDatabaseUsername
$credential = Get-MyCredential ($FileRootPath + "DbSyncred.xml")
Write-Host "Connecting to Azure database"
$SqlCtx = New-AzureSqlDatabaseServerContext -ServerName $ServerName -Credential $credential
Write-Host "Connecting to Blob storage"
$StorageCtx = New-AzureStorageContext -StorageAccountName $StorageName -StorageAccountKey $StorageKey
$Container = Get-AzureStorageContainer -Name $ContainerName -Context $StorageCtx
Write-Host "Exporting data to blob"
$exportRequest = Start-AzureSqlDatabaseExport -SqlConnectionContext $SqlCtx -StorageContainer $Container -DatabaseName $DatabaseName -BlobName $BlobName
Get-AzureSqlDatabaseImportExportStatus -Request $exportRequest
# use the below script in powershell to execute the script
# powershell -ExecutionPolicy ByPass –File C:\PowerShellScripts\AzureServerName\mySavedScript.ps1 –noexit