I'm writing a PowerShell deployment script which automates the creation of my Azure resources and an accompanying ServicePrincipal.
Here is the code I'm using, which I've tested and works when run directly from PowerShell with the latest Azure 1.0.4 SDK module:
$ResourceGroupName = "my-resource-group"
$ADAppIdentifierUri = [string]::Concat("https://", $ResourceGroupName, ".azurewebsites.net")
# Generate a password for the AD application
$ServicePrincipalPassword = [Guid]::NewGuid().ToString().Replace("-", "")
# Create the Azure AD Application and service principal, and only assign access to our resource group
$AzureADApplication = New-AzureRmADApplication -DisplayName $ResourceGroupName -HomePage $ADAppIdentifierUri -IdentifierUris $ADAppIdentifierUri -Password $ServicePrincipalPassword
When I run this code using my ResourceGroup project deployment script in Visual Studio, I get the following error:
New-AzureRmADApplication : Unable to cast object of type 'Microsoft.Azure.TokenCloudCredentials' to type 'Microsoft.Azure.Common.Authentication.AccessTokenCredential'.
According to the stack trace the exception was raised at the start of the command New-AzureRmADApplication, so the exception is happening internally in the Azure SDK code unfortunately.
I've browsed the source code of the SDK in the following files and could not find any insight:
https://github.com/Azure/azure-powershell/blob/f803b991daa7eeeea1217238ab071c8d83de34be/src/ResourceManager/Resources/Commands.Resources/ActiveDirectory/NewAzureADApplicationCommand.cs
https://github.com/Azure/azure-powershell/blob/956d0ca795acfce67d8f142bf059ab2b8ab2c67b/src/ResourceManager/Resources/Commands.Resources/Models.ActiveDirectory/ActiveDirectoryClient.cs
https://www.symbolsource.org/Public/Metadata/NuGet/Project/Microsoft.Azure.Graph.RBAC/1.6.0-preview/Release/.NETFramework,Version%3Dv4.0/Microsoft.Azure.Graph.RBAC/Microsoft.Azure.Graph.RBAC/Generated/GraphRbacManagementClient.cs?ImageName=Microsoft.Azure.Graph.RBAC
I can only find one person who's encountered this same error at this link here:
https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/
However, the solution there does not make sense to me because I am not using a management certificate to authenticate, and I don't have any management certificates listed on the manage.windowsazure.com site.
This is an issue (i.e. bug) when using token based authentication with the AzureRMAD* cmdlets. When you run the script from VS, VS uses the token you have from the VS sign-in to avoid prompting for auth. To work around it, you have to run it outside of VS using credentials.
There is an internal work item tracking this but if you want to monitor progress you can file an issue here: https://github.com/Azure/azure-powershell/issues/
Related
I am trying to shutdown the VM using Azure Automation Account System Managed identity option.
However I am ending up with below error.
As per the other articles it is mentioned to upgrade the module Update-ModulesInAutomationToLatestVersion but I could not update due to below error. I am not sure what is the issue in the script. Same script works with AzureRunAsConnection option without issues ( script ).I even checked with simple login with System Managed Identity it successfully login and fetches the resource group names.
I have tested the above shared script in my automation account. Below are
the couple of observations:
You need to use Connect-AzureRMAccount -Identity cmdlet instead of 'connect-AzAccount` to connect to your subscription because the rest of the script that you have written using Azure RM cmdlets.
If we use AzureRM cmdlets in your run book script the job is getting suspended stating that Azure RM is going to retired and suggesting us to use Az Module in your workflow.
You can refer to this documentation on how to migrate your PowerShell scripts automatically from AzureRM to AZ modules.
If you want to perform start/stop on your virtual Machines you can leverage the Azure Automation start/stop during the off hours feature.
According to the MICROSOFT DOCUMENTATION and looking at your script the Azure Rm module is not supported and it has been updated to the latest version of Az module.
For more information please refer the below links:-
MICROSOFT DOCUMENT|Using a system-assigned managed identity for an Azure Automation account & Troubleshoot runbook issue.
I am trying to put some auto start policy on my VM on Azure.
So, I used automation account and power shell script to do this from this link: https://adamtheautomator.com/azure-vm-schedule/
But on testing it give me error of Run Login-AzureRmAccount to login
Please suggest how to fix this?
## Get the Azure Automation Acount Information
$azConn = Get-AutomationConnection -Name 'AzureRunAsConnection'
## Add the automation account context to the session
Add-AzureRMAccount -ServicePrincipal -Tenant $azConn.TenantID -ApplicationId $azConn.ApplicationId -CertificateThumbprint $azConn.CertificateThumbprint
## Get the Azure VMs with tags matching the value '10am'
$azVMs = Get-AzureRMVM | Where-Object {$_.Tags.StartTime -eq '10am'}
## Start VMs
$azVMS | Start-AzureRMVM
Regards
ESNGSRJ
This can happen when the Run As account isn't configured appropriately. You will need to create one to provide authentication for managing resources on the Azure Resource Manager using Automation runbooks.
When you create a Run As account, it performs the following tasks:
Creates an Azure AD application with a self-signed certificate, creates a service principal account for the application in Azure AD, and assigns the Contributor role for the account in your current subscription.
Creates an Automation certificate asset named AzureRunAsCertificate in the specified Automation account.
Creates an Automation connection asset named AzureRunAsConnection in the specified Automation account.
Please note the following requirements from the referenced link:
You must have an Azure Automation Account with an Azure Run As account already prepared. If you don’t have this yet, learn how to create one when you go to Create a new Automation account in the Azure portal.
The Azure PowerShell module must be installed. If you don’t have this yet, please go to the Install the Azure PowerShell module page for more information.
Note: You can configure your Runbook to use managed identities as well and it has added benefits as compared to using Run As accounts. You can get started with this tutorial to use managed identity.
As part of troubleshooting/diagnosing a permissions issue with the service principal that one of our runbooks is using, Microsoft support has asked me to run the same PowerShell code locally so we can capture logs. In order to do this, I need to authenticate exactly the same way as the runbook does, which means authenticating with the certificate that the AzureRunAsConnection is using.
After swapping out some cmdlets that only exist in Azure Automation for equivalent commands for Azure RM (e.g. Get-AutomationConnection has to be replaced with Get-AzAutomationAccount and Get-AzAutomationConnection, and you have to switch to using FieldDefinitionValues), the authentication part of my script looks like this::
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PSDefaultParameterValues['*:ErrorAction']='Stop'
'*** Authenticating with Azure'
$automationAccount = Get-AzAutomationAccount `
-Name "MY_AUTOMATION_ACCOUNT" `
-ResourceGroupName "MY_RESOURCE_GROUP"
$connection = $automationAccount | Get-AzAutomationConnection -Name "AzureRunAsConnection"
# Log-in to Az Account Management Graph API (for DNS updates)
Login-AzAccount -ServicePrincipal `
-Tenant $connection.FieldDefinitionValues.TenantID `
-ApplicationId $connection.FieldDefinitionValues.ApplicationID `
-CertificateThumbprint $connection.FieldDefinitionValues.CertificateThumbprint
When I run it, though, I get this error:
Login-AzAccount : No certificate was found in the certificate store with thumbprint
93FAB7F0BA11D08F8ABBAF5C587C77ECB058A8BB
It appears that I need to export the certificate that the AzureRunAsConnection is using so I can import it into my local machine. However, though I can renew the certificate that Azure Automation uses or upload my own, it doesn't appear that there is an easy way to get the current certificate. I know this is by design -- for security -- but for a case like this it's a pain.
I found this article from 2018 that describes how to export the cert while inside a hybrid worker, but the code didn't work for me in Azure Cloud Shell nor locally (Get-AutomationCertificate is undefined):
https://www.lunavi.com/blog/how-to-download-an-azure-automation-connection-certificate-locally
Some guides on the web suggest creating a blob storage account and then writing a script to export to it, but that seems like a lot of effort for something I just need once for this repro.
What's the fastest, easiest way to get this certificate for local debugging/repro?
In the end, I used the article from 2018 to craft a quick and dirty way to get the certificate in a consumable format out of the runbook.
I modified the script that's running in the runbook to add the following lines at the top:
"*** Exporting Run As Certificate for Debugging"
$cert = Get-AutomationCertificate -Name "AzureRunAsCertificate"
$certData = $cert.Export("pfx", 'MySuperSecurePassword')
throw ([Convert]::ToBase64String($certData))
This causes an exception that contains the contents of the certificate as its message. Then when I run this code via the runbook "Test pane", I get the contents of the certificate dumped out in base64 format at the top:
I use an exception just so that: 1) the rest of the runbook does not execute, and 2) I am guaranteed to see the message. I found that if I just did a Write-Host before throwing an exception, the output might not get flushed before the script stopped running.
I'm then able to copy the base64-encoded part that's in parenthesis, paste it into a file, and decode the contents of the file with [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String in PowerShell or base64 --decode in WSL to get a PFX file. I can then open that PFX file up and import it into my local user store:
I want to configure the authentication for my Azure function via code, be it powershell, ARM template or an API? is this possible?
i'm under the impression that an Azure Function is nothing more then an App Service so i would assume it resolve around there.
https://learn.microsoft.com/en-us/powershell/module/az.websites/?view=azps-2.0.0#app_service - there doesn't seem to be anything in the powershell.
https://resources.azure.com/ doesn't seem to give much information.
Here is some documentation on how to use managed identities for App Service and Azure Functions: https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity
You could create an PowerShell function app with MSI (Managed Service Identity) enable in a consumption plan. Here is some documentation (https://azure.microsoft.com/en-us/resources/templates/101-functions-managed-identity/) on how to do that.
Once the function app is created, you can grant it access to a given resource https://learn.microsoft.com/en-us/powershell/module/az.resources/new-azroleassignment?view=azps-2.0.0#examples
Lastly, the PowerShell function app comes with a profile.ps1 which contains code to authenticate against Azure via MSI out the box.
# Authenticate with Azure PowerShell using MSI.
# Remove this if you are not planning on using MSI or Azure PowerShell.
if ($env:MSI_SECRET -and (Get-Module -ListAvailable Az.Accounts)) {
Connect-AzAccount -Identity
}
Please give it a try and let us know if you run into any issues.
Azure Functions Authentication are still pending. Currently AFAIK there is not a way to add authentication via code except with the Function Host Keys
You can track the issue here in Github
Using terraform is a really good way of configuring these, a good example is below. Also az CLI 'az webapp auth' seems to have really good support now. PowerShell still seems to be lagging behind.
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/function_app
I have a load of Azure Powershell deployment scripts that are triggered by the build server after the completion of a build which work perfectly - I use the Import-AzurePublishSettingsFile (which is securely stored locally) to log into Azure unattended.
I now need to extend these to include management of Sql Azure Servers, Elastic Pools and Databases.
These, however, are part of the Azure Resource Manager cmdlets which have a different method of authentication.
I've found these articles:
Authenticating a Service Principal with Azure Resource Manager
Using Azure PowerShell with Azure Resource Manager
Using Windows Azure Active Directory to Authenticate the Management Libraries)
but all appear to require you to enter your credentials at some stage at the process. The second link above explicitly states:
The AzureResourceManager module requires Add-AzureAccount. A Publish Settings file is not sufficient.
I've tried (just to see what happens) switching to the Resource Manager with Switch-AzureMode -Name AzureResourceManager and then just executing one of the cmdlets, such as Get-AzureResourceGroup -Name "blah" but I just get an error of
Get-AzureResourceGroup : AuthenticationFailed: Authentication failed. The 'Authorization' header is not present or provided in an invalid format.
I am quite happy to set up an AD Application, manually, once, through the portal and then provide my scripts with the relevant Application ID or whatever is required. I just need it to be unattended so that my build can deploy!
Can anyone tell me how I go about making an unattended script to use these Azure Resource Manager cmdlets through Powershell?
This post gives full details of how to do this. Basically you embed your powershell scripts with the username and password of your AD user.
Unattended authentication to Azure Management APIs with Azure Active Directory
But be aware that if, like me, you wish to combine calls to the AzureResourceManager and AzureServiceManagement modes (using Switch-AzureMode) then you must use Add-AzureAccount -Credential <credentials> and also Remove-AzureAccount -Name <username> otherwise some of the AzureServiceManagement mode cmdlets cease to work.