Powershell Script to download Azure recommendations - azure

Login-AzAccount
$subs= az account list --query '[*].id'
Get-AzAdvisorRecommendation list --subscription $subs
I need to download the list of Azure recommendations on a tenant which will be having multiple subscriptions using Powershell script

Get-AzAdvisorRecommendation list --subscription $subs
Instead of --subscription you need to pass -subscription as a parameter to Get-AzAdvisorRecommendation cmdlet.
As per the Azure PowerShell cmdlet documentation, The Cmdlet Get-AzAdvisorRecommendation doesnt have any flag -subscription as parameter.
You can use this below script to pull the azure advisor recommendations for all subscriptions under a particular tenant.
$list=#()
$sub=get-azsubscription
Write-Output $sub
foreach( $item in $sub){
Set-AzContext -Subscription $item.Id -Tenant $item.TenantId -Force
$rg=Get-AzResourceGroup
foreach($r in $rg){
$list+=Get-AzAdvisorRecommendation -ResourceGroupName $r.ResourceGroupName
}
}
$list | Export-Csv C:\Users\list.csv
Here is the sample output for reference:
While testing the above script in our local environment, we have passed a single subscription to the cmdlet Get-azsubscription using the -subscriptionId flag.

Using this updated script, I can download the recommendations as well, thanks Venkatesh for your inputs.
Login-AzAccount
$result= 'C:\Users\new.csv'
$list=#()
$subs=get-AzSubscription
foreach( $sub in $subs){
Set-AzContext -Subscription $sub.Id -Force
$list+=Get-AzAdvisorRecommendation | Select-Object category, Impact, #{Name="SubscriptionName"; Expression={$sub.name}}, #{Name="SubscriptionID";
Expression={$sub.Id}}, #{Name="Recommendation"; Expression=$_.ShortDescription.Problem}}, ImpactedField, ImpactedValue,RecommendationTypeId, LastUpdated, MetaData, SuppressionId, Name,
resourceid
}
$list | Export-Csv $result -NoTypeInformation

Related

Get-AzSubscription won't show my subscription

I have a subscription I want to pause/resume with a PowerShell script (Azure Analysis Services). I use this exact same script to pause my Embedded Capacity and that works fine, but when I run my script for my new subscription it wont work. This is the script I use:
$userPassword = "myappsecret"
$userPassword2 = ConvertTo-SecureString -String $userPassword -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "appid", $userPassword2
Connect-AzAccount -ServicePrincipal -TenantId "tenantid" -Credential $Credential
Select-AzSubscription -SubscriptionId "subscriptionname here"
Get-AzPowerBIEmbeddedCapacity -ResourceGroupName "groupnamehere" -Name "namehere"
Suspend-AzPowerBIEmbeddedCapacity -Name "namehere" -ResourceGroupName "groupnamehere" -PassThru
To check why this won't work I tried to simply use Get-AzSubscription to see if something was wrong and it wont show any subscription.
If I try the same for my Embedded Capacity it works just fine.
What could be wrong?
To get the list of all Azure Ad subscriptions by using Get-AzSubscription, make sure that you have owner/admin role.
You can make use of the below command to get Azure Ad subscriptions for a specific tenant:
Make sure to connect-azaccount with Administrator details.
Get-AzSubscription -TenantId "your_tenant_id"
Get-AzContext command list the information of the Azure Subscription that is currently selected.
To use a specific subscription, you can make use of below command:
Get-AzSubscription -SubscriptionId "xxxx-xxxx-xxxx-xxxx" -TenantId "yyyy-yyyy-yyyy-yyyy" | Set-AzContext
Or please modify your code by adding the below snippet:
$subscriptionId = 'Your_Subscription_ID';
Select-AzSubscription -SubscriptionId $subscriptionId
You can check the Subscription Id via Azure Portal too.
Reference:
Get-AzSubscription (Az.Accounts) | Microsoft Docs

How to run Powershell script on multiple Subscriptions Using Az PowerShell Command

I have multiple azure tenants, each having multiple subscriptions, and I have to run a single PowerShell script for all my subscriptions.
This can be achieved using Azure CLI, and it works perfectly.
I use Azure CLI as below;
$az_account = (az account list --query "[].[name]" -o tsv)
foreach ($account in $az_account) {
az account set --name $account
#<RUN SCRIPTS HERE>#
}
But in some situations, I have to use the Az PowerShell command instead of Azure CLI.
So could anyone help me
How to run Az PowerShell commands for multiple subscriptions
Or the Az PowerShell profile file path ( same as Azure CLI which is C:\Users\%USER\.Azure\azureProfile.json ).
How to run Az PowerShell commands for multiple subscriptions
You can use the below PowerShell Scripts to run the multiple subscription PowerShell commands.
# Get the Subscription Details using Get-AzSubscription Command
Get-AzSubscription | ForEach-Object {
# Set the context Details using Set-AzContext Command which is equalent to the az account set CLI Command
$_ | Set-AzContext
$subscriptionName = $_.Name
#<RUN YOUR SCRIPTS HERE>#
}
Or the Az PowerShell profile file path ( same as Azure CLI which is C:\Users\%USER\.Azure\azureProfile.json ).
Refer here for profile file path location
Resolution
After a couple of tries, finally found some methods to solve my issue. posting the same here might be helpful for someone.
You can connect all the subscriptions using the below commands
Connect-AzAccount -Tenant "xxxx-xxxxx-xxxx-xxx" -Subscription "xxxx-xxxxx-xxxx-xxx"
To List all the connected subscriptions
Get-AzContext -ListAvailable | Select-Object Name, Subscription, Tenant
If you want to rename to a friendly Name,
Rename-AzContext -SourceName "Azure subscription 1 (xxxxx-xxxx-xxxx-xxxx-xxxx) - xxxxx-xxxx-xxx-xxxx-xxxx-xxx - jawad#xyz.com" -TargetName "MySubscription"
To save these profiles to file,
Save-AzContext -Path "C:\Users\jawad\Downloads\AzpwshProfile.json"
You can import any time these profiles using the below command, (test first clear the profile Clear-AzContext -Force)
Import-AzContext -Path "C:\Users\jawad\Downloads\AzpwshProfile.json"
Now you easily use for loop to set the subscriptions, for example
$acc = (Get-AzContext -ListAvailable | Select-Object Name)
foreach ($account in $acc) {
>> Select-AzContext $account.Name
>> Get-AzVM | Export-Csv -Path "inventory.csv"
>> }
Thank you

New automation variable by cli or ansible

After create a runbook and edit content, I want to create variable and set value for them. How can I do it by ansible or azure cli ?
Please help me
Azure Automation stores each encrypted variable securely. When you create a variable, you can specify its encryption and storage by Azure Automation as a secure asset.
You must set the value with the Set-AzAutomationVariable cmdlet or the internal Set-AutomationVariable cmdlet. You use the Set-AutomationVariable in your runbooks that are intended to run in the Azure sandbox environment, or on a Windows Hybrid Runbook Worker.
You can create variables and set value for them using PowerShell script.
$rgName = "ResourceGroup01"
$accountName = "MyAutomationAccount"
$vm = Get-AzVM -ResourceGroupName "ResourceGroup01" -Name "VM01" | Select Name, Location,Extensions
New-AzAutomationVariable -ResourceGroupName "ResourceGroup01" -AutomationAccountName "MyAutomationAccount" -Name "MyComplexVariable" -Encrypted $false -Value $vm
$vmValue = Get-AzAutomationVariable -ResourceGroupName "ResourceGroup01" -AutomationAccountName "MyAutomationAccount" -Name "MyComplexVariable"
$vmName = $vmValue.Value.Name
$vmTags = $vmValue.Value.Tags
Reference: Manage variables in Azure Automation | Microsoft Docs

Azure-automation: Cannot bind parameter 'Context'

I am trying to create new directories in Azure datalake using azure automation powershell workflow.
The code that i have is like this:
$ctx = New-AzStorageContext -ConnectionString $connectionstring
New-AzDataLakeGen2Item -Context $ctx -FileSystem $filesystemName -Path $dirname -Directory
the error message that I get:
New-AzDataLakeGen2Item : Cannot bind parameter 'Context'. Cannot convert the "Microsoft.WindowsAzure.Commands.Storage.AzureStorageContext" value of type "Deserialized.Microsoft.WindowsAzure.Commands.Storage.AzureStorageContext" to type "Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext
I dont know how to solve this error? any help is greatly appreciated.
In our local environment, We have created a Powershell runbook running with PowerShell Version 5.1.
Using the same above shared cmdlets, we are able to create a new directory in the Azure Data lake storage account. We have used System managed identity to connect to subscription resources from the automation account.
Here is the Powershell script that we have used in Automation Account:
Disable-AzContextAutosave -Scope Process # Ensures you do not inherit an AzContext in your runbook
$AzureContext = (Connect-AzAccount -Identity).context # Connect to Azure with system-assigned managed identity
$AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext # set and store context
Import-module -name Az.Storage
$ctx=New-AzStorageContext -StorageAccountName "<strgaccountName>" -StorageAccountKey "<storageaccountKey>"
New-AzDataLakeGen2Item -Context $ctx -FileSystem "testfiler" -Path "dir1/dir2" -Directory
Here is the Sample output for reference:

Install extension on both Classic and ARM VMs with single PowerShell command

I have a script that installs OMS extensions to all ARM VMs in the subscription. The problem is that I have subscriptions that contain only ARM VMs, subscriptions that contain only Classic VMs, and subscription that have both types of VMs. How can I modify the script to work in all of the conditions? The script is:
#This script installs OMS Monitoring Agent to all VMs in the selected Subscription.
#Before running this script, the user must login to Azure account and select target subscription.
#Example:
#Login-AzureRmAccount
#Select-AzureRmSubscription 'SubscriptionName'
$WorkspaceID = 'Provide Workspace ID here'
$WorkspaceKey = 'Provide Workspace key here'
$VMs = Get-AzureRmVM
$VMs.where({$_.osprofile.windowsconfiguration}) | ForEach-Object {
"Installing Microsoft.EnterpriseCloud.Monitoring.MicrosoftMonitoringAgent Extension: {0}" -f $_.id
Set-AzureRmVMExtension -ResourceGroupName $_.ResourceGroupName -VMName $_.Name -Name omsAgent -Publisher 'Microsoft.EnterpriseCloud.Monitoring' `
-ExtensionType 'MicrosoftMonitoringAgent' -AsJob -TypeHandlerVersion '1.0' -Location $_.Location -ForceRerun 'yesh' `
-SettingString ( "{'workspaceId': '$WorkspaceID'}") `
-ProtectedSettingString "{'workspaceKey': '$WorkspaceKey'}" |
Add-Member -Name VM -Value $_.Id -MemberType NoteProperty
}
Since you got both classic and ARM VMs, you got two different deployment models, hence two different PowerShell modules you are using.
In other words, you need to log in separately for each and have separate scripts for using them.
In the classic model you need to run the following cmdlet to login and access your VMs:
Add-AzureAccount
Get-AzureVM | Set-AzureVMExtension ``
-Publisher 'Microsoft.EnterpriseCloud.Monitoring' ``
-ExtensionName 'MicrosoftMonitoringAgent' ``
-Version '1.*' ``
-PublicConfiguration "<workspace id>" ``
-PrivateConfiguration "<workspace key>" ``
While searching for information I found this script. It's a script for on-boarding VMs from single, or multiple subscriptions, using both deployment models.

Resources