WebJobs not stopping by using the Rest API Post method within powershell script - Getting Error 403 - This web app is stopped - azure

When switching slots withing azure on my application, i am trying to stop the webjobs on the "stopped" server as they seem to keep running within azure. However when i use the invoke-restmethod within my powershell script, it comes back with Error 403 - This web app is stopped, but on my azure site it is still running. Frustratingly i can use the method when using postman, but when it comes to my script with the identical request it is not stopping the webjobs.
I have tried running this particular script within powershell, but it wont run due to the stated error. The Get method works fine in powershell, bringing back the application, but the stop rest call does not.
function StopWebJob($slotToStop) {
# Get an access token to authenticate the web jobs API
Write-Verbose -Verbose "Getting an access token..."
$stopToken = Get-BasicAuthToken $slotToStop
Write-Verbose -Verbose "Got access token."
#Generate a header to start/stop the web jobs using the access token
$stopHeader = #{ 'Authorization'= $stopToken }
Write-Verbose -Verbose "Checking job status..."
$getJob = "https://$WebAppName-$slotToStop.scm.azurewebsites.net/api/continuouswebjobs/{myWebJob}/"
$getJobResult = Invoke-RestMethod -Uri $getJob -Headers $stopHeader -Method Get
If($getJobResult.status -ne "Stopped") {
Write-Verbose -Verbose "Stopping job..."
$stop = "https://$WebAppName-$slotToStop.scm.azurewebsites.net/api/continuouswebjobs/{MyWebJob}/stop"
Invoke-RestMethod -Uri $stop -Headers $stopHeader -Method Post
Write-Verbose -Verbose "Job stopped."
} else {
Write-Verbose -Verbose "Job is already stopped."
}
}
When the slot switches, I expect the Job on the "down" slot to be stopped via the rest api.

I can reproduce your issue, looks you missed the -UserAgent in the Invoke-RestMethod.
It should be like below, add the -UserAgent "powershell/1.0" to your command.
Invoke-RestMethod -Uri $stop -Headers $stopHeader -Method Post -UserAgent "powershell/1.0"
Then it will work fine, you could refer to my complete sample.
$username = "`$website"
$password = "pwd"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $password)))
Write-Verbose -Verbose "Checking job status..."
$getJob = "https://<webappname>-slot1.scm.azurewebsites.net/api/continuouswebjobs/webjob1"
$getJobResult = Invoke-RestMethod -Uri $getJob -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method Get
If($getJobResult.status -ne "Stopped") {
Write-Verbose -Verbose "Stopping job..."
$stop = "https://<webappname>-slot1.scm.azurewebsites.net/api/continuouswebjobs/webjob1/stop"
Invoke-RestMethod -Uri $stop -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method Post -UserAgent "powershell/1.0"
Write-Verbose -Verbose "Job stopped."
} else {
Write-Verbose -Verbose "Job is already stopped."
}

Related

Why do I get "Request Entity Too Large" When Using the ZipDeploy API Azure?

I have a ASP.NET zip that I'm attempting to upload to an ASE slot using the zipdeploy API, and for one slot it's erroring out resulting in a "Request entity too large" error.
Here's the code I'm using:
$url = "https://" + $slot + "/api/zipdeploy?isAsync=true"
Invoke-WebRequest -Uri $url -Headers #{Authorization = ("Basic {0}" -f $authInfo)} -Method POST -UseBasicParsing -InFile $zip -ContentType "multipart/form-data"
If I use a relatively small zip it'll work, but if I use the zip I want which is 100MB+, it'll fail.

Azure devops release edit bulk 110

Hello I have 145 releases
And I have to do an equal action for everyone for example add a certain variable and edit a certain line.
Is there a way to control everyone with a script?
I checked for a template, but it creates the release from 0 and does not edit it.
Can a script in PS or Python be a solution? I did not find any information on Google about it, other than an export release template.
Azure devops release edit bulk 110
You could use the REST API Definitions - Update to update the release pipeline:
PUT https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/{DefinitionsId}?api-version=6.0
And if we want to batch modify the release pipeline, we need to get each ID of the release pipeline with REST API Definitions - List:
GET https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions?api-version=6.0
Then we could iterate through each Rlease ID obtained.
I provide a rough code for your better reading:
$connectionToken="PAT"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$ReleasePipelineUrl = "https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions?api-version=6.0"
Write-Host "URL: $ReleasePipelineUrl"
$ReleasePipelines = (Invoke-RestMethod -Uri $PipelineUrl -Method Get -UseDefaultCredential -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)})
$ReleasePipelinesId = $ReleasePipelines.value.id
Write-Host "ReleasePipelinesId = $ReleasePipelinesId"
ForEach ($Pt in $ReleasePipelinesId)
{
$baseUrl = "https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/$($Pt)?api-version=6.0"
$pipeline = (Invoke-RestMethod -Uri $baseUrl -Method Get -UseDefaultCredential -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)})
Write-Host "URL: $baseUrl"
$pipeline.variables.TestValue.value = "$buildNumber"
####****************** update the modified object **************************
$json = #($pipeline) | ConvertTo-Json -Depth 99
Write-Host "URL: $json "
$updatedef = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers #{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}
write-host "=========================================================="
Write-host "The value of Varialbe 'TestValue' is updated to" $updatedef.variables.TestValue.value
}

'Invoke-RestMethod : The remote server returned an error: (401) Unauthorized' only in Azure DevOps release pipeline

I have a PowerShell script that works from a local PowerShell but when it runs in a PowerShell task in an Azure DevOps release pipeline it returns Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.
The user is added as a project member within Azure DevOps and I have also created a Personal Access Token with full access.
function Get-HttpBasicHeader([string]$username, [string]$password)
{
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $userName, $password)))
return #{Authorization=("Basic {0}" -f $base64AuthInfo)}
}
$headers = Get-HttpBasicHeader $userName $password
$url = "https://transpa.vsrm.visualstudio.com/transPA/_apis/release/releases?definitionId=42&definitionEnvironmentId=61&api-version=5.0"
$response = Invoke-RestMethod -Uri $url -Method Get -Headers $headers
What am I doing wrong? Let me know if I should provide any additional information.

Outlook rest-api from powershell returning oath request (401)

I'm trying to create an auto notification app from outlook,
which I tried to use outlook rest API to do that.
for now I'm just making a simple code, but the result always returning error code 401
I've tried to register my apps into app registration on my Azure tenants. but have no luck nor I understand what to do next...
$uri = "https://outlook.office365.com/api/v2.0/me/sendmail"
$userName = << my username >>
$password = << my password >>
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $userName,$password
$body = "{
""Subject"":""rest API test"",
""Importance"":""High"",
""Body"":{
""ContentType"":""HTML"",
""Content"":""test test 1 2 3""
},
""ToRecipients"":[{
""Address"":""<< my recipients >>""
}]
}"
Invoke-RestMethod -Uri $uri -Method Post -Credential $credb -ContentType "application/json" -Body $body
the result from api said :
{"error":{"code":"OAuthMissingForThisApiVersion","message":"Authentication for this API version requires OAuth."}}
which is why I tried to register my app to azure app registration to get my token.
do anyone knows how to solve this problem?
or even some tutorial to show me how to set an app registration until I can get the token to my powershell app.
regards,
https://outlook.office.com/api/v1.0 doesn't support Basic auth as OAuth is the recommended auth mechanism, but you can continue to use https://outlook.office365.com/api/v1.0 if you need to keep using Basic auth.
Try something like below, it should work
$uri = "https://outlook.office365.com/api/v1.0/me/sendmail"
$UserName = "mv.v#my.domain"
$Password = cat C:\MydomainCreds.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username,$password
$body = "{
""Message"":{
""Subject"": ""This is a send test"",
""Importance"": ""High"",
""Body"": {
""ContentType"": ""HTML"",
""Content"": ""How about this for a surprise!""
},
""ToRecipients"": [
{
""EmailAddress"":{
""Address"": ""mytestmailbox#anywhere.com""
}
}
]
}}"
Invoke-RestMethod -Uri $uri -Method Post -Credential $cred -ContentType "application/json" -Body $Body
Hope it helps.

Azure Function Key Management API - Authentication error

I have two Azure function apps, both in the same Azure subscription. I can retrieve keys for one but not for the other. As far as I can see there is no difference between the two function apps.
I'm using this Powershell code:
function GetHostKey
{
param($webAppName, $resourceGroupName)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Write-Host "Getting master key from $webAppName"
$xml = [xml](Get-AzureRmWebAppPublishingProfile -Name $webAppName -ResourceGroupName $resourceGroupName -Format WebDeploy -OutputFile null)
$msdeployUsername = $xml.SelectNodes("//publishProfile[#publishMethod=`"MSDeploy`"]/#userName").value
$msdeployPassword = $xml.SelectNodes("//publishProfile[#publishMethod=`"MSDeploy`"]/#userPWD").value
$apiBaseUrl = "https://$webAppName.scm.azurewebsites.net/api"
$siteBaseUrl = "https://$webAppName.azurewebsites.net"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $msdeployUsername,$msdeployPassword)))
$jwt = Invoke-RestMethod -Uri "$apiBaseUrl/functions/admin/token" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET
$uri = "$siteBaseUrl/admin/host/systemkeys/_master"
$response = Invoke-RestMethod -Uri $uri -Headers #{Authorization=("Bearer {0}" -f $jwt)} -Method GET
return $response.value
}
The call to $siteBaseUrl/admin/host/systemkeys/_master returns the expected json for one function app, but the other one returns a login screen.
Compare both functions settings, versions. Try to get the keys manually from the portal to isolate the source of the problem. I had the same problem till i deleted and recreated the functions.

Resources