The following code works great via Azure Cloud Shell (completes, App Service deleted as expected).
Remove-AzWebApp -ResourceGroupName "ResourceGroup1" -Name "AppService1" -Force
It also completes without error within my Runbook workflow, but the App Service remains operational. This feels like a permissions problem, but I've tried adding the Owner role at the subscription level without success.
Any ideas/tips for how to make this work for the AzureRunAsConnection account?
This feels like a permissions problem, but I've tried adding the Owner role at the subscription level without success.
It is not a permission problem, when you create the automation account along with the RunAsAccount, it will add the service principal related to the RunAsAccount to the subscription as a Contributor role, which is enough to remove the web app.
If you are using the PowerShell Workflow Runbook, try the sample below, it works for me. (First, make sure you have installed the Az.Accounts, Az.Websites modules in the automation account -> Modules.)
workflow testrun3
{
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
Connect-AzAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
Remove-AzWebApp -ResourceGroupName "<group-name>" -Name "joywebapp1234" -Force
}
Check the result in the portal:
To create or update a Run As account, you must have specific privileges and permissions. An Application administrator in Azure Active Directory and an Owner in a subscription can complete all the tasks. Use Remove-AzAutomationConnection to remove an Automation connection.
For more details, you could refer to this article about Run As account permissions.
Related
I am trying to make a code using PowerShell so that secrets are not hardcoded on my runbook so that it will not be exposed in the script. I created encrypted variables in my automation account. These variables are AppID, AppSecret and TenantID.
This is the part of the script to login automatically to Azure. I didn't use managed identity for some compatibility reasons with the script.
My script is running fine when secrets and IDs are hardcoded but when I created variables it is not working. Error message is "Run Connect-AzAccount". Below is my code. Need help on how to correct this. Thank you in advance.
$AzVariableApplicationID = 'AppID'
$AzVariableAppSecret = 'AppSecret'
$AzVariableTenantID = 'TenantID'
$AppID = Get-AzAutomationVariable -Name $AzVariableApplicationID
$AppSecret = Get-AzAutomationVariable -Name $AzVariableAppSecret
$TenantID = Get-AzAutomationVariable -Name $AzVariableTenantID
$SecureSecret = $AppSecret | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList $AppID, $SecureSecret
Connect-AzAccount -ServicePrincipal -Credential $Credential -Tenant $TenantID
As described in PsCustom Object - Hitchikers GUID(e) to Automation
, It is not possible to retrieve values for encrypted variables as they’re available within the runbook at runtime via the Get-AutomationVariable cmdlet
I found an alternative approach to "Connect Azure" by using "Certificate-based authentication" inside PowerShell runbook without hardcoding the values:
Created a new Service principal and provided the "Owner" role access to avoid any restrictions.
To authenticate via service principal, I create a new self-signed certificate with the command:
$cert=New-SelfSignedCertificate -Subject "CN=xxxxxCert" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature
Upload a certificate under Certifications & Secrets:
Click windows + R to open the run box and give certmgr.msc as shown here.
Export a certificate without private key.
Upload a certificate in the below path:
AzureAD -> App registrations -> Serviceprincipal
Now, I have exported the same certificate with key and uploaded inside my automation account to authenticate Service principal connection:
Added an "Azure Service Principal" connection inside automation accounts by providing "ApplicationID, TenantID, Certificate Thumbprint" of my Service principal as shown:
Inside PowerShell runbook, I ran the below script that works for me:
$connectionName = "serviceprincipalname"
try
{
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRMAccount
-ServicePrincipal `
-TenantID $servicePrincipalConnection.TenantID `
-ApplicationID $servicePrincipalConnection.applicationID `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found. "
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
Logged in to Azure:
Register an App in App registrations and create a service principal in AzureAD
Unable to assign role to user using New-AzureRmRoleAssignment command. When I run the above command its thronging an error as follows .
New-AzureRmRoleAssignment : Object reference not set to an instance of an object.
Can any one help to resole the issue.
To assign role to user successfully in the runbook, follow the steps below.
Note : The New-AzureRmRoleAssignment you used belongs to the old AzureRM, it was deprecated and will not be updated anymore. In my sample, I use the new Az command New-AzRoleAssignment, I also recommend you to use it.
1.Navigate to the subscription in the portal(you need to be Owner/User Access Administrator in the subscription) -> add the service principal of your automation RunAs account as an Owner/User Access Administrator(by default it will be added as Contributor when it was created, but Contributor have no permission to run New-AzRoleAssignment).
2.Navigate to the Azure Active Directory in the portal -> App registrations -> find the AD App of your RunAs Account and add the Directory.Read.All application permission in Azure Active Directory Graph(Not Microsoft Graph) like below, don't forget to click the Grant admin consent for xxx button at last(you need to be the admin role in your AAD tenant). The permission may take about 30 min to take effect.
3.Navigate to the automation account in the portal -> Modules -> make sure you have installed the Az.Accounts, Az.Resources modules, if not, go to Browse Gallery, search for the names, and install them.
4.Then in the runbook, use the script below, it works fine on my side. In my sample, I add the user as a Reader in the resource group joyRG, you can change it, it depends on your requirement.
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Connect-AzAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
$user = Get-AzADUser -UserPrincipalName joyw2#xxxx.onmicrosoft.com
New-AzRoleAssignment -ObjectId $user.id -ResourceGroupName joyRG -RoleDefinitionName Reader
I am trying to create a Runbook which does some maintenance in Active Directory. On creation of an Automation Account an "RunAs" account was created. In the runbook I connect to AD using the below command.
$connectionName = "AzureRunAsConnection"
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to AzureAD..."
Connect-AzureAD `
-TenantId $servicePrincipalConnection.TenantId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-LogLevel Info
This command runs fine, however the subsequent use of AD CMDLETS gives the following error,
$Users = Get-AzureADUser
Get-AzureADUser : Error occurred while executing GetUsers Code: Authorization_RequestDenied Message: Insufficient privileges to complete the operation.
HttpStatusCode: Forbidden
HttpStatusDescription: Forbidden
HttpResponseStatus: Completed
The same is true for other CMDLETS in the AD module, not just this I have tried adding API permission through the registered application (relating to the Automation Account connection resource) in Active Directory but I am still facing the above privileges issue.
According to some test, you need to add the permissions of Azure AD but not Micorsoft Graph. It seems the Get-AzureADUser command use Azure AD graph in the backend. So we need to do the operations as below:
After that we can use the command Get-AzureADUser successfully(if you test the command in powershell, when you add the Azure AD permission, please close the powershell and reopen it and re-connect)
Simply, I'm running Connect-AzureRmAccount using runbook automation in Azure, it gives me the error below:
Unable to find an entry point named 'GetPerAdapterInfo' in DLL
'iphlpapi.dll'.
I already imported the Azureprofile module and I can not figure out what is the issue.
If you want to connect to the Azure account with the PowerShell command Connect-AzureRmAccount in your Runbook, then it is really unnecessary. Just as I said in the comment, when you use the Runbook, you are already in an exact subscription of the tenant with an account. So just run your script without connecting the account.
If you really want to connect with the PowerShell, you can use the service principal like this:
Disable-AzureRmContextAutosave –Scope Process
$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Connect-AzureRmAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationID $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint
But I really suggest you can just run the PowerShell script in your Runbook directly.
Update
When you create the Runbook, there will be a connection for you to run the PowerShell script. Or you can create the connection as your requirement. See Connection assets in Azure Automation. You could just use the default connection use the code like this:
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
I had the same problem, in my case I was trying to simply use the Azure Cmdlet Get-AzVm.
I previously used code similar to what Charles posted above, the problem is that doesn't work with the Az Cmdlets as you can't use both the AzureRM and the new Azure modules at the same time.
I replaced all of that with the following and now it works:
Disable-AzContextAutosave –Scope Process
$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Connect-AzAccount -ServicePrincipal -Tenant $Conn.TenantID `
-ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint
$AzureContext = Select-AzSubscription -SubscriptionId $Conn.SubscriptionID
I found this in the following article: https://learn.microsoft.com/en-us/azure/automation/automation-first-runbook-textual
I'd like to use a powershell script in Azure automation to schedule switching on/off resources.
I'd like to do this without creating an account as our domain enforces password resets. I know that the automation account creates a certificate - is it possible to authenticate with this instead, when using the resource manager (AKA not a "classic" account).
Yes, this is a valid approach, in fact if you create an Azure Automation account and use the defaults it will create that for you and you can use that transparently. Taken from example runbook:
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
$null = Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
dozen edits because my brain stopped working