C# 使用ARM或Powershell脚本部署Web作业

C# 使用ARM或Powershell脚本部署Web作业,c#,powershell,azure,azure-web-app-service,powershell-2.0,C#,Powershell,Azure,Azure Web App Service,Powershell 2.0,我正在尝试使用powershell脚本将Web作业部署到Azure中,我们有自己的部署框架,当我从本地计算机部署时,只有在我拥有管理员或共同管理员权限的情况下,如果我拥有参与者访问脚本失败,它才能成功部署。我们的部署框架只有参与者权限,是否有任何方法可以使用contributor权限部署web作业,而我并没有找到任何用于web作业部署的ARM模板,因为我在本地有解决方案文件。有什么建议吗 这是我的剧本 `Add-AzureAccount (since web job doesn't have a

我正在尝试使用powershell脚本将Web作业部署到Azure中,我们有自己的部署框架,当我从本地计算机部署时,只有在我拥有管理员或共同管理员权限的情况下,如果我拥有参与者访问脚本失败,它才能成功部署。我们的部署框架只有参与者权限,是否有任何方法可以使用contributor权限部署web作业,而我并没有找到任何用于web作业部署的ARM模板,因为我在本地有解决方案文件。有什么建议吗 这是我的剧本

`Add-AzureAccount (since web job doesn't have any RM commandlett i am using classic login where All our resource are in RM )
Select-AzureSubscription -SubscriptionName "*************"

$packageSource ="$Global:packageDir/../output\deletelogs\bin"

$destinationSource = "$env:TEMP\DeleteLogsWebjob.zip"

If(Test-path $destinationSource) {Remove-item $destinationSource}

Add-Type -assembly "system.io.compression.filesystem"

[io.compression.zipfile]::CreateFromDirectory($packageSource, $destinationSource) 

$webappname = AzCreateWebAppName "mywebapp$(Get-Random)"

$location =   "EastUs"           #GetCurrentRegion

$resourceGroupName= "*****"           # AzGetResourceGroup

$webjobName = $webappname +"_deletelogsjob"

$jobCollecctionName = $webappname + $webjobName + "JobCollection"

#<### Defining Schedules
#$date = Get-Date 
#$startDate = $date.ToString("MM-dd-yyy HH:mm tt")
#$endDate = $date.AddYears(1).ToString("MM-dd-yyy HH:mm tt")#>

# #Create an App Service plan in Free tier.
New-AzureRmAppServicePlan -Name $webappname -Location $location -ResourceGroupName $resourceGroupName -Tier Basic

## Create a web app.
$webapp = New-AzureRmWebApp -Name $webappname -Location $location -AppServicePlan $webappname -ResourceGroupName $resourceGroupName

###### Create WebJob

$job = New-AzureWebsiteJob -Name $webapp -JobName $webjobName -JobType Triggered -JobFile $destinationSource

$jobCollection = New-AzureRmSchedulerJobCollection -Location $location -JobCollectionName $jobCollecctionName -ResourceGroupName $resourceGroupName

$temp = "$env:TEMP\appsetting.xml"

$file = Get-AzureRMWebAppPublishingProfile -ResourceGroupName $resourceGroupName -Name $webappname -OutputFile $temp -Format WebDeploy


$webSitePassword = ([xml]$file).ChildNodes[0].ChildNodes[0].Attributes[5].Value


$webSiteUserName = ([xml]$file).ChildNodes[0].ChildNodes[0].Attributes[4].Value

$uri = "https://{0}:{1}@{2}.scm.azurewebsites.net/api/triggeredwebjobs/{3}/run" -f $webSiteUserName, $webSitePassword,$webappname, $webjobName

New-AzureRmSchedulerHttpJob -ResourceGroupName $resourceGroupName `
  -JobCollectionName $jobCollection[0].JobCollectionName -JobName "deleteLogsScheduler" -Method POST `
  -URI $uri -StartTime $startDate -Interval 2 -Frequency Minute `
  -EndTime $endDate`
`添加AzureAccount(因为web作业没有任何RM命令,所以我使用的是经典登录,所有资源都在RM中)
选择AzureSubscription-SubscriptionName“**************”
$packageSource=“$Global:packageDir/。/output\deletelogs\bin”
$destinationSource=“$env:TEMP\DeleteLogsWebjob.zip”
If(测试路径$destinationSource){Remove item$destinationSource}
添加类型-assembly“system.io.compression.filesystem”
[io.compression.zipfile]::CreateFromDirectory($packageSource,$destinationSource)
$webappname=AzCreateWebAppName“mywebapp$(随机获取)”
$location=“EastUs”#GetCurrentRegion
$resourceGroupName=“*******”#AzGetResourceGroup
$webjobName=$webappname+“\u deletelogsjob”
$jobcollectionname=$webappname+$webjobName+“JobCollection”
#
##在免费层创建应用程序服务计划。
新AzureRmappsServicePlan-Name$webappname-Location$Location-ResourceGroupName$ResourceGroupName-Tier Basic
##创建一个web应用程序。
$webapp=New AzureRmWebApp-Name$webappname-Location$Location-AppServicePlan$webappname-ResourceGroupName$ResourceGroupName
######创建WebJob
$job=New AzureWebsiteJob-Name$webapp-JobName$webjobName-JobType-Triggered-JobFile$destinationSource
$jobCollection=New AzureRmSchedulerJobCollection-Location$Location-JobCollectionName$JobCollectionName-ResourceGroupName$ResourceGroupName
$temp=“$env:temp\appsetting.xml”
$file=Get-AzureRMWebAppPublishingProfile-ResourceGroupName$ResourceGroupName-Name$webappname-OutputFile$temp-Format WebDeploy
$webSitePassword=([xml]$file).ChildNodes[0]。ChildNodes[0]。属性[5]。值
$webSiteUserName=([xml]$file).ChildNodes[0]。ChildNodes[0]。属性[4]。值
$uri=“https://{0}:{1}@{2}.scm.azurewebsites.net/api/triggeredwebjobs/{3}/run”-f$webSiteUserName、$webSitePassword、$webappname、$webjobName
新AzureRmSchedulerHttpJob-ResourceGroupName$ResourceGroupName`
-JobCollectionName$jobCollection[0]。JobCollectionName-JobName“deleteLogsScheduler”-方法POST`
-URI$URI-StartTime$startDate-间隔2-频率分钟`
-EndTime$endDate`

您可以在此示例中使用


下面几行代码是powershell脚本,它允许您在web应用程序中部署webjob。参数通过设置文件引用传递

#Requires -Version 3.0

Param(
    [string] $settingsFileName = '\Settings\settings.json',
    [boolean] $unitTestMode = $false
    )
$Apiversion = "2015-08-01"
# Define FUNCTIONS

#Check if any requirement is missing
function Test-ParameterSet
{
    param
    (
        [parameter(Mandatory = $true)][System.Object]$settings
    )
    # Loop through the $settings and check no missing setting
    if ($null -eq $applicationFileJson.subscriptions) {throw "Missing subscriptions field in settings file"}
    foreach ($subscription in $applicationFileJson.subscriptions)
    {
        if ($null -eq $subscription.subscriptionId) {throw "Missing subscription Id field in settings file"}
        # Loop through the $settings and check no missing setting
        foreach ($vault in $settings.WorkLoads)
        {
            if ($null -eq $vault.applicationName) {throw "Missing applicationNam in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.environmentName) {throw "Missing environmentName in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.resourceGroupName) {throw "Missing resourceGroupName in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.webAppName) {throw "Missing webAppName in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.Storagerg) {throw "Missing Storagerg in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.webjobname) {throw "Missing webjobname in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.webjobtype) {throw "Missing webjobtype in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.storageAccountName) {throw "Missing storageAccountName in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.container_name) {throw "Missing container_name in settings file for $($subscription.subscriptionId)"}
            If ($vault.webjobtype -eq "triggeredwebjobs")
            {
                if ($null -eq $vault.trigger_type) {throw "Missing trigger_type in settings file for $($subscription.subscriptionId)"}
            }
            }

            If ($vault.webjobtype -eq "triggeredwebjobs" -and $vault.trigger_type -eq "scheduled") 
            {
                 if ($null -eq $vault.schedule) {throw "Missing schedule in settings file for $($subscription.subscriptionId)"}

            If ($vault.webjobtype -eq "continuouswebjobs") 
            {
                 if ($null -eq $vault.continuous_type) {throw "Missing continuous_type in settings file for $($subscription.subscriptionId)"}
            }
    } 
    return $true
} 
}




function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName)
{ 
$resourceType = "Microsoft.Web/sites/config"
$resourceName = "$webAppName/publishingcredentials"
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion $Apiversion -Force
return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
}


function Publish-webjob
{ 

        [OutputType([String])]
    param
    (
         [parameter(Mandatory = $true)][string]$resourceGroupName,
         [parameter(Mandatory = $true)][string]$webAppName,
         [parameter(Mandatory = $true)][string]$Storagerg,
         [parameter(Mandatory = $true)][string]$webjobname,
         [parameter(Mandatory = $true)][string]$webjobtype,
         [parameter(Mandatory = $true)][string]$storageAccountName,

         [parameter(Mandatory = $true)][string]$container_name,
         [parameter(Mandatory = $true)][string]$settingsFileName,
         [parameter(Mandatory = $true)][string]$i

    )  

    #Check resource group exist
    try {
        $resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction Stop   
    }
    catch {
        $resourceGroup = $null
    }
    if ($null -eq $resourceGroup)
    {
        $message = "Resource group $resourceGroupName not found, deployment stop"
        Write-Verbose $message
        return $message
    }   
        else 
    {
        # Prepare deployment variables
        Write-Verbose "ResourceGroup Found"

        $SettingsJson = Get-JsonParameterSet -settingsFileName $settingsFileName
        $trigger_type = "$($SettingsJson.WorkLoads[$i].trigger_type)"
        Write-Verbose $trigger_type
        $schedule = "$($SettingsJson.WorkLoads[$i].schedule)"
        Write-Verbose $schedule
        $continuous_type = "$($SettingsJson.WorkLoads[$i].continuous_type)"
        Write-Verbose $continuous_type
    }

    # Unlock ResourceGroup
                    Unlock-ResourceGroup $resourceGroupName
                    write-verbose "ResourceGroup Unlocked"

    $accessToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppname


    #Get storage account context and storage bolo
    $sa= Get-AzureRmStorageAccount -ResourceGroupName $Storagerg -Name $storageAccountName
    $ctx=$sa.Context
    $blobs = Get-AzureStorageBlob -Container $container_name -Context $ctx
    $webjobtype=$webjobtype+"webjobs"
    $apiUrl = "https://$webAppName.scm.azurewebsites.net/api/$webjobtype/$webjobname"


    #create a folder to save all the files of the container
    $Location=$PSScriptRoot

    New-Item -Path $Location -Name $webjobname -ItemType "directory" -Force
    $folderPath = "$Location"+"\"+$webjobname
    $localFile = $Location+"\"+$webjobname+"\"


    #Generating header to create and publish the Webjob :
    $Header = @{
    "Content-Disposition"="attachment;filename=$($webAppName)"
    "Authorization"=$accessToken
            }
    #Check if the storage container is empty
    If($blobs.Count -eq 0)
    {
        Write-Error  "The storage container is found empty"  
    }

    #get files from container
    foreach ($blob in $blobs)
    {   
        $file=New-TemporaryFile
        $file=Get-AzureStorageBlobContent -Container $container_name -Blob $blob.Name -Context $ctx -Destination $localFile -Force
        $contents = Get-Content $localFile -Raw -ErrorAction:SilentlyContinue
        $f=New-TemporaryFile
        Add-Content $f $contents
    }

    If ($webjobtype -eq "triggeredwebjobs" -and $trigger_type -eq "scheduled") 
    {

            $f = New-TemporaryFile 
            $r="{ ""schedule"" : "+""""+ $schedule+"""" + "}"
            Add-Content $f $r
            $destination=$Location+"\"+$webjobname+"\settings.job"

            Move-Item -Path $f -Destination $destination
    }


    If ($webjobtype -eq "continuouswebjobs") 
    {

        $f = New-TemporaryFile 
        If($continuous_type -eq "singleinstance")
        {
            $c="true"
        }
        If($continuous_type -eq "multipleinstance")
        {
            $c="false"
        }
        $r="{ ""is_singleton"" : " + $c + "}"
        Add-Content $f $r
        $destination=$Location+"\"+$webjobname+"\settings.job"
        Move-Item -Path $f -Destination $destination

    }

    #Archive the files to a zip
    $source = $localFile + "*"
    $wz=$webjobname+".zip"
    $destination = $Location+"\"+$webjobname+"\"+$wz
    Compress-Archive -U -Path $source -DestinationPath $destination

    #Deploying webjobs
    $result = Invoke-RestMethod -Uri $apiUrl -Headers $Header  -Method put -InFile $destination -ContentType 'application/zip'  -ErrorAction Stop 
    Write-Host "Print result " -ForegroundColor Green


    #delete the folder from local mahine
    Remove-Item $folderPath -Force  -Recurse -ErrorAction SilentlyContinue


    # lock ResourceGroup
                #Lock-ResourceGroup $resourceGroupName
                write-verbose "ResourceGroup locked"

    return $result

}



function Publish-Infrastructure
{
param(
        [parameter(Mandatory = $true)][string]$settingsFileName
     )

    $settings = Get-JsonParameterSet -settingsFileName $settingsFileName
    $deploymentIsSucceeded = $true
    $workloadCount = $settings.WorkLoads.Count
    Write-Verbose "workloadCounts: $workloadCount"
    if($workloadCount -ge 1)
    {
        for($i = 0;$i -lt $workloadCount; $i++)
            { 

                $applicationName = $settings.WorkLoads[$i].applicationName
                Write-Verbose "application name: $applicationName"
                $environmentName = $settings.WorkLoads[$i].environmentName
                $applicationFile = "..\SettingsByWorkload\" + "nv_" + $applicationName + ".workload.json"
                $applicationFile = Get-FileFullPath -fileName $applicationFile  -rootPath $PSScriptRoot
                $applicationFileJson = Get-JsonParameterSet -settingsFileName $applicationFile
                Write-Verbose "application file json: $applicationName"
                $null = Test-ParameterSet -settings $settings

                $policyCount = $applicationFileJson.subscriptions.Count
                Write-Verbose "$policyCount"
                if($policyCount -ge 1)
                {  
                    for($j = 0;$j -lt $policyCount; $j++)
                    { 


                        if($applicationFileJson.subscriptions[$j].environmentName -eq $environmentName)
                        {    

                            $subscriptionId = $applicationFileJson.subscriptions[$j].subscriptionId 
                            Write-Verbose "Environment Subscription: $($subscriptionId)"
                            Set-ContextIfNeeded -SubscriptionId $subscriptionId
                            foreach ($webjob in $settings.WorkLoads[$i])
                            {                   
                                                $resourceGroupName = $webjob.resourceGroupName
                                                $webAppName = $webjob.webAppName
                                                $Storagerg = $webjob.Storagerg
                                                $webjobname = $webjob.webjobname
                                                $webjobtype = $webjob.webjobtype
                                                $storageAccountName = $webjob.storageAccountName
                                                $schedule = $webjob.schedule
                                                $container_name = $webjob.container_name
                                                $trigger_type = $webjob.trigger_type
                                                Write-Verbose "Ready to start deployment on environment $EnvironmentName of a webjob in subscription $subscriptionId for resource group: $resourceGroupName"

                                                $result = Publish-webjob ` -resourceGroupName $resourceGroupName `
                                                -webAppName $webAppName `
                                                -Storagerg $Storagerg `
                                                -webjobname $webjobname `
                                                -webjobtype $webjobtype `
                                                -storageAccountName $storageAccountName `
                                                -settingsFileName $settingsFileName `
                                                -container_name $container_name `
                                                -i $i

                            }
                        }
                    }
                }        
            }

    }

        return $true

}


#START OF SCRIPT
if ($unitTestMode)
{
    #do nothing
    Write-Verbose 'Unit test mode, no deployment' -Verbose
}
else 
{
  #Log in Azure if not already done
    try 
    {
        $azureRmContext = Get-AzureRmContext -ErrorAction Stop
    }
    catch 
    {
        $result = Add-AzureRmAccount
        $azureRmContext = $result.Context
    }
    Write-Verbose "Subscription name $($azureRmContext.Subscription.Name)" -Verbose
    $VerbosePreference = 'Continue'

    # Get required templates and setting files. Throw if not found
    $scriptsPath=$PSScriptRoot

    $scriptsPath = Split-Path -Path $scriptsPath -Parent  


    $SettingsPath = Join-Path $scriptsPath $settingsFileName

    $settingsFileName = $SettingsPath



    Write-Verbose "Settings file name $($settingsFileName)" -Verbose

    # Deploy infrastructure
    return Publish-Infrastructure `
        -settingsFileName $settingsFileName `

# END of script
}

你检查过这个吗?您应该使用ARM cmdlet,而不是将ARM和classic cmdlet混合使用。这可能是在同一代码中同时使用ARM和classic的问题,并且您提供的代码具有一些kudu授权,而我没有获得这些授权,如果您有任何参考,请与我共享。我更新了我的答案。你可以检查一下。你的脚本在我的本地版本中运行良好,但我们的部署框架不支持kudu,有没有其他方法不使用kudu作为常规powershell脚本。嗨,你的框架不支持kudu,这是什么意思?Azure web应用程序都支持kudu。如果可能的话,你可以问一个关于你的详细场景的新问题。
$creds = Invoke-AzureRmResourceAction -ResourceGroupName YourResourceGroup -ResourceType Microsoft.Web/sites/config -ResourceName YourWebApp/publishingcredentials -Action list -ApiVersion 2015-08-01 -Force

$username = $creds.Properties.PublishingUserName
$password = $creds.Properties.PublishingPassword
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))

$apiBaseUrl = "https://$($website.Name).scm.azurewebsites.net/api"

$kuduVersion = Invoke-RestMethod -Uri "$apiBaseUrl/environment" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET
#Requires -Version 3.0

Param(
    [string] $settingsFileName = '\Settings\settings.json',
    [boolean] $unitTestMode = $false
    )
$Apiversion = "2015-08-01"
# Define FUNCTIONS

#Check if any requirement is missing
function Test-ParameterSet
{
    param
    (
        [parameter(Mandatory = $true)][System.Object]$settings
    )
    # Loop through the $settings and check no missing setting
    if ($null -eq $applicationFileJson.subscriptions) {throw "Missing subscriptions field in settings file"}
    foreach ($subscription in $applicationFileJson.subscriptions)
    {
        if ($null -eq $subscription.subscriptionId) {throw "Missing subscription Id field in settings file"}
        # Loop through the $settings and check no missing setting
        foreach ($vault in $settings.WorkLoads)
        {
            if ($null -eq $vault.applicationName) {throw "Missing applicationNam in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.environmentName) {throw "Missing environmentName in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.resourceGroupName) {throw "Missing resourceGroupName in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.webAppName) {throw "Missing webAppName in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.Storagerg) {throw "Missing Storagerg in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.webjobname) {throw "Missing webjobname in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.webjobtype) {throw "Missing webjobtype in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.storageAccountName) {throw "Missing storageAccountName in settings file for $($subscription.subscriptionId)"}
            if ($null -eq $vault.container_name) {throw "Missing container_name in settings file for $($subscription.subscriptionId)"}
            If ($vault.webjobtype -eq "triggeredwebjobs")
            {
                if ($null -eq $vault.trigger_type) {throw "Missing trigger_type in settings file for $($subscription.subscriptionId)"}
            }
            }

            If ($vault.webjobtype -eq "triggeredwebjobs" -and $vault.trigger_type -eq "scheduled") 
            {
                 if ($null -eq $vault.schedule) {throw "Missing schedule in settings file for $($subscription.subscriptionId)"}

            If ($vault.webjobtype -eq "continuouswebjobs") 
            {
                 if ($null -eq $vault.continuous_type) {throw "Missing continuous_type in settings file for $($subscription.subscriptionId)"}
            }
    } 
    return $true
} 
}




function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName)
{ 
$resourceType = "Microsoft.Web/sites/config"
$resourceName = "$webAppName/publishingcredentials"
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion $Apiversion -Force
return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
}


function Publish-webjob
{ 

        [OutputType([String])]
    param
    (
         [parameter(Mandatory = $true)][string]$resourceGroupName,
         [parameter(Mandatory = $true)][string]$webAppName,
         [parameter(Mandatory = $true)][string]$Storagerg,
         [parameter(Mandatory = $true)][string]$webjobname,
         [parameter(Mandatory = $true)][string]$webjobtype,
         [parameter(Mandatory = $true)][string]$storageAccountName,

         [parameter(Mandatory = $true)][string]$container_name,
         [parameter(Mandatory = $true)][string]$settingsFileName,
         [parameter(Mandatory = $true)][string]$i

    )  

    #Check resource group exist
    try {
        $resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction Stop   
    }
    catch {
        $resourceGroup = $null
    }
    if ($null -eq $resourceGroup)
    {
        $message = "Resource group $resourceGroupName not found, deployment stop"
        Write-Verbose $message
        return $message
    }   
        else 
    {
        # Prepare deployment variables
        Write-Verbose "ResourceGroup Found"

        $SettingsJson = Get-JsonParameterSet -settingsFileName $settingsFileName
        $trigger_type = "$($SettingsJson.WorkLoads[$i].trigger_type)"
        Write-Verbose $trigger_type
        $schedule = "$($SettingsJson.WorkLoads[$i].schedule)"
        Write-Verbose $schedule
        $continuous_type = "$($SettingsJson.WorkLoads[$i].continuous_type)"
        Write-Verbose $continuous_type
    }

    # Unlock ResourceGroup
                    Unlock-ResourceGroup $resourceGroupName
                    write-verbose "ResourceGroup Unlocked"

    $accessToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppname


    #Get storage account context and storage bolo
    $sa= Get-AzureRmStorageAccount -ResourceGroupName $Storagerg -Name $storageAccountName
    $ctx=$sa.Context
    $blobs = Get-AzureStorageBlob -Container $container_name -Context $ctx
    $webjobtype=$webjobtype+"webjobs"
    $apiUrl = "https://$webAppName.scm.azurewebsites.net/api/$webjobtype/$webjobname"


    #create a folder to save all the files of the container
    $Location=$PSScriptRoot

    New-Item -Path $Location -Name $webjobname -ItemType "directory" -Force
    $folderPath = "$Location"+"\"+$webjobname
    $localFile = $Location+"\"+$webjobname+"\"


    #Generating header to create and publish the Webjob :
    $Header = @{
    "Content-Disposition"="attachment;filename=$($webAppName)"
    "Authorization"=$accessToken
            }
    #Check if the storage container is empty
    If($blobs.Count -eq 0)
    {
        Write-Error  "The storage container is found empty"  
    }

    #get files from container
    foreach ($blob in $blobs)
    {   
        $file=New-TemporaryFile
        $file=Get-AzureStorageBlobContent -Container $container_name -Blob $blob.Name -Context $ctx -Destination $localFile -Force
        $contents = Get-Content $localFile -Raw -ErrorAction:SilentlyContinue
        $f=New-TemporaryFile
        Add-Content $f $contents
    }

    If ($webjobtype -eq "triggeredwebjobs" -and $trigger_type -eq "scheduled") 
    {

            $f = New-TemporaryFile 
            $r="{ ""schedule"" : "+""""+ $schedule+"""" + "}"
            Add-Content $f $r
            $destination=$Location+"\"+$webjobname+"\settings.job"

            Move-Item -Path $f -Destination $destination
    }


    If ($webjobtype -eq "continuouswebjobs") 
    {

        $f = New-TemporaryFile 
        If($continuous_type -eq "singleinstance")
        {
            $c="true"
        }
        If($continuous_type -eq "multipleinstance")
        {
            $c="false"
        }
        $r="{ ""is_singleton"" : " + $c + "}"
        Add-Content $f $r
        $destination=$Location+"\"+$webjobname+"\settings.job"
        Move-Item -Path $f -Destination $destination

    }

    #Archive the files to a zip
    $source = $localFile + "*"
    $wz=$webjobname+".zip"
    $destination = $Location+"\"+$webjobname+"\"+$wz
    Compress-Archive -U -Path $source -DestinationPath $destination

    #Deploying webjobs
    $result = Invoke-RestMethod -Uri $apiUrl -Headers $Header  -Method put -InFile $destination -ContentType 'application/zip'  -ErrorAction Stop 
    Write-Host "Print result " -ForegroundColor Green


    #delete the folder from local mahine
    Remove-Item $folderPath -Force  -Recurse -ErrorAction SilentlyContinue


    # lock ResourceGroup
                #Lock-ResourceGroup $resourceGroupName
                write-verbose "ResourceGroup locked"

    return $result

}



function Publish-Infrastructure
{
param(
        [parameter(Mandatory = $true)][string]$settingsFileName
     )

    $settings = Get-JsonParameterSet -settingsFileName $settingsFileName
    $deploymentIsSucceeded = $true
    $workloadCount = $settings.WorkLoads.Count
    Write-Verbose "workloadCounts: $workloadCount"
    if($workloadCount -ge 1)
    {
        for($i = 0;$i -lt $workloadCount; $i++)
            { 

                $applicationName = $settings.WorkLoads[$i].applicationName
                Write-Verbose "application name: $applicationName"
                $environmentName = $settings.WorkLoads[$i].environmentName
                $applicationFile = "..\SettingsByWorkload\" + "nv_" + $applicationName + ".workload.json"
                $applicationFile = Get-FileFullPath -fileName $applicationFile  -rootPath $PSScriptRoot
                $applicationFileJson = Get-JsonParameterSet -settingsFileName $applicationFile
                Write-Verbose "application file json: $applicationName"
                $null = Test-ParameterSet -settings $settings

                $policyCount = $applicationFileJson.subscriptions.Count
                Write-Verbose "$policyCount"
                if($policyCount -ge 1)
                {  
                    for($j = 0;$j -lt $policyCount; $j++)
                    { 


                        if($applicationFileJson.subscriptions[$j].environmentName -eq $environmentName)
                        {    

                            $subscriptionId = $applicationFileJson.subscriptions[$j].subscriptionId 
                            Write-Verbose "Environment Subscription: $($subscriptionId)"
                            Set-ContextIfNeeded -SubscriptionId $subscriptionId
                            foreach ($webjob in $settings.WorkLoads[$i])
                            {                   
                                                $resourceGroupName = $webjob.resourceGroupName
                                                $webAppName = $webjob.webAppName
                                                $Storagerg = $webjob.Storagerg
                                                $webjobname = $webjob.webjobname
                                                $webjobtype = $webjob.webjobtype
                                                $storageAccountName = $webjob.storageAccountName
                                                $schedule = $webjob.schedule
                                                $container_name = $webjob.container_name
                                                $trigger_type = $webjob.trigger_type
                                                Write-Verbose "Ready to start deployment on environment $EnvironmentName of a webjob in subscription $subscriptionId for resource group: $resourceGroupName"

                                                $result = Publish-webjob ` -resourceGroupName $resourceGroupName `
                                                -webAppName $webAppName `
                                                -Storagerg $Storagerg `
                                                -webjobname $webjobname `
                                                -webjobtype $webjobtype `
                                                -storageAccountName $storageAccountName `
                                                -settingsFileName $settingsFileName `
                                                -container_name $container_name `
                                                -i $i

                            }
                        }
                    }
                }        
            }

    }

        return $true

}


#START OF SCRIPT
if ($unitTestMode)
{
    #do nothing
    Write-Verbose 'Unit test mode, no deployment' -Verbose
}
else 
{
  #Log in Azure if not already done
    try 
    {
        $azureRmContext = Get-AzureRmContext -ErrorAction Stop
    }
    catch 
    {
        $result = Add-AzureRmAccount
        $azureRmContext = $result.Context
    }
    Write-Verbose "Subscription name $($azureRmContext.Subscription.Name)" -Verbose
    $VerbosePreference = 'Continue'

    # Get required templates and setting files. Throw if not found
    $scriptsPath=$PSScriptRoot

    $scriptsPath = Split-Path -Path $scriptsPath -Parent  


    $SettingsPath = Join-Path $scriptsPath $settingsFileName

    $settingsFileName = $SettingsPath



    Write-Verbose "Settings file name $($settingsFileName)" -Verbose

    # Deploy infrastructure
    return Publish-Infrastructure `
        -settingsFileName $settingsFileName `

# END of script
}