Azure Runbook - Get a file from Azure File System Storage - powershell

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.

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:

write to text file on azure file share

I would like to move a ps script to Azure to run as a runbook. It basically checks all new SharePoint sites and checks if they meet certain criteria, like enables version control if not set.
The script works like:
$sitesdonelist = "c:\log.txt"
$sitesdone = get-content -Path $sitesdonelist
foreach($sitecoll in $sitecollections) {
$currentsite = $sitecoll.Url
if ($sitesdone -inotcontains $currentsite) {
checksite
add-content -Path $sitesdonelist -Value $sitecoll.Url
}
}
I would like this code to work on Azure and part of this is to move the sites done list to an Azure file share and append the processed sites to it. So far I see two options and none of them seem right:
Download the file to $env:TEMP, append and upload on finish: I
will miss all sites done if something fails halfway
Download the file to $env:TEMP, append and upload after every site: would make the process slow and cause lot of unnecessary data load
Is there a better option? Can I write directly to a file on Azure file share from an Azure PowerShell runbook?
If you want to write something as log to a file in your Azure file share from Azure Automation runbook , pls try the PS command below :
$appid = "<your appliaction ID>"
$passwd = "<your Azure AD application Client secret>"
$tenantId= "<your tenant ID>"
$secpasswd = ConvertTo-SecureString -String $passwd -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential ($appid, $secpasswd)
Connect-AzAccount -ServicePrincipal -Credential $cred -Tenant $tenantId
$fileName = "<file name,including path>"
$storageacc = Get-AzStorageAccount -ResourceGroupName <resource group name> -Name <storage account name>
$file = (Get-AzStorageFile -ShareName qsfileshare -Context $storageacc.Context -Path $fileName)[0]
$content = "content you want to write"
$file.UploadTextAsync($file.DownloadTextAsync().GetAwaiter().GetResult() + $content).GetAwaiter().GetResult()
#get the content of the file that we write.
$file.DownloadTextAsync().GetAwaiter().GetResult()
Result in automation :
Previously , the content of the file is "hello!!!" only, as you can see ,the content has been written to the file . Hope it helps .

Migrate local bash script with Azure CLI commands to Azure Powershell task in Azure DevOps

I currently have a bash script that runs some az commands to clean a storage account container and upload the contents of a directory to it:
az storage blob delete-batch --account-name $ACCOUNT_NAME --source $web
az storage blob upload-batch --account-name $ACCOUNT_NAME -s $SOURCE_PATH -d $web
I would like to reuse that functionality inside a Powershell Azure task that runs on Azure DevOps Services because I have a lot of other stuff going on that script besides the storage cleaning and upload.
What's the best way to migrate this? Been looking in the Powershell Azure module documentation but I can't find a proper equivalent to blob delete-batch and blob upload-batch.
Also though in calling the az command directly but for that I would have to login so I would need a way to pass the service principal details from the Powershell Azure task into the az login command before executing those lines.
Any ideas are welcome. thanks in advance
use Azure PowerShell to login Azure with service principal
You can use the following script
$appId = "your application id "
$password = "your application secret"
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($appId, $secpasswd)
Add-AzureRmAccount -Credential $mycreds -Tenant "your tenat id" -ServicePrincipal
I can use Azure CLI command "az storage blob upload-batch" to upload a
local directory to Azure storage. How to implement it with Azure
PowerShell
Azure PowerShell does not provide the command like that. It just provides the command Set-AzureStorageBlobContent to allow customers to upload file to Azure storage. So you need to write a script with the command to implement how to upload a directory to Azure storage. For example
$StorageAccountKey=" "
$sourceFileRootDirectory=" "
$StorageAccountName=" "
$ContainerName=" "
$ctx = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
$container = Get-AzureStorageContainer -Name $ContainerName -Context $ctx
if ($container) {
$filesToUpload = Get-ChildItem $sourceFileRootDirectory -Recurse -File
foreach ($x in $filesToUpload) {
$blobName = ($x.fullname.Substring($sourceFileRootDirectory.Length + 1)).Replace("\", "/")
Set-AzureStorageBlobContent -File $x.fullname -Container $container.Name -Blob $blobName -Context $ctx -Force:$Force
}
}
I can use Azure CLI command "az storage blob delete-batch" to clean up
a container. How to implement it with Azure
PowerShell
Azure PowerShell does not provide the command that we can use to directly delete all blob in one container. So we need to write a script to implement it. Now, we have two choices
Delete the container and create a new container with the same name
$StorageAccountKey=" "
$StorageAccountName=" "
$ContainerName=" "
$context = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
Remove-AzureStorageContainer -Name $ContainerName -Context $context
New-AzureStorageContainer -Name $ContainerName -Context $context
Get all blobs in the container then delete them
$StorageAccountKey=" "
$StorageAccountName=" "
$ContainerName=" "
$Token = $null
$Total = 0
$MaxCount=5000
$context = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
do
{
$Blobs = Get-AzureStorageBlob -Container $ContainerName -MaxCount $MaxCount -ContinuationToken $Token -Context $context
if($Blobs.Length -le 0) { Break;}
$Token = $Blobs[$blobs.Count -1].ContinuationToken;
foreach($blob in $blobs){
Remove-AzStorageBlob -Blob $blob.Name -Container $ContainerName -Context $context
}
}
While ($Token -ne $null)
Why not use the Azure CLI task in Azure DevOps that uses a Service connection for the authentication part? See the documentation here.

How do I deploy to Azure App Service with 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

Working with Azure Development Storage from command-line

I need to upload some files to my Azure storage emulator using scripts. The same task for remote Azure storage is performed easily with Azure PowerShell cmdlets, just call
Add-Blob -BlobType Block -FilePath $myFilePath -ContainerName $myContainerName
But how can I do the same thing for local storage emulator?
For those looking for how to do this with Azure SDK (2.1), here is how:
$StorageContext = New-AzureStorageContext -Local
Set-AzureStorageBlobContent -File $SourceFilePath `
-Container $DestinationContainerName -Blob `
$DestinationBlobName -Context $StorageContext
If you want to actually upload to an Azure storage account, change the $StorageContext:
New-AzureStorageContext –StorageAccountName $StorageAccountName `
-StorageAccountKey $StorageAccountKey
You could use the Azure Command Line Tools, available here:
https://github.com/RobBlackwell/AzureCommandLineTools
They run on the normal command prompt, they're not actually powershell cmdlets.
SET AZURE_CONNECTION_STRING=UseDevelopmentStorage=true
PutBlob filename [containername[/blobname]]
Found the solution using PowerShell Cmdlets.
You need to specify -UseDevelopmentStorage option to the cmdlets:
Get-Container -UseDevelopmentStorage
or
Add-Blob -UseDevelopmentStorage -BlobType Block -FilePath $myFilePath -ContainerName $myContainerName