Can I use MFA app passwords with Azure oauth2.0 ROPC? - azure

In powershell we have a script that gets info from Azure REST API using Resource Owner Password Credentials.
https://learn.microsoft.com/bs-latn-ba/azure/active-directory/develop/v2-oauth-ropc
The script works perfectly with users that don't have MFA enabled. For user with MFA it doesn't work.
I tried to use an app password that I created on the user account with MFA but this didn't work also.
https://support.microsoft.com/en-au/help/12409/microsoft-account-app-passwords-and-two-step-verification
The script is running as a service so user interaction is no option. We also need to use ROPC because the info we needed is only available trough delegated permisions on the Azure app.
Is there anyone that has experience with this?
Here is the script:
$tenantid = '*************************'
$subscriptionid = '*********************'
$clientid = '***********************'
$clientsecret = '******************'
$username = '*****************'
$password = '************************'
##################################################################
##################################################################
##################################################################
$return = Invoke-Command -ScriptBlock {
param($tenantid,$subscriptionid,$clientid,$clientsecret,$username,$password)
Add-Type -AssemblyName System.Web
$encPass = [System.Web.HttpUtility]::UrlEncode($password)
$encScope = [System.Web.HttpUtility]::UrlEncode('https://management.azure.com/user_impersonation')
$encSecret = [System.Web.HttpUtility]::UrlEncode($clientsecret)
$body = "client_id=$clientid&scope=$encScope&username=$username&password=$encPass&grant_type=password&client_secret=$encSecret"
$auth = Invoke-WebRequest "https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token" -Method Post -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing
$token = ($auth | ConvertFrom-Json).access_token
$headers = #{
'Authorization'="Bearer $($token)"
}
$data = Invoke-WebRequest "https://management.azure.com/subscriptions/$subscriptionid/providers/Microsoft.Advisor/recommendations?api-version=2017-04-19" -Method GET -Headers $headers -UseBasicParsing
New-Object PSObject -Property #{
content=$data.content
}
} -ArgumentList $tenantid,$subscriptionid,$clientid,$clientsecret,$username,$password
$content = $return.content
Write-Host $content
The output when I use an user with MFA enabled:
Invoke-WebRequest : {"error":"invalid_grant","error_description":"AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to
access '*******'.\r\nTrace ID: d9a7f9f2-c52c-40ca-b057-9513bd353900\r\nCorrelation ID: 3329e686-7bd0-409d-b7da-91e49221bacc\r\nTimestamp: 2019-10-02
13:19:36Z","error_codes":[50076],"timestamp":"2019-10-02
13:19:36Z","trace_id":"d9a7f9f2-c52c-40ca-b057-9513bd353900","correlation_id":"3329e686-7bd0-409d-b7da-91e49221bacc","error_uri":"https://login.microsoftonline.com/error?code=50076","suberror":"basic_action"}
At C:\Users\Wouter.sterkens\Documents\VS Projects\Azure Monitoring\advisor.ps1:27 char:9
+ $auth = Invoke-WebRequest "https://login.microsoftonline.com/$tenanti ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
ConvertFrom-Json : Cannot bind argument to parameter 'InputObject' because it is null.
At C:\Users\Wouter.sterkens\Documents\VS Projects\Azure Monitoring\advisor.ps1:29 char:19
+ $token = ($auth | ConvertFrom-Json).access_token
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [ConvertFrom-Json], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
Invoke-WebRequest : {"error":{"code":"AuthenticationFailedMissingToken","message":"Authentication failed. The 'Authorization' header is missing the access token."}}
At C:\Users\Wouter.sterkens\Documents\VS Projects\Azure Monitoring\advisor.ps1:34 char:9
+ $data = Invoke-WebRequest "https://management.azure.com/subscriptions ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
The output when I change the password with an app password created on the user account
Invoke-WebRequest : {"error":"invalid_grant","error_description":"AADSTS50126: Invalid username or password.\r\nTrace ID: 3674934a-120b-48f3-96d8-7ec8ddf44300\r\nCorrelation ID:
593aecd7-bbb2-4c5a-96e1-050bc00047ac\r\nTimestamp: 2019-10-02 13:26:46Z","error_codes":[50126],"timestamp":"2019-10-02
13:26:46Z","trace_id":"3674934a-120b-48f3-96d8-7ec8ddf44300","correlation_id":"593aecd7-bbb2-4c5a-96e1-050bc00047ac","error_uri":"https://login.microsoftonline.com/error?code=50126"}
At C:\Users\Wouter.sterkens\Documents\VS Projects\Azure Monitoring\advisor.ps1:27 char:9
+ $auth = Invoke-WebRequest "https://login.microsoftonline.com/$tenanti ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
ConvertFrom-Json : Cannot bind argument to parameter 'InputObject' because it is null.
At C:\Users\Wouter.sterkens\Documents\VS Projects\Azure Monitoring\advisor.ps1:29 char:19
+ $token = ($auth | ConvertFrom-Json).access_token
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [ConvertFrom-Json], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
Invoke-WebRequest : {"error":{"code":"AuthenticationFailedMissingToken","message":"Authentication failed. The 'Authorization' header is missing the access token."}}
At C:\Users\Wouter.sterkens\Documents\VS Projects\Azure Monitoring\advisor.ps1:34 char:9
+ $data = Invoke-WebRequest "https://management.azure.com/subscriptions ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

As far as I know, app password is used to complete MFA with the clients which do not support modern authentication. Now, you use ROPC OAuth flow. APP password does not support it.
According to the situation, I suggest you finish MFA manually to get refresh token then we use refresh token to get access token and call API. Because MFA refresh token will not expire until you revoke it. Or you use OAuth 2.0 client credentials flow to get the access token. For example
User refresh token
Register Azure AD application
Use OAuth 2.0 authorization code flow to complete MFA and get refresh token
$Params = #{
'client_id' = 'b0114608-677e-4eca-ae22-60c32e1782d9'
'redirect_URI' = 'https://www.baidu.com'
'response_type'='code'
'scope' = 'offline_access openid https://management.azure.com/user_impersonation'
}
$ClientSecret =''
$TeantID = ''
$Query = "?"; $Params.Keys | % {$Query+= "$($_)=$($Params.Item($_))&"} ; $Query = $Query.TrimEnd('&')
$IE= new-object -ComObject "InternetExplorer.Application"
$IE.Visible = $true
$IE.navigate2("https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/authorize$Query")
write-host "get authorization code"
pause
Add-Type -AssemblyName System.Web
[System.Web.HttpUtility]::ParseQueryString(([uri] $IE.LocationURL).Query)['code']
$Code = [System.Web.HttpUtility]::ParseQueryString(([uri] $IE.LocationURL).Query)['code']
$IE.Quit()
$TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/token" -Body #{
client_id = $Params.client_id
scope = ''
code = $Code
redirect_uri = $Params.Redirect_URI
grant_type = 'authorization_code'
client_secret = $ClientSecret
}
$TokenResult.refresh_token
Get Access token and call the api
$TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/token" -Body #{
client_id = ''
scope = 'https://management.azure.com/user_impersonation'
redirect_uri = ''
grant_type = 'refresh_token'
client_secret = ''
refresh_token =''
}
Invoke-RestMethod -Method Get -Uri '' -Headers #{Authorization = "Bearer "+ $TokenResult.access_token}
Use OAuth 2.0 client credentials flow
$TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/token" -Body #{
client_id = ''
scope = 'https://management.azure.com/.default'
grant_type = 'client_credentials'
client_secret = ''
}
Invoke-RestMethod -Method Get -Uri '' -Headers #{Authorization = "Bearer "+ $TokenResult.access_token}
Update
According to your need, you can create a service principal and assign RABC role to the service principal. Then you can OAuth 2.0 client credentials flow to get access token and call Azure rest api. The detailed steps are as below
Create a service principal and assign RABC role to the service principal
Connect-AzAccount
$password=''
$credentials = New-Object Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential -Property #{ StartDate=Get-Date; EndDate=Get-Date -Year 2024; Password=$password'}
$sp = New-AzAdServicePrincipal -DisplayName jimtest1 -PasswordCredential $credentials
New-AzRoleAssignment -ApplicationId $sp.ApplicationId -RoleDefinitionName Owner
Get access token
# get access token
$TeantID='hanxia.onmicrosoft.com'
$TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/token" -Body #{
client_id = $sp.ApplicationId # the application id of service principal
scope = 'https://management.azure.com/.default'
grant_type = 'client_credentials'
client_secret = $password # you use it in step 1
}
Call Azure Rest API
#list resource group
$values =Invoke-RestMethod -Method Get -Uri "https://management.azure.com/subscriptions/e5b0fcfa-e859-43f3-8d84-5e5fe29f4c68/resourcegroups?api-version=2019-05-10" -Headers #{
Authorization = "Bearer "+ $TokenResult.access_token
ContentType = 'application/json'
}
For more details, please refer to
https://learn.microsoft.com/en-us/powershell/azure/create-azure-service-principal-azureps?view=azps-2.7.0
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-api-authentication#get-app-only-access-token-for-azure-resource-manager

Related

Unable to create Azure B2C User Flow via powershell with b2cIdentityUserFlow

I am trying to create a user flow with PowerShell, but I receiveThe remote server returned an error: (403) Forbidden.. I was reading the documentation from Microsoft but with no success.
Connect-AzAccount -Tenant "myorg.onmicrosoft.com"
$managementAccessToken = Get-AzAccessToken -TenantId "$tenantId" -ResourceTypeName MSGraph
$DefinitionFilePath = "C:\azdeploy\flows\b2csignin.json"
$signinFlowContent = Get-Content $DefinitionFilePath
Invoke-WebRequest -Uri "https://graph.microsoft.com/beta/identity/b2cUserFlows" `
-Method "POST" `
-Headers #{
"Content-Type" = "application/json"
"Authorization" = "Bearer $($managementAccessToken.Token)";
} `
-Body $signinFlowContent
JSON Content(Default From Microsoft Docs):
{
"id": "Customer",
"userFlowType": "signUpOrSignIn",
"userFlowTypeVersion": 3
}
Connect-AzAccount is made with a user who is Global Administrator, also tried with Lifecycle Workflows Administrator permissions. I don't know what to do, trying the old API but it is deprecated. I need to create a few User Flows with а few Application Claims. How can I achieve this?
Thanks!
I tried to reproduce the same in my environment and got below results:
I created one json file with same parameters as you like below:
I have one user named Sritest having Global Administrator role like below:
When I ran the same code as you by signing in with above user, I got same error as below:
Connect-AzAccount -Tenant "myorg.onmicrosoft.com"
$managementAccessToken = Get-AzAccessToken -TenantId "$tenantId" -ResourceTypeName MSGraph
$DefinitionFilePath = "C:\test\b2csignin.json"
$signinFlowContent = Get-Content $DefinitionFilePath
Invoke-WebRequest -Uri "https://graph.microsoft.com/beta/identity/b2cUserFlows" `
-Method "POST" `
-Headers #{
"Content-Type" = "application/json"
"Authorization" = "Bearer $($managementAccessToken.Token)";
} `
-Body $signinFlowContent
Response:
You need to have IdentityUserFlow.ReadWrite.All permission to create userflow.
To resolve the error, I registered one Azure AD application and added that API permission like below:
Make sure to grant admin consent after adding API permissions in application. Now, I created one client secret and added all these details in getting access token by modifying PowerShell code.
When I ran below modified code, userflow created successfully as below:
Connect-AzureAD -TenantId "c6d99123-0cf9-4b64-bde3-xxxxxxxxx"
$graphtokenBody = #{
grant_type = "client_credentials"
scope = "https://graph.microsoft.com/.default"
client_id = "appID"
client_secret = "secret"
}
$graphToken = Invoke-RestMethod -Uri "https://login.microsoftonline.com/c6d99123-0cf9-4b64-bde3-xxxxxxxxx/oauth2/v2.0/token" -Method POST -Body $graphtokenBody
$token = $graphToken.access_token
$DefinitionFilePath = "C:\test\b2csignin.json"
$signinFlowContent = Get-Content $DefinitionFilePath
Invoke-WebRequest -Uri "https://graph.microsoft.com/beta/identity/b2cUserFlows" `
-Method "POST" `
-Headers #{
"Content-Type" = "application/json"
"Authorization" = "Bearer $($token)";
} `
-Body $signinFlowContent
Response:
To confirm that, I checked the same in Portal where B2C_1_Customer userflow is present like below:

Storage REST API Returns Remote Name Could Not be Resolve Often

I am calling the storage REST API to get container names using
Invoke-WebRequest -Method GET -Uri $storage_url -Headers $headers
This command often returns 'remote name could not be resolved error', even when the storage account exists and is reachable. Just running the command again gives correct result.
Invoke-WebRequest : The remote name could not be resolved: '<storageAccountName>.blob.core.windows.net'
At line:1 char:1
+ Invoke-WebRequest -Method GET -Uri $storage_url -Headers $headers #In ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
From the information you provided, you use the client credential flow to get the access token, then use the token to call the Storage Rest API - List Containers.
You could use the script below, it works for me.
Make sure the service principal you used has a RBAC role e.g. Contributor/Owner in your storage account -> Access Control, if not, click the Add to add it.
$ClientID = "xxxxxxx"
$ClientSecret = "xxxxxxx"
$tennantid = "xxxxxxx"
$storageaccountname = "joystoragev2"
$TokenEndpoint = {https://login.microsoftonline.com/{0}/oauth2/token} -f $tennantid
$Resource = "https://storage.azure.com/"
$Body = #{
'resource'= $Resource
'client_id' = $ClientID
'grant_type' = 'client_credentials'
'client_secret' = $ClientSecret
}
$params = #{
ContentType = 'application/x-www-form-urlencoded'
Headers = #{'accept'='application/json'}
Body = $Body
Method = 'Post'
URI = $TokenEndpoint
}
$token = Invoke-RestMethod #params
$accesstoken = $token.access_token
$url = {https://{0}.blob.core.windows.net/?comp=list} -f $storageaccountname
$header = #{
'Authorization' = 'Bearer ' + $accesstoken
'x-ms-version' = '2019-02-02'
}
$response = Invoke-WebRequest –Uri $url –Headers $header –Method GET
$response.RawContent

calling azure graph api to fetch Get-PimAzureResourceRoleDefinition

I am trying to a call graphapi to get roledefination but i am getting permission errors, and have i checked my service prnciple it had all required permissions.
Invoke-RestMethod : {
"error": {
"code": "UnknownError",
"message": "{\"errorCode\":\"PermissionScopeNotGranted\",\"message\":\"Authorization failed due to missing permission scope PrivilegedAccess.ReadWrite.AzureResources,PrivilegedAccess.Read.AzureResources.\",\"target\":null,\"details\":null,\"innerError\":null,\"instanceAnnotations\":[],\"typeAnnotation\":null}",
"innerError": {
"request-id": "d762f8d4-2cc4-428e-b1ea-7623d8d388f1",
"date": "2020-06-03T04:25:03"
}
}
}
At line:38 char:15
+ $Result = Invoke-RestMethod -Uri $uri -Headers $Headers
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Below is my code
========================
$TenantName = 'xxxx.onmicrosoft.com'
$ClientId = 'xxxxxx'
$ClientSecret = "xxxxxx"
# Create a hashtable for the body, the data needed for the token request
# The variables used are explained above
$Body = #{
'tenant' = $TenantId
'client_id' = $ClientId
'scope' = 'https://graph.microsoft.com/.default'
'client_secret' = $ClientSecret
'grant_type' = 'client_credentials'
}
$Params = #{
'Uri' = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
'Method' = 'Post'
'Body' = $Body
'ContentType' = 'application/x-www-form-urlencoded'
}
$AuthResponse = Invoke-RestMethod #Params
$Headers = #{
'Authorization' = "Bearer $($AuthResponse.access_token)"
}
#Find Pim Role
$uri = "https://graph.microsoft.com/beta/privilegedAccess/azureResources/resources/xxxxxxxxxxxx/roleDefinitions`?`$filter=displayName eq 'xxxxxx-Contributors'"
$Result = Invoke-RestMethod -Uri $uri -Headers $Headers
Also how to get resource id of roledefination which we are passing in URL after /resources
Check your Api permissions, make sure the PrivilegedAccess.Read.AzureResources is selected and click the button Grant admin consent for xxx.
You could decode your access_token via https://jwt.io/, scp shows your scopes.
Update:
how to get resource id of roledefination which we are passing in URL after /resources
try request this:
GET https://graph.microsoft.com/beta/privilegedAccess/azureResources/resources

Microsoft Graph - Grant_Type client_credentials calendarview - Access is denied. Check credentials and try again

I am using PowerShell to get Calendar events from MS Graph.
Grant Type: client_credentials
$clientId = "xxx"
$tenantName = "xxx"
$clientSecret = "xxx"
$resource = "https://graph.microsoft.com/"
$ReqTokenBody = #{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
client_Id = $clientID
Client_Secret = $clientSecret
}
$TokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody
Grant Type: Password
$clientID = "xxx"
$tenantName = "xxx"
$ClientSecret = "xxx"
$Username = "xxx#xxx.com"
$Password = "xxx"
$ReqTokenBody = #{
Grant_Type = "Password"
client_Id = $clientID
Client_Secret = $clientSecret
Username = $Username
Password = $Password
Scope = "https://graph.microsoft.com/.default"
}
$TokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token" -Method POST -Body $ReqTokenBody
Get Calendar Events:
$apiUrl = "https://graph.microsoft.com/v1.0/groups/xxxxxxxxxx/calendarview?startdatetime=$mystartdate1&enddatetime=$myenddate1&orderby=start/DateTime ASC&top=100"
$Data = Invoke-RestMethod -Headers #{Authorization = "Bearer $($Tokenresponse.access_token)"} -Uri $apiUrl -Method Get
$Groups = ($Data | select-object Value).Value
#$Groups | Format-Table subject, start -AutoSize
$Groups | Select-Object -Property subject, Start, End
If I authenticate by Password Grant Type then it displays the results.
However if I authenticate by Client Credentials Grant Type then it throws following error:
Invoke-RestMethod : {
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"request-id": "cc111097-c8c2-4a35-af21-52cbbced33b7",
"date": "2019-11-29T09:37:51"
}
}
}
At line:10 char:9
+ $Data = Invoke-RestMethod -Headers #{Authorization = "Bearer $($Token ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
With the Client Credentials Grant Type I have no problem getting results from
$apiUrl = "https://graph.microsoft.com/v1.0/users/"
$apiUrl = 'https://graph.microsoft.com/v1.0/groups'
$apiUrl = "https://graph.microsoft.com/v1.0/devicemanagement/manageddevices"
Am I doing something wrong or the client credentials authentication cannot pull the calendar events.
When using the client credential flow to get the access token for Microsoft Graph, the Application permission in your AD App -> API permissions is needed.
But in this case, the Application permission is not supported for the List calendarView API. Without this permission, the token you got will not be able to call this API successfully.

Save-AzureWebSiteLog Invoke-WebRequest error

I was really close to finish my job but it started to cause this error.
when I execute this
Save-AzureWebSiteLog -Name $WebSiteName -Output "C:\logs\error.zip"
Save-AzureWebSiteLog : The maximum message size quota for incoming
messages (65536) has been exceeded. To increase the quota, use the
MaxReceivedMessageSize property on the appropriate binding element.
so, I searched for the solution, it seems like that many people have exact same problem.
https://azure.microsoft.com/en-us/blog/windows-azure-websites-online-tools-you-should-know-about/
Thanks to #Parth Sehgal, I have tried to solve the problem by using powershell
$username = "maiemai"
$password = "Password"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))
$apiUrl = "https://wngphase2it.scm.azurewebsites.net/api/zip/LogFiles/"
$response = Invoke-WebRequest -Uri $apiUrl -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET
try
{
$filename = [System.IO.Path]::GetFileName($response.BaseResponse.ResponseUri.OriginalString)
$filepath = [System.IO.Path]::Combine("c:\asdf\", "http1.zip")
$filestream = [System.IO.File]::Create($filepath)
$response.RawContentStream.WriteTo($filestream)
}
finally
{
$filestream.Close()
}
but I am stuck with this error
Invoke-WebRequest : Server Error
401 - Unauthorized: Access is denied due to invalid credentials.
You do not have permission to view this directory or page using the credentials that you supplied.
At line:5 char:13
+ $response = Invoke-WebRequest -Uri $apiUrl -Headers #{Authorization=("Basic {0}" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest],
WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
You cannot call a method on a null-valued expression.
At line:11 char:1
+ $response.RawContentStream.WriteTo($filestream)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Username and Password is definitely correct, but it is still causing this error.
How should I change this line?
$response = Invoke-WebRequest -Uri $apiUrl -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET
First of all, your username is incorrect in this case.
In order to use the Azure Kudu REST API to retrieve the zipped log files for your Azure web app, you will need to use your web app's MSDeploy credential in the publish profile file.
The correct form of Azure web app's MSDeploy username should be ${yoursitename}.
You can get your web app's publish profile from the new Azure portal or via Azure PowerShell command: Get-AzureRMWebAppPublishingProfile
I have also fixed the issue in your PowerShell script which I tested with my own web app.
$username = "`$wngphase2it"
$password = "yourMSDeployUserPwd"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))
$apiUrl = "https://wngphase2it.scm.azurewebsites.net/api/zip/LogFiles/"
$response = Invoke-WebRequest -Uri $apiUrl -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET
try
{
$filename = [System.IO.Path]::GetFileName($response.BaseResponse.ResponseUri.OriginalString)
$filepath = [System.IO.Path]::Combine("c:\asdf\", "http1.zip")
$filestream = [System.IO.File]::Create($filepath)
$response.RawContentStream.WriteTo($filestream)
}
finally
{
$filestream.Close()
}
Reference: Sample of using Kudu REST API with PowerShell
Let me know whether it helps to resolve your issue.

Resources