I am trying to write a script in PowerShell ISE (5.1) that retrieves all customers using the PartnerCenter Powershell. My script is:
type here# Azure AD Application Configuration
$tenantId = "HIDDEN"
$appId = "HIDDEN"
$appSecret = "HIDDEN"
# Partner Center API Configuration
$scope = "https://api.partnercenter.microsoft.com/.default"
$body = @{
grant_type = "client_credentials"
scope = $scope
client_id = $appId
client_secret = $appSecret
resource = "https://api.partnercenter.microsoft.com"
}
$params = @{
ContentType = "application/x-www-form-urlencoded"
Headers = @{ "Content-Type" = "application/x-www-form-urlencoded" }
Body = $body
Method = "Post"
URI = "https://login.microsoftonline.com/$tenantId/oauth2/token"
}
$response = Invoke-RestMethod @params
$token = $response.access_token
Connect-PartnerCenter -AccessToken $token
# Get all customers
$customers = Get-PartnerCustomer
$customers
However, running this gives the following error:
Get-PartnerCustomer : (invalid_grant)
At line:32 char:14
+ $customers = Get-PartnerCustomer
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-PartnerCustomer], PartnerException
+ FullyQualifiedErrorId : Microsoft.Store.PartnerCenter.PowerShell.Commands.GetPartnerCustomer
In the Azure Portal, the app is registered properly, I am sure the tenantid, appid and appsecret are correct and the following API permissions are added so that should be sufficient (and approved by admin):
The problem is probably MFA. This can also be seen by running the following script:
# Azure AD Application Configuration
$tenantId = "HIDDEN"
$appId = "HIDDEN"
$appSecret = "HIDDEN"
# Connect to Partner Center using the access token
Connect-PartnerCenter
# Get Customers
$customers = Get-PartnerCustomer
# Display Customers
$customers
In this case, chrome opens, asks for login and afterwards MFA is requested. Doing this manually works and the customers are succesfully outputted as a result.
However I would like the script to connect automatically using the API keys without needing to login manually, and this invalid_grant
error is probably caused due to the MFA.
Is there a simple way to fix this? Since it should be an easy script and I know this was possible in the past, before MFA was required, but now I just can't get it to work. Keep getting the invalid_grant error
Or is there maybe an alternative way to do this?
I created one app registration and added API permissions as below:
When I ran your script in my environment, I too got same error like this:
$tenantId = "HIDDEN"
$appId = "HIDDEN"
$appSecret = "HIDDEN"
# Partner Center API Configuration
$scope = "https://api.partnercenter.microsoft.com/.default"
$body = @{
grant_type = "client_credentials"
scope = $scope
client_id = $appId
client_secret = $appSecret
resource = "https://api.partnercenter.microsoft.com"
}
$params = @{
ContentType = "application/x-www-form-urlencoded"
Headers = @{ "Content-Type" = "application/x-www-form-urlencoded" }
Body = $body
Method = "Post"
URI = "https://login.microsoftonline.com/$tenantId/oauth2/token"
}
$response = Invoke-RestMethod @params
$token = $response.access_token
Connect-PartnerCenter -AccessToken $token
# Get all customers
$customers = Get-PartnerCustomer
$customers
Response:
In the cases where MFA is enabled, you can make use of refresh tokens that will be valid for 90 days as an alternative.
To get refresh token, you need to login with Partner Center user account manually once and can use it to generate access tokens.
I used below PowerShell script that gives refresh token in response after successful authentication.
$appId = "appId"
$appSecret = ConvertTo-SecureString -String "secret" -AsPlainText -Force
$tenantId = "tenantId"
$credential = [PSCredential]::new($appId, $appSecret)
$tokenSplat = @{
ApplicationId = $appId
Credential = $credential
Scopes = "https://api.partnercenter.microsoft.com/user_impersonation"
ServicePrincipal = $true
TenantId = $tenantId
UseAuthorizationCode = $true
}
$token = New-PartnerAccessToken @tokenSplat
$token.RefreshToken
Response:
You can now use this refresh token that is valid for 90 days and connect to Partner Center like this:
$connectSplat = @{
ApplicationId = $appId
Credential = $credential
RefreshToken = $token.RefreshToken
}
Connect-PartnerCenter @connectSplat
Get-PartnerRole
Response:
Reference: Generate Microsoft Partner Center Refresh Token – moiaune.dev by Mads Moi-Aune