0

I am required to write a PowerShell script, which can connect to my company's Azure account, check and create Azure resources (eg. Service Bus namespace, Service Bus topic, and Service Bus subscriptions). Everything worked well until I tried to deploy my script as a step in my project's on-premise TeamCity. I keep getting this error message

Exception calling "ShouldContinue" with "2" argument(s): "Windows PowerShell is in NonInteractive mode. Read and Prompt functionality is not available."

I investigated and found out that the problem is in this line

Connect-AzAccount

If I run the script manually, it will pop up a prompt asking me to login to Azure. I believe that's what went wrong. Because my project's on-premise TeamCity does not seem have an option to open a prompt for PowerShell command. I have read some workarounds, even on this website, but none of them is applicable to my case. Even a solution like https://stackoverflow.com/a/61099568/8213536 gave me these errors

WARNING: Unable to acquire token for tenant 'organizations' with error 'UsernamePasswordCredential authentication failed: There was an error parsing WS-Trust response from the endpoint. This may occur if there is an issue with your ADFS configuration. See https://aka.ms/msal-net-iwa-troubleshooting for more details. Error Message: Object reference not set to an instance of an object. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/usernamepasswordcredential/troubleshoot' Connect-AzAccount : UsernamePasswordCredential authentication failed: There was an error parsing WS-Trust response from the endpoint. This may occur if there is an issue with your ADFS configuration. See https://aka.ms/msal-net-iwa-troubleshooting for more details. Error Message: Object reference not set to an instance of an object. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/usernamepasswordcredential/troubleshoot At line:1 char:1

  • Connect-AzAccount -Credential $creds
  •   + CategoryInfo          : CloseError: (:) [Connect-AzAccount], AuthenticationFailedException
      + FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand
    

One of the other solutions https://stackoverflow.com/a/52014189/8213536 requires an application's principal id, which is not applicable for my scenario either, as I am not creating a new application. I just need to be able to automatically connect to Azure (without prompt), check and create SB Namespace, SB Topic and SB Subscription.

Could someone please help me on this? Thanks.

Jesse Squire
  • 6,107
  • 1
  • 27
  • 30
Anthony
  • 1,882
  • 2
  • 9
  • 18
  • That link https://stackoverflow.com/a/52014189/8213536 refers to a service principal. That is definitely the correct way. It's not just for creating a new application. Other platforms like Azure DevOps have this capability built in. – Nick.Mc Oct 12 '22 at 03:56
  • Instructions for service principals are quite confusing and make it look like you are creating an application, but you aren't you're just creating a service principal and all the plumbing that goes with it – Nick.Mc Oct 12 '22 at 03:58
  • @Nick.McDermaid ok I've tried with the instructions in the link but when I attempted to access resources (after I connected using my newly created principal), I got "Get-AzServiceBusNamespace : 'this.Client.SubscriptionId' cannot be null.". Do you know how to add a service principal into an Azure subscription? – Anthony Oct 12 '22 at 05:45
  • Does this help https://github.com/Azure/azure-powershell/issues/13560? – Rukmini Oct 12 '22 at 06:07
  • @Rukmini I've tried with eric wang's suggestion but the problem is still there. Besides, I need a way to not show the authentication prompt, because there is no "interactive" option for PowerShell on the on-premise TeamCity. I've tried with New Registration suggestion and still got the error message "Get-AzServiceBusNamespace : 'this.Client.SubscriptionId' cannot be null.". The account's subscription is still null. I don't know how to add it into my company's Azure subscription. – Anthony Oct 12 '22 at 06:41
  • 1
    If your authentication is successful with Connect-Azaccount, then you have to set context as follows: ```Set-AzContext -Subscription Subscription1``` For more info please refer https://learn.microsoft.com/en-us/powershell/module/az.accounts/connect-azaccount?view=azps-8.3.0#examples – Dilly B Oct 12 '22 at 06:45
  • @DillyB I keep getting the error "Set-AzContext : Please provide a valid tenant or a valid subscription." despite I've tried with the subscription id and the subscription name. – Anthony Oct 12 '22 at 08:14
  • @Rukmini I'm not able to login using the approach above. I kept getting the error "Connect-AzAccount : UsernamePasswordCredential authentication failed: Unsupported User Type 'Unknown'. Please see https://aka.ms/msal-net-up.". The only authentication approach that worked for me is https://stackoverflow.com/a/52014189/8213536 but I cannot add the principal into the subscription. I've figured out that this may need my cloud admin to grant me some extra permissions on the subscription. I'll check with him tomorrow. I'm not sure if my script will work after this. – Anthony Oct 12 '22 at 08:14
  • Yes that is every developers problem... insufficient rights to set up security principals. Your cloud Admin should understand service principals. – Nick.Mc Oct 12 '22 at 10:31
  • BTW, there are many was to create Azure resources via code. This is often achieved using ARM templates, but there are many other options. – Nick.Mc Oct 12 '22 at 10:36
  • 1
    ok with the permissions set by my cloud admin, I am able to get my script working with my dedicated principal. Thank you all for your help. – Anthony Oct 13 '22 at 07:02
  • 1
    If you could write it up as an answer it would probably be quite valuable to others. – Nick.Mc Oct 13 '22 at 13:13
  • Oh ok thanks for reminding me. I'll summarise what I did and post as an answer. Sorry I got carried away with lots of things at work recently. – Anthony Oct 16 '22 at 17:12

1 Answers1

0

As promised, I would like to post my solution. First I created a service principal with a client secret key. Then I asked my company's cloud engineer to assign it to the Azure subscription of my company and to the resource group that I intended to group all my necessary resources into. Finally in my code, I implemented something similar to https://stackoverflow.com/a/61099568/8213536

$applicationId = $azServicePrincipalId
Write-Host "Connecting to Azure using principal $applicationId"
$securePassword = $azServicePrincipalPw | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $applicationId, $securePassword
Connect-AzAccount -ServicePrincipal -TenantId $azureTenantId -Credential $credential

$azServicePrincipalId and $azServicePrincipalPw came from the Service Principal itself, while $azureTenantId came from my company's Azure subscription.

It is now working as expected.

Anthony
  • 1,882
  • 2
  • 9
  • 18