我正在尝试使用PowerShell脚本将Web作业部署到Azure,我们有自己的部署框架,当我从本地计算机部署时,只有拥有管理员或共同管理员权限才能成功部署参与者访问脚本失败。我们的部署框架只有参与者权限,有没有办法用参与者权限部署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`
答案 0 :(得分:1)
您可以使用此blog中的示例。
#Resource details :
$resourceGroupName = "<Resourcegroup name>";
$webAppName = "<WebApp name>";
$Apiversion = 2015-08-01
#Function to get Publishing credentials for the WebApp :
function Get-PublishingProfileCredentials($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 $publishingCredentials
}
#Pulling authorization access token :
function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName){
$publishingCredentials = Get-PublishingProfileCredentials $resourceGroupName $webAppName
return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f
$publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
}
$accessToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppname
#Generating header to create and publish the Webjob :
$Header = @{
'Content-Disposition'='attachment; attachment; filename=Copy.zip'
'Authorization'=$accessToken
}
$apiUrl = "https://$webAppName.scm.azurewebsites.net/api/<Webjob-type>/<Webjob-name>"
$result = Invoke-RestMethod -Uri $apiUrl -Headers $Header -Method put -InFile "<Complete path of the file>\
<filename>.zip" -ContentType 'application/zip'
#NOTE: Update the above script with the parameters highlighted and run in order to push a new Webjob under the specified WebApp.
对于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
答案 1 :(得分:0)
以下几行代码是Power Shell脚本,它使您可以在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
}