Setup Azure Function from Powershell

I am doing the exact same thing to create a dev sandbox environment.

Provisioning function apps is a gap in the Az Powershell module but it does appear to be possible.

I provisioned my function app by following the steps here https://clouddeveloper.space/2017/10/26/deploy-azure-function-using-powershell/ but changed it to use an existing app service plan instead of consumption plan.

$AppServicePlan = "abc-123"
$AppInsightsKey = "your key here"
$ResourceGroup = "MyRgName"
$Location = "westeurope"
$FunctionAppName = "MyFunctionName"
$AzFunctionAppStorageAccountName = "MyFunctionAppStorageAccountName"
$FunctionAppSettings = @{
    ServerFarmId="/subscriptions/<GUID>/resourceGroups/$ResourceGroup/providers/Microsoft.Web/serverfarms/$AppServicePlan";
    alwaysOn=$True;
}

# Provision the function app service
New-AzResource -ResourceGroupName $ResourceGroup -Location $Location -ResourceName $FunctionAppName -ResourceType "microsoft.web/sites" -Kind "functionapp" -Properties $FunctionAppSettings -Force | Out-Null

$AzFunctionAppStorageAccountKey = Get-AzStorageAccountKey -ResourceGroupName $ResourceGroup -AccountName $AzFunctionAppStorageAccountName | Where-Object { $_.KeyName -eq "Key1" } | Select-Object Value
$AzFunctionAppStorageAccountConnectionString = "DefaultEndpointsProtocol=https;AccountName=$AzFunctionAppStorageAccountName;AccountKey=$($AzFunctionAppStorageAccountKey.Value)"
$AzFunctionAppSettings = @{
    APPINSIGHTS_INSTRUMENTATIONKEY = $AppInsightsKey;
    AzureWebJobsDashboard = $AzFunctionAppStorageAccountConnectionString;
    AzureWebJobsStorage = $AzFunctionAppStorageAccountConnectionString;
    FUNCTIONS_EXTENSION_VERSION = "~2";
    FUNCTIONS_WORKER_RUNTIME = "dotnet";
}

# Set the correct application settings on the function app
Set-AzWebApp -Name $FunctionAppName -ResourceGroupName $ResourceGroup -AppSettings $AzFunctionAppSettings | Out-Null

This might help: To create an Azure Function we have dependency over "Storage Account", "Service Plan", "a resource group" and "Application Insight"(optional). Below i am initially defining variables. Post that i am checking if Resource group exist. If not it will create a new one. Post which i created Azure Storage Account, Service Plan and Application Insight. In Azure function we need to select Runtime Stack which can be "Java"/"DotNet"/"Python" etc. Here I am using "Dotnet". Azure Function requires Storage Account keys to link the same, which is extracted below under variables "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING" etc. To link AppInsight with Function we need to map Application_Insight_InstrumentationKey. Please follow inline comments :

#=============Defining All Variables=========
$location = 'Southeast Asia'
$resourceGroupName = 'functionrgnew1'
$storageAccount = 'functionsasdnewqq1'
$subscriptionId = '<id>'
$functionAppName = 'functionapppsdfsdnew1'
$appInsightsName = 'appinsightnameprdad' 
$appServicePlanName = 'functionappplan'
$tier = 'Premium'

#========Creating Azure Resource Group========
$resourceGroup = Get-AzResourceGroup | Where-Object { $_.ResourceGroupName -eq $resourceGroupName }
if ($resourceGroup -eq $null)
{
  New-AzResourceGroup -Name $resourceGroupName -Location $location -force
}

#selecting default azure subscription by name
Select-AzSubscription -SubscriptionID $subscriptionId
Set-AzContext $subscriptionId

#========Creating Azure Storage Account========
if(!(Test-AzureName -Storage $storageAccount))
{
  New-AzStorageAccount -ResourceGroupName $resourceGroupName -AccountName $storageAccount -Location $location -SkuName "Standard_LRS"
}

#========Creating App Service Plan============
New-AzAppServicePlan -ResourceGroupName $resourceGroupName -Name $appServicePlanName -Location $location -Tier $tier
$functionAppSettings = @{
    ServerFarmId="/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Web/serverfarms/$appServicePlanName";
    alwaysOn=$True;
}

#========Creating Azure Function========
$functionAppResource = Get-AzResource | Where-Object { $_.ResourceName -eq $functionAppName -And $_.ResourceType -eq "Microsoft.Web/Sites" }
if ($functionAppResource -eq $null)
{
  New-AzResource -ResourceType 'Microsoft.Web/Sites' -ResourceName $functionAppName -kind 'functionapp' -Location $location -ResourceGroupName $resourceGroupName -Properties $functionAppSettings -force
}

#========Creating AppInsight Resource========
New-AzApplicationInsights -ResourceGroupName $resourceGroupName -Name $appInsightsName -Location $location
$resource = Get-AzResource -Name $appInsightsName -ResourceType "Microsoft.Insights/components"
$details = Get-AzResource -ResourceId $resource.ResourceId
$appInsightsKey = $details.Properties.InstrumentationKey

#========Retrieving Keys========
$keys = Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -AccountName $storageAccount
$accountKey = $keys | Where-Object { $_.KeyName -eq 'Key1' } | Select-Object -ExpandProperty Value
$storageAccountConnectionString = 'DefaultEndpointsProtocol=https;AccountName='+$storageAccount+';AccountKey='+$accountKey

#========Defining Azure Function Settings========
$AppSettings =@{}
$AppSettings =@{'APPINSIGHTS_INSTRUMENTATIONKEY' = $appInsightsKey;
                'AzureWebJobsDashboard' = $storageAccountConnectionString;
                'AzureWebJobsStorage' = $storageAccountConnectionString;
                'FUNCTIONS_EXTENSION_VERSION' = '~2';
                'FUNCTIONS_WORKER_RUNTIME' = 'dotnet';
                'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING' = $storageAccountConnectionString;
                'WEBSITE_CONTENTSHARE' = $storageAccount;}
Set-AzWebApp -Name $functionAppName -ResourceGroupName $resourceGroupName -AppSettings $AppSettings