Azure automation with cosmosDB - azure

Trying to perform some updates to CosmosDB with the Azure automation run books. I have made a RunAs service principal Account to authenticate with Azure
Updating the Modules used for the Get-AzureRmResource appear to cause some issues where I can no longer retrieve the CosmosDB object.
$Conn = Get-AutomationConnection -Name "AzureRunAsConnection"
Add-AzureRmAccount -ServicePrincipal -Tenant $Conn.TenantID `
-ApplicationID $Conn.ApplicationID -CertificateThumbprint
$Conn.CertificateThumbprint
Select-AzureRmSubscription -SubscriptionName "Visual Studio Enterprise" -ErrorAction SilentlyContinue
#resource and app variables declared here.
$cosmosDbResource = (Get-AzureRmResource -ResourceType
"Microsoft.DocumentDb/DatabaseAccounts" -ResourceGroup $applicationGroup -
ApiVersion "2015-04-08" -Name $cosmosDBName)
"Before CosmosDB Resource"
$cosmosDbResource | FT
"Cosmos DB Properties"
$cosmosDbResource.Properties
This code works just fine on the plain deployment of automation accounts with the module. AzureRM.Resources at 1.0.3.
If I try and update the AzureRM.Resource and its dependencies to 6.1.0 I can no longer retrieve my CosmosDB instance.
I think that there may be a conflict with the powershell modules with the update

Depending on what you wish to update within cosmosdb.....
The official cosmosdb powershell modules are pretty laking at the moment, take a look at the community cosmosdb powershell module it is far more feature rich and easier to work with:
https://github.com/PlagueHO/CosmosDB

Related

Powershell AzureAD module returns different objects when running from Azure compared to locally

I have an Azure Automation Hybrid Worker setup. When I run a simple
Get-AzureADUser -SearchString "user#domain"
through the Powershell console on the Hybrid Worker VM I get the proper user object as a response.
But when I run the exact same statement from an Azure Automation runbook on the same Hybrid Worker null is returned.
It's driving me crazy to debug this inconsistency, I'm using the same account to authenticate against Azure.
Can you make sure that the Azure Run as account is setup and the required certificate in PFX is installed on the Hybrid Worker. And also can you trying having only the user name in the searchstring.
Within the runbook you can use the below snippet to connect to AzureAD and then call Get-AzureADUser
$connectionName = "AzureRunAsConnection"
$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
"Logging into Azure AD....."
Connect-AzureAD -TenantID $servicePrincipalConnection.TenantID -ApplicationId $servicePrincipalConnection.ApplicationId -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
Get-AzureADUser -SearchString "membername"
Below pane should help you test the run book and show the status of the runbook or any errors you might see.
Additional documentation reference to create Azure Automation Run As Account.
Hope this helps.

Azure storage account key updation using RM module

I am trying to setup a powershell code which would update the storage account credentials every once in a while and below is the script that I have come across and it works perfectly fine.
function setupContext(){
Add-AzureRmAccount
Save-AzureRmContext -Path “path\to\json\file”
}
#setupContext
Import-AzureRmContext -Path “path\to\json\file”
$subscriptionId='***********************************'
Select-AzureRMSubscription -SubscriptionId $subscriptionId -WarningAction SilentlyContinue
$resourceGroup="**************"
$storageAccountName="******************"
$BLOBKey= New-AzureRmStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageAccountName -KeyName key2
Write-Host "BLOB Key:"$BLOBKey.Keys[0]
The above code does the required work, however it requires us to login to the azure-rm account which basically defeats the idea of automating this process since I would need keep updating this generated profile.
Note: I am not allowed to use az module as of now since the environment in which I work has some .NET version limitations.
So if there any other solution which could overcome the azure rm login issue, please suggest.
Use Azure Automation. This automatically sets up something called RunAs account. Which simply said is just Azure AD Service Principal.
Then assign this principal privileges on the storage account just like any other user and you are done.
And in the Automation Runbook do
$connection = Get-AutomationConnection -Name AzureRunAsConnection
Connect-AzureRmAccount `
-ServicePrincipal `
-Tenant $connection.TenantID `
-ApplicationID $connection.ApplicationID `
-CertificateThumbprint $connection.CertificateThumbprint
$AzureContext = Select-AzureRmSubscription -SubscriptionId $connection.SubscriptionID
... run rest of the code ...
If you want to run this from outside of Azure like on-prem server then set up manually service principal. Here is guide
https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal
And just log into this app from powershell instead of the user.
Looks you want to use a non-interactive way to do that automatically. To access the azure resource with a non-interactive way, your best option currently is to use the service principal(AD App).
An Azure service principal is an identity created for use with applications, hosted services, and automated tools to access Azure resources.
The other reply is for azure automation runbook, you could follow my steps to automate it in other places else.
1.Create an Azure Active Directory application and create a secret for the app, save the secret and get values for signing in.
2.Navigate to the storage account(or the subscription which the storage account located) in the portal -> Access control (IAM) -> Add -> Add role assignment -> search your service principal(AD App) with name and add it as a role(e.g. Owner/Contributor) -> Save.
Note: To give the role, you need to use an account which is an Owner of the specific scope(storage account/subscription).
3.Then use the script as below, replace the specific properties with the values in step 1.
function setupContext(){
$azureAplicationId ="<application id>"
$azureTenantId= "<tenant id>"
$azurePassword = ConvertTo-SecureString "<client secret>" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Add-AzureRmAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
Save-AzureRmContext -Path “path\to\json\file”
}
#setupContext
Import-AzureRmContext -Path “path\to\json\file”
$subscriptionId='***********************************'
Select-AzureRMSubscription -SubscriptionId $subscriptionId -WarningAction SilentlyContinue
$resourceGroup="**************"
$storageAccountName="******************"
$BLOBKey= New-AzureRmStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageAccountName -KeyName key2
Write-Host "BLOB Key:"$BLOBKey.Keys[0]
Besides, if you want to learn more about the service principal, you could take a look at this link - Application and service principal objects in Azure Active Directory

Set-AzContext works in Azure Cloud Shell but doesn't in Azure PowerShell

When i execute following command
Clear-AzureProfile
Connect-AzAccount -TenantID xxxxxxxxxxxxxxxxxxx
Set-AzContext -SubscriptionId xxxxxxxxxxxxxxxxxxx
in Azure PowerShell i get this error.
Set-AzContext : Please provide a valid tenant or a valid subscription.
At line:6 char:1
+ Set-AzContext -SubscriptionId xxxxxxxxxxxxxxxxxxx
and if i run the same command in Azure Cloud Shell it works
Name Account SubscriptionName Environment TenantId
xxxx xxxxxxx xxxx xxxx xxxx
I switched from free-trial to pay-as-you-go subscription and using credentials for pay-as-you-go in both environment but it doesn't work. can anyone help
Close your powershell and open a new one, or use Clear-AzContext, not Clear-AzureProfile. Then use Connect-AzAccount -Tenant xxxxx -Subscription xxxxx, it should work.
If you are cycling through subscriptions in the same tenant and don't want to have to sign in with Connect-AzAccount multiple times, the following worked for me to switch between subscriptions:
Remove-AzContext -InputObject (Get-AzContext) -Force | Out-Null;
$sub = Set-AzContext -Subscription $_.SubscriptionName;
Before adding the Remove-AzContext statement I was seeing that Set-AzContext was not actually switching the context to another subscription for some reason.
I used to have this problem too, and my solution was different that one provided on top of this.
Apparently, in our Azure Cloud Shell, we have several contexts available, so, we don't have to set the context (using Set-AzContext), but to switch to one or other context, using Select-AzContext)
I can list the contexts using
Get-AzContext -ListAvailable
Then choose one using the
Select-AzContext -Name ...
For-example, in scripts, I use this one-line command to switch to the subscription having ID $SubscriptionID :
Select-AzContext -name ((Get-AzContext -ListAvailable).Name -match $SubscriptionId)[0]
Not elegant, but efficient
I don't know why we are in such situation. Maybe because we are administrating using invited accounts from another tenant.
Hope this help someone in same situation than us.

Azure Logic Apps: how to run Powershell script or Azure CLI?

I'm building my Azure Logic Apps worklow which is supposed to check some conditions and run following Powershell:
Stop-AzureWebsiteJob -Name MyWebsite -JobName MyWebJob
Start-AzureWebsiteJob -Name MyWebsite -JobName MyWebJob -JobType Continuous
The question is: what's the easiest way to invoke such script in Azure Logic Apps? It seems like there's no built in block/connector for Powershell so I'd like to know what are the possibilites. Or perhaps it might be easier to run az CLI command with similar operation
Finally I ended up with a solution which takes advantage of Azure Automation. From Azure Portal we can create new Resource typing in Automation:
Once the resource is created we can add new Runbook under runbooks tab:
Runbook can run Powershell Workflow and get authorized using AzureRunAsConnection option (details here). My sample Powershell which is supposed to restart WebJob an specific App Service looks like below:
Workflow RestartMyWebJob
{
$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint
$AzureContext = Select-AzureRmSubscription -SubscriptionId $Conn.SubscriptionID
$Apiversion = "2015-08-01"
$ResourceGroupName = 'My-Resource-Group-Name'
$ResourceName = 'My-Resource-Group-Name/My-AppService--WebJob-Name'
Invoke-AzureRmResourceAction -ResourceGroupName $ResourceGroupName -ResourceType Microsoft.Web/sites/ContinuousWebJobs -ResourceName $ResourceName -Action stop -ApiVersion $Apiversion -Force
Invoke-AzureRmResourceAction -ResourceGroupName $ResourceGroupName -ResourceType Microsoft.Web/sites/ContinuousWebJobs -ResourceName $ResourceName -Action start -ApiVersion $Apiversion -Force
}
Having this Workflow setup we can run it from Azure Logic Apps by adding new block to our logic.
Currently, azure logic seems not support to run powershell and cli script, here is a voice in azure feedback, you could vote it.
Workaround:
If you want to start and stop the webjob, you can call the Kudu WebJobs API in the logic app.
You can follow the steps below.
1.Run the powershell command locally to generate the Authorization token of your web app.
$creds = Invoke-AzureRmResourceAction -ResourceGroupName joywebapp -ResourceType Microsoft.Web/sites/config -ResourceName joywebapp2/publishingcredentials -Action list -ApiVersion 2015-08-01 -Force
$username = $creds.Properties.PublishingUserName
$password = $creds.Properties.PublishingPassword
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $password)))
The $base64AuthInfo is what we need, it should be like JGpveXdlYmFwcDI6NnJxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxzRktSdXlUcU5acUUzdFhNb05j.
The token will never be changed except you reset the publish profile, so you just need to do this step once.
2.In the logic app, specific the Method, URI, Headers(The header should be like
Authorization: Basic JGpveXdlYmFwcDI6NnJxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxzRktSdXlUcU5acUUzdFhNb05j, note use space to separate the Basic and token), for example , I start a triggered webjob in my web app.
Triggered result:
So you just need to follow the steps above, for your issue, refer to the APIS:
Start a continuous job
Stop a continuous job
Create an Azure Function with an http trigger with Powershell as the function language (or any other supported language). Then you call the Function easily in the Logic app by calling an Http endpoint.
actually nowdays Azure provide this option, without creating runbooks and automation accounts. It is still in preview mode, but seems to be working !
You can also have your PowerShell code run in an Azure Container Instance supporting PowerShell and create an new Container Group from the Logic App workflow.

How to query entities from Azure Storage Table with AzureRM?

I have a couple of Azure Runbooks which use AzureRM to automatically scale service plans depending in some configuration.
That configuration is saved on my Azure Storage Account as entities in a table.
However, I can't find a way to read the entities from that table using AzureRM in my runbooks...
I can't use any Az modules because it would complain about also importing AzureRM next to Az. And I don't want to have 2 separate automation accounts just to be able to use AzureRM and Az at the same time.
So is there any way to get all the entities from an Azure Storage Table using the AzureRM module?
According to my test, if you want to use AzureRm module to get all the entities from an Azure Storage Table, you can use the modlue AzureRmStorageTable. But please note that its version only lows than 1.0.0.23. For more details, please refer to https://github.com/paulomarquesc/AzureRmStorageTable/blob/master/ReleaseNotes.md.
For example:
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
}
}
$table = Get-AzureStorageTableTable -resourceGroup jimtest -tableName SchemasTable -storageAccountName jimtestdiag417
Get-AzureStorageTableRowAll -table $table
Update
Regarding how to install the special version module for Azure Automation account, you can do that via the page.
Thank to the comment of Michale B. on my question, the following has fixed my problem:
Could also make use of the alias option in the Az module. learn.microsoft.com/en-us/powershell/module/az.accounts/… . This will allow you to use (most) AzureRM functions, while also using the Az module

Resources