Hi @Thomas Lu ,
Firstly, there were two probable typos in the code that you have shared.
- Value of $jobOutputURL contains unwanted "}" after $resourceGroup.
- Uri mentioned in the last line of the code is referring to $webhookUrl but it is supposed to consider $jobOutputURL.
After removing those probable typos, I have created below sample runbook to solve this issue.
Then, I have created webhook as shown below.
Then, I have tried the same way as you did and have received same authorization header missing error.
This is because the last line of the code thats using the second Invoke-RestMethod command doesn't understand using which access token or authorization it should use to send an HTTP or HTTPS request to the RESTful web service API resource URI management.azure.com that we have stored in the variable $jobOutputURL.
So, we need to add headers parameter to that Invoke-RestMethod cmdlet which should contain access token. For that, as a one-time task, you would have to create a service principal, the one that makes the API call, grant permission, generate client secret. Next, you can use PowerShell to get bearer token and use it in our second Invoke-RestMethod command as shown below.
Job output from UI:
Lastly, find the code below so it can be easily used in your environment:
# Replace these variables with your desired values
$spName = "xxxxxxxxxxxx" # Replace with the desired service principal name
$role = "Contributor" # Replace with the desired role
# Create a new service principal with RBAC
$sp = New-AzADServicePrincipal -DisplayName $spName
# Assign the desired role to the service principal
New-AzRoleAssignment -RoleDefinitionName $role -ServicePrincipalName $sp.AppId
$tenantId = $sp.AppOwnerOrganizationId
$clientId = $sp.AppId
$clientSecret = $sp.PasswordCredentials.SecretText
$resource = "https://management.azure.com/" # Replace with your API resource URI
$tokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/token"
$tokenParams = @{
"grant_type" = "client_credentials"
"client_id" = $clientId
"client_secret" = $clientSecret
"resource" = $resource
}
Start-Sleep -Seconds 120
$tokenResponse = Invoke-RestMethod -Uri $tokenUrl -Method Post -ContentType "application/x-www-form-urlencoded" -Body $tokenParams
$accessToken = $tokenResponse.access_token
$headers = @{
"Authorization" = "Bearer $accessToken"
}
$webhookUrl = "xxxxxxxxxxxxxxxxxx" # Replace with your webhook Url
$jsonBody = '{ "samaccountname":"thomas.lu" }'
$response = Invoke-RestMethod -Uri $webhookUrl -Method Post -ContentType "application/json" -Body $jsonBody
$subscriptionID = "xxxxxxxxxxxxxxxxxxx" # Replace with your subscription ID
$resourceGroup = "xxxxxxxxxxxxxxxxxxxxx" # Replace with your resource group name
$automationAccount = "xxxxxxxxxxxxxxxxx" # Replace with your automation account name
$jobOutputURL = "https://management.azure.com/subscriptions/$subscriptionID/resourceGroups/$resourceGroup/providers/Microsoft.Automation/automationAccounts/$automationAccount/jobs/$($response.JobIds[0])/output?api-version=2019-06-01"
Start-Sleep -Seconds 120
$requestOutput = Invoke-RestMethod -Uri $jobOutputURL -Method Get -Headers $headers
$requestOutput
Let me know if you have any questions.