How do I deploy to Azure App Service with PowerShell? - powershell

I have looked around and with the thousands of commands in the Azure and AzureRM commandlets in PowerShell, I'm still not sure how to do this.
What I have working so far:
Installed Azure and AzureRM modules and imported them to the script
Generated the "*.publishsettings" file from the get-AzurePublishSettingsFile command
Imported the "*.publishsettings" file
Can acccess the website with the "Stop-AzureWebsite" and "Start-AzureWebsite" commandlets
What I need to do:
create a new deployment and push files to the app-service site.
Notes: I do not have a Visual Studio project and .csproj file configs. I simply want to take the contents of a folder and push that to the website.
Any help would be useful as the documentation is really bad on details and there are thousands of commands in PowerShell to go through.

You could check this blog:Deploy an App Service using Azure PowerShell to a Deployment Slot.
Get-AzurePublishSettingsFile
Import-AzurePublishSettingsFile .\Your-Publish-Settings-credentials.publishsettings
Get-AzureSubscription
Select-AzureSubscription -SubscriptionName "The Subscription Name containing the slot"
Set-AzureSubscription -SubscriptionId "ID of subscription"
$WebAppName = "standard(staging)"
Get-AzureWebsite -Name $WebAppName
Publish-AzureWebsiteProject -Name $WebAppName -Package "C:\PowerShell\standard.zip" -Slot "staging"

The above link (https://blogs.msdn.microsoft.com/benjaminperkins/2016/10/01/deploy-an-app-service-using-azure-powershell-to-a-deployment-slot/)talks about a GIT based deployment. OP wanted something from a folder.
Check this one out -
Create an Azure Website with PowerShell and FTP

Unfortunately the accepted answer gave me the following error:
Get-AzureWebSite : Requested value 'PremiumV2' was not found
This StackOverflow answer suggests to use Get-AzureRmWebApp instead, but this introduces some challenges with authentication. After some searching I found the following article which explained exactly what I needed: an approach to do a publish to Azure without any human interaction.
Please see a very simplified version of the script below.
#In the Azure portal go to (search for) "Azure Active Directory" ->
#"Properties" -> Directory ID
$TenantId = "<Azure Active Directory Id>"
#In the Azure portal go to (search for) "Subscriptions" -> Subscription ID
$SubscriptionId = "<Azure Subscription Id>"
#In the Azure portal go to (search for) "Azure Active Directory" -> "App registrations" ->
#Create a new registration, this will give you the ID and Secret below.
#Make sure to give your new app registration sufficient rights to your app service
$ServicePrincipleApplicationId = "<Service Principle Id>"
$ServicePrincipleApplicationSecret = "<Service Principle Secret>"
$WebAppPath = "<Local folder where your package is located>"
$ResourceGroupName = "<The name of the Azure resource group that contains your app service>"
$WebAppName = "<The name of your Azure app service>"
$WebAppSlot = "<The name of the deployment slot you want to publish to>"
$MSDeployPath = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe"
$source = "-source:contentPath=$WebAppPath"
$publishProfileOutputPath = Join-Path -Path $ENV:Temp -ChildPath 'publishprofile.xml'
$dest = "-dest:contentPath=d:\home\site\wwwroot\,publishSettings=$publishProfileOutputPath"
$SecurePassword = $ServicePrincipleApplicationSecret | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ServicePrincipleApplicationId, $securePassword
$connectParameters = #{
Credential = $Credential
TenantId = $TenantId
SubscriptionId = $SubscriptionId
}
Add-AzureRmAccount #connectParameters -ServicePrincipal
Get-AzureRmWebAppSlotPublishingProfile -OutputFile $publishProfileOutputPath -Format WebDeploy -ResourceGroupName $ResourceGroupName -Name $WebAppName -Slot $WebAppSlot
Stop-AzureRmWebAppSlot -ResourceGroupName $ResourceGroupName -Name $WebAppName -Slot $WebAppSlot
& $MSDeployPath #('-verb:sync', $source, $dest)
Start-AzureRmWebAppSlot -ResourceGroupName $ResourceGroupName -Name $WebAppName -Slot $WebAppSlot

To deploy your zip package to Azure Web App Service using PowerShell cmdlet.
Refer MS Docs.
Connect to Azure Subscription via PowerShell. Execute Publish-AzWebApp to deploy Web App.
$webAppName = "<NameOfWebAppService>"
$resourceGroup = "<WebAppResourceGroupName>"
$zipArchiveFullPath = "<zip-package-filePath\FileName.zip>"
Publish-AzWebApp -ResourceGroupName "$resourceGroup" -Name "$webAppName" -ArchivePath "$($zipArchiveFullPath)" -Force

Related

Create/Update PATH MAPPINGS of Azure WebApp using Azure Devops task or PowerShell

I want to update configure an Azure storage mount with Azure File Share(PATH MAPPINGS) for Azure WebApp on Containers via Azure DevOps pipeline. To achieve this, I am currently using an 'Azure PowerShell task' (code below). However, the PowerShell script is configuring the 'Advance' option, and exposes the Storage Account Access Key. Is there a way to configure the 'Basic' one.
PowerShell 'New-AzWebAppAzureStoragePath' creates an 'advance' configuration.
There is also a Devops task 'Azure webapp for containers' which allows me to set 'app settings' and 'configuration settings', but no option for 'path mappings'.
Is there any alternative in PowerShell or Azure devops task, to create a 'path mapping' to Azure file share with 'BASIC' configuration.
Script:
try{
# Check if AzureStoragePath (PATH MAPPINGS) already exists for the web app
$webapp = get-AzWebApp -ResourceGroupName $webAppResourceGroupName -Name $webAppName
if($webapp.AzureStoragePath -ne $null){
# 'Path Mapping' to Azure storage File does not exist. Proceed with creating one.
# Get Storage Account Primary Key
$storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $storageResourceGroupName -AccountName $storageAccountName).value[0]
$storageAccountContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey
# Returns 'True' or 'False' depending whether File share exists or not
$storageShareObject = get-azstorageshare -Name $storageFileShareName -context $storageAccountContext -erroraction silentlycontinue
$storageShareExists = (($storageShareObject) -ne $null)
if($storageShareExists -ne 'True'){
$storageShareObjectFQDN = $storageShareObject.name + ".files.core.windows.net"
# Create a WebApp Storage Path object
$webAppStoragePathObject = New-AzWebAppAzureStoragePath -Name 'someConfig' -AccountName $storageShareObjectFQDN -Type AzureFiles -ShareName $storageFileShareName -AccessKey $storageAccountKey -MountPath "/edgemicro/config"
# Configure the 'Path mappings' for the web app
Set-AzWebApp -ResourceGroupName $webAppResourceGroupName -Name $webAppName -AzureStoragePath $webAppStoragePathObject
}
}
}catch{
# '$_' contains all the details about exception
$_
}
I can reproduce the same issue with Azure powershell.
However, You can use azure cli instead of azure powershell as workaround. See below command. Check here for more information.
az webapp config storage-account add --resource-group $storageResourceGroupName --name $webAppName --custom-id "someConfig" --storage-type "AzureFiles" --share-name $storageFileShareName --account-name $storageAccountName --access-key $storageAccountKey --mount-path "/parent"
With above azure cli command, you can create a basic configuration. See below screenshot:

Azure Runbook - Get a file from Azure File System Storage

I am creating a Azure workflow runbook wherein I have to get a file from Azure File System Storage and publish that to a azure web app.
I tried with New-PSDrive but that command is not supported in runbook (even InlineScript doesn't work). Could anyone help me with the script. In the below code I need to populate file path from azure file system.
$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Connect-AzureRmAccount -ServicePrincipal -Tenant $Conn.TenantID `
-ApplicationId $Conn.ApplicationID `
-CertificateThumbprint $Conn.CertificateThumbprint
$zipFilePath = ???
Publish-AzureWebsiteProject -Name $siteName -Package $zipFilePath
I searched a lot but couldn't find much information on this.
Are you referring to a file in a Azure Storage account? If so, that is pretty easy to accomplish. Add the following to your Runbook, filling in the required information:
$StorageAccountKey = Get-AutomationVariable -Name 'storageKey'
$Context = New-AzureStorageContext -StorageAccountName 'your-storage' `
-StorageAccountKey $StorageAccountKey
Get-AzureStorageFileContent -ShareName 'your-share' -Context $Context `
-path 'your-file' -Destination 'C:\Temp'
$filePath = Join-Path -Path 'C:\Temp' -ChildPath 'your-file'
You also need to create an variable in your Automation Account, called "storageKey" containing your Storage Accounts key.
Mounting Azure File share as a drive is not currently supported in Automation cloud jobs, though it will probably be supported in a few months. In the meantime, use the Get-AzureStorageFile command from the Azure.Storage module to retrieve the file to a temp folder.
Alternatively, run this job on a Hybrid worker. In this case, make sure all the prerequisites are met in order to mount the share as a network drive.

How to restart an Azure appservice from Azure Powershell

How can you restart an AppService from Azure's Powershell running in a Runbook in an Automation Account in an ARM subscription in Azure?
I thought the approach would be:
Restart-AzureWebsite -Name "your-appservice-name"
but that gets:
Restart-AzureWebsite : No default subscription has been designated.
Use select-AzureSubscription -Default #<subscriptionName> to set the default subscription.
There is no Restart-AzureRmWebApp available in Azure PowerShell.
All combinations of the following lead to just a bunch of other error messages:
$Cred = Get-AutomationPSCredential -Name 'your-credentials-name'
Add-AzureAccount -Credential $Cred
Add-AzureRMAccount -Credential $Cred
Get-AzureSubscription –SubscriptionName 'your-subscription-name' | Select-AzureSubscription -Default
Restart-AzureWebsite -Name "your-appservice-name"
There is no Restart-AzureRmWebApp available in Azure PowerShell.
As Walter - MSFT mentioned that we could import AzureRM.Websites, before that we need to update AzureRM.Profile to 4.0, more detail you could refer to the screenshot.
Before to do that we could create Azure AD service principal locally.
How to create service principal we could refer to this document
Login-AzureRmAccount
$sp = New-AzureRmADServicePrincipal -DisplayName exampleapp -Password "password"
Sleep 20
New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $sp.ApplicationId
Run Restart-AzureRmWebApp command in the Runbook.
$azureAplicationId ="Application Id"
$azureTenantId= "tenant Id"
$azurePassword = ConvertTo-SecureString "password" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Add-AzureRmAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
Restart-AzureRmWebApp -ResourceGroupName "ResourceGroup" -Name "WebApp Name"
This Powershell script works inside an Azure Automation Runbook:
Invoke-AzureRmResourceAction -ResourceGroupName "<your-resource-group-name>" -ResourceName "<your-resource-name>" -ResourceType 'Microsoft.Web/sites' -Action 'Restart' -Force
Edit
However the next script is probably better; it relies on #Tom Sun's answer above, i.e.
Upgrade the modules - go to Automation Accounts / Modules / Update Azure Modules.
Import the AzureRm.Websites module - go to Automation Accounts / Modules / Browse Gallery.
Create under Automation Accounts / Credentials.
$Cred = Get-AutomationPSCredential -Name '<your-credentials>'
Add-AzureRMAccount -Credential $Cred
Get-AzureRmSubscription –SubscriptionName '<your-subscription-name>' | Select-AzureRmSubscription
Restart-AzureRmWebApp -ResourceGroupName "office" -Name "<your-appservice-name>"

Azure Rotate Storage Keys and Update ADF Linked Service

I am looking for a way to implement doing key rotation in an Azure Automation I have found a way to create a powershell runbook and have implemented the following code:
$azureAccountName = <acct_name>
$azurePassword = ConvertTo-SecureString <pass> -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePassword)
Login-AzureRmAccount -ServicePrincipal -Credential $psCred -TenantId <tenant id> -SubscriptionId <sub id>
#Optionally you may set the following as parameters
$StorageAccountName = <storage acct name>
$RGName = <rg name>
#Key name. For example key1 or key2 for the storage account
New-AzureRmStorageAccountKey -ResourceGroupName $RGName -Name $StorageAccountName -KeyName "key1" -Verbose
New-AzureRmStorageAccountKey -ResourceGroupName $RGName -Name $StorageAccountName -KeyName "key2" -Verbose
When I ran this, it worked, however, it broke my Azure Data Factory Linked Service. I realized that the connection string for the linked service is broken, so I set out to try to reset the connection string in the automation script. I was able to get the connection string by doing:
(Get-AzureRmDataFactoryLinkedService -DataFactoryName <adf name> -ResourceGroupName <rg name> -Name <ls name>).Properties.TypeProperties.ConnectionString
I cannot find a way to set this connection string using powershell and azure automation.
You could use Power Shell to rest this connection. But you need use Remove-AzureRmDataFactoryLinkedService (Removes a linked service from Azure Data Factory.) and use New-AzureRmDataFactoryLinkedService to re-link your storage account to data factory.
Please refer to this tutorial.
You need create a json file like below:
{
"name": "AzureStorageLinkedService",
"properties": {
"type": "AzureStorage",
"typeProperties": {
"connectionString": "DefaultEndpointsProtocol=https;AccountName=<accountname>;AccountKey=<accountkey>"
}
}
}
Use New-AzureRmDataFactoryLinkedService to link.
New-AzureRmDataFactoryLinkedService -ResourceGroupName ADFTutorialResourceGroup -DataFactoryName <Name of your data factory> -File .\AzureStorageLinkedService.json
But if you use Azure automation to execute this, there is a issue you will meet. On runbook, you could not store a json file, maybe you could save on a public github(no safe). Another solution is use Hybrid Runbook Worker.

Powershell Error Open Edx deployment on Azure

Why doest this script return diff error on Windows10 and Mac for the same Powershell Version?
Script executed:
Now, Azure PowerShell on Mac is in preview. It does not have full functions of Windows PowerShell. Parameter ServicePrincipalName is not supported on Mac now, so you get the error.
According to the error on Windows PowerShell. It seems that your application ID or password wrong. Do you check your them? You could use the following cmdlets to create service principal and logon Azure.
#login Azure
Login-AzureRmAccount
#create RM AD application
$app = New-AzureRmADApplication –DisplayName "<Your Application Display Name>" –HomePage "<http://YourApplicationHomePage>" –IdentifierUris "<http://YourApplicationUri>" –Password "<Your Password>"
#create a service principal for that application
New-AzureRmADServicePrincipal –ApplicationId $app.ApplicationId
#Assign that service principal a role.
New-AzureRmRoleAssignment –RoleDefinitionName Reader –ServicePrincipalName $app.ApplicationId
#Authenticating using a service principal
$pass = ConvertTo-SecureString "<Your Password>" -AsPlainText –Force
$cred = New-Object -TypeName pscredential –ArgumentList "<Your UserName>", $pass
Login-AzureRmAccount -Credential $cred -ServicePrincipal –TenantId <Your TenantId>
More information please refer to this link.
I found it. finally thanks to the collaboration of Microsoft support:
this line of code.
Set-AzureSubscription -SubscriptionName $AzureSubscriptionName| Out-Null
Is not correct. It should be:
Select-AzureRmSubscription -SubscriptionName $AzureSubscriptionName| Out-Null