В облачном сервисе Microsoft Azure есть специальный сервис для анализа использования виртуальных машин, который показывает, мощности каких машины не соответствуют выставленным параметрам серверов, расходы на которые можно уменьшить, снизив параметры серверов - Azure Advisor, раздел Cost. Через PowerShell-скрипт можно запросить необходимую информацию, чтобы потом использовать ее в своих проектах автоматизации облачной инфраструктуры.
# ------------------------------------------------------------------------------------------------
# Defining variables
# ------------------------------------------------------------------------------------------------
# Functions
Function Write-ScriptLog {
Param(
[CmdletBinding()]
[Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[String]$Message,
[Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[String]$LogFile
)
Process {
$LogMessage = Get-Date -uformat "%d.%m.%Y %H:%M:%S"
$LogMessage += "`t"
$LogMessage += $Message
$LogMessage | Out-File -FilePath $LogFile -Append
}
}#End Function
# ------------------------------------------------------------------------------------------------
# Получение пути к скрипту
$ScriptFolder = $MyInvocation.MyCommand.Path.SubString(0,($MyInvocation.MyCommand.Path.Length - $MyInvocation.MyCommand.Name.Length))
# Формирование пути к лог-файлу
$LogFile = $ScriptFolder + $MyInvocation.MyCommand.Name.SubString(0,($MyInvocation.MyCommand.Name.Length - 4)) + ".log"
$JsonFile = $ScriptFolder + $MyInvocation.MyCommand.Name.SubString(0,($MyInvocation.MyCommand.Name.Length - 4)) + ".json"
# Создание лог-файла
Out-File -FilePath $LogFile
Write-ScriptLog -LogFile $LogFile -Message ($MyInvocation.MyCommand.Name + " started")
# Чтение аргументов из командной строки
Write-ScriptLog -LogFile $LogFile -Message "Reading input arguments"
If ($args.length -ne 3) {
Write-ScriptLog -LogFile $LogFile -Message "Wrong number of agruments"
Write-ScriptLog -LogFile $LogFile -Message "Using default values"
$AZU_TENANT_ID = 'abcdefjh-1234-abcd-1234-abcdefjhigkl'
$AZU_CLIENT_ID = 'hjfedcba-4321-dcba-4321-lkgihjfedcba'
$AZU_SECRET_KEY = '123.abc.1234567.abcdefj.123456789'
} else {
$AZU_TENANT_ID = $args[0]
$AZU_CLIENT_ID = $args[1]
$AZU_SECRET_KEY = $args[2]
}
Write-ScriptLog -LogFile $LogFile -Message " azu_tenant_id is $AZU_TENANT_ID"
Write-ScriptLog -LogFile $LogFile -Message " azu_client_id is $AZU_CLIENT_ID"
Write-ScriptLog -LogFile $LogFile -Message " aqzu_secret_key is $AZU_SECRET_KEY"
Write-ScriptLog -LogFile $LogFile -Message " output json-file is $JsonFile"
# вход в Azure
Write-ScriptLog -LogFile $LogFile -Message "Logging in to Azure"
$AZU_SECRET_KEY_SEC = ConvertTo-SecureString $AZU_SECRET_KEY -AsPlainText -Force
$pscredential = New-Object -TypeName System.Management.Automation.PSCredential($AZU_CLIENT_ID, $AZU_SECRET_KEY_SEC)
Disconnect-AzAccount
Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $AZU_TENANT_ID | Out-Null
# создание пустого списка свойств резервного копирования серверов
$data = New-Object System.Collections.Generic.List[System.Object]
# получение всех рекомендаций
Write-ScriptLog -LogFile $LogFile -Message "Reading recommendations"
$recommendations_list = Get-AzAdvisorRecommendation -Category Cost
Write-ScriptLog -LogFile $LogFile -Message ($vault_list.length.ToString() + " recommendations found")
ForEach ($recommendation_item in $recommendations_list) {
If ($recommendation_item.ImpactedField -eq "Microsoft.Compute/virtualMachines") {
$id = $recommendation_item.ImpactedValue.ToLower()
$name = $recommendation_item.ImpactedValue
if ($recommendation_item.ShortDescription.Problem.ToLower() -eq ("Right-size or shutdown underutilized virtual machines").ToLower()) {
$status = 'over_provisioned'
} else {
$status = 'see in the portal'
}
$type_current = $recommendation_item.ExtendedProperties.currentSku
$type_recommended = $recommendation_item.ExtendedProperties.targetSku
$utilization_cpu = 'Maximum: ' + $recommendation_item.ExtendedProperties.MaxCpuP95
$utilization_ram = 'Maximum: ' + $recommendation_item.ExtendedProperties.MaxMemoryP95
# составление словаря свойств резервного копирования сервера
$recommendation_properties = New-Object System.Object
$recommendation_properties | Add-member -MemberType NoteProperty -Name id -Value $id
$recommendation_properties | Add-member -MemberType NoteProperty -Name name -Value $name
$recommendation_properties | Add-member -MemberType NoteProperty -Name status -Value $status
$recommendation_properties | Add-member -MemberType NoteProperty -Name type_current -Value $type_current
$recommendation_properties | Add-member -MemberType NoteProperty -Name type_recommended -Value $type_recommended
$recommendation_properties | Add-member -MemberType NoteProperty -Name utilization_cpu -Value $utilization_cpu
$recommendation_properties | Add-member -MemberType NoteProperty -Name utilization_ram -Value $utilization_ram
# доабвление полученных свойств в список свойств резервного копирования серверов
$data.Add($recommendation_properties)
}
}
Write-ScriptLog -LogFile $LogFile -Message "Reading data from Azure is complete"
Write-ScriptLog -LogFile $LogFile -Message "Deleteing the output file if it exists"
If (Test-Path $JsonFile) { Remove-Item -Path $JsonFile }
If ($data -ne '') {
Write-ScriptLog -LogFile $LogFile -Message ("Saving json-file " + $JsonFile)
$data | ConvertTo-Json | Out-File -FilePath $JsonFile -Encoding "utf8"
}
# ------------------------------------------------------------------------------------------------
Write-ScriptLog -LogFile $LogFile -Message "----- The script finished -----"
Результат работы скрипта - json-файл с рекомендациями по оптимизации виртуальных машин
[
{
"id": "rhaaa001",
"name": "rhAAA001",
"status": "over_provisioned",
"type_current": "Standard_D4s_v3",
"type_recommended": "Standard_B4ms",
"utilization_cpu": "Maximum: 4",
"utilization_ram": "Maximum: 47"
},
{
"id": "rhaaa003",
"name": "rhAAA003",
"status": "over_provisioned",
"type_current": "Standard_D16s_v3",
"type_recommended": "Standard_B16ms",
"utilization_cpu": "Maximum: 1",
"utilization_ram": "Maximum: 76"
}
]
