Runbooks
<#
.SYNOPSIS
Script para start/stop de recursos com o schedule gerenciado via Tags
.DESCRIPTION
O script não precisa de nenhum parâmetro, ele irá ler todo o ambiente no Azure em busca dos recursos com o schedule gerenciado via Tag
Módulos necessários que não são padrão na Automation Account:
Az.Accounts
Az.Aks
Os schedules necessários podem ser criados com o script abaixo, apenas substituindo o ID da Automation Account
$AutomationAccountId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Automation/automationAccounts/account1";
$RunbookName = "ManagedSchedule";
$TempID = $AutomationAccountId.Split("/");
$SubscriptionId = $TempID[2];
$ResourceGroupName = $TempID[4];
$ResourceName = $TempID[-1];
Select-AzSubscription -SubscriptionId $SubscriptionId;
$TimeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById("E. South America Standard Time");
$TimeZoneId = $TimeZone.Id;
$BrazilDateTime = [System.TimeZoneInfo]::ConvertTimeFromUtc([DateTime]::UtcNow, $TimeZone);
$BrazilDateTime = $BrazilDateTime.AddHours(2);
$Minutes = @("00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55");
foreach ($Minute in $Minutes) {
$StartTime = "$($BrazilDateTime.Hour):$($Minute)";
New-AzAutomationSchedule -AutomationAccountName $ResourceName -Name "ManagedSchedule-$($Minute)" -StartTime $StartTime -HourInterval 1 -ResourceGroupName $ResourceGroupName -TimeZone $TimeZoneId;
Register-AzAutomationScheduledRunbook -AutomationAccountName $ResourceName -RunbookName $RunbookName -ScheduleName "ManagedSchedule-$($Minute)" -ResourceGroupName $ResourceGroupName;
}
.EXAMPLE
PS C:\> ManagedSchedule.ps1
.NOTES
Filename: ManagedSchedule.ps1
Author: Caio Souza do Carmo
Modified date: 2023-02-27
Version 1.0 - Start e Stop de VMs e AKS
#>
function GetDate() {
$tDate = (Get-Date).ToUniversalTime();
$TimeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById("E. South America Standard Time");
$tCurrentTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($tDate, $TimeZone);
$DateInfo = @{
"UFormat" = "%Y-%m-%d %H:%M:%S"
"Date" = $tCurrentTime
}
return Get-Date @DateInfo;
}
function DesiredState() {
param (
[Parameter()]
[String[]]$StartAt,
[Parameter()]
[String[]]$StopAt,
[Parameter()]
[String]$KeepStatus
)
$Weekday = (Get-Date).DayOfWeek.value__;
$TimeFormat = "^([01]\d|2[0-3]):([0-5]\d)$";
if ($KeepStatus -eq "On") {
return "start";
}
if ($KeepStatus -eq "Off") {
return "stop";
}
$StartTime = $StartAt[$Weekday];
$StopTime = $StopAt[$Weekday];
if ( ($StartTime -notmatch $TimeFormat) -or ($StopTime -notmatch $TimeFormat) ) {
if ( ($StartTime -match $TimeFormat) -and ($StopTime -notmatch $TimeFormat) ) {
$StopTime = "23:59";
}
else {
$Index = $Weekday;
$ExpectedState = "";
for ($i = 0; $i -lt 6; $i++) {
$Index--;
if ($Index -eq -1) {
$Index = 6;
}
if ($StopAt[$Index] -match $TimeFormat) {
$ExpectedState = "stop";
break;
}
if ($StartAt[$Index] -match $TimeFormat) {
$ExpectedState = "start";
break;
}
}
if ($ExpectedState -eq "start") {
$StartTime = "00:00";
if ($StopTime -notmatch $TimeFormat) {
$StopTime = "23:59";
}
}
else {
$StartTime = "23:59";
if ($StopTime -notmatch $TimeFormat) {
$StopTime = "00:00";
}
}
}
}
$Format = "HH:mm";
$BrazilCulture = New-Object System.Globalization.CultureInfo("pt-BR");
$StartDateTime = [DateTime]::ParseExact($StartTime, $Format, $BrazilCulture);
$StopDateTime = [DateTime]::ParseExact($StopTime, $Format, $BrazilCulture);
$BrazilTimeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById("E. South America Standard Time");
$BrazilDateTime = [System.TimeZoneInfo]::ConvertTimeFromUtc([DateTime]::UtcNow, $BrazilTimeZone);
$StartDateTime = $BrazilDateTime.Date.Add($StartDateTime.TimeOfDay);
$StopDateTime = $BrazilDateTime.Date.Add($StopDateTime.TimeOfDay);
if ( ($StartDateTime -le $BrazilDateTime) -and ($StopDateTime -ge $BrazilDateTime) ) {
return "start";
}
else {
return "stop";
}
}
function StartStopVM() {
param (
[Parameter()]
[String]$ResourceId,
[Parameter()]
[String]$Action
)
$TempID = $ResourceId.Split("/");
#$SubscriptionId = $TempID[2];
$ResourceGroupName = $TempID[4];
$ResourceName = $TempID[-1];
if ($Action -eq "start") {
Start-AzVM -ResourceGroupName $ResourceGroupName `
-Name $ResourceName `
-NoWait;
}
elseif ($Action -eq "stop") {
Stop-AzVM -ResourceGroupName $ResourceGroupName `
-Name $ResourceName `
-Force `
-NoWait;
}
}
function StartStopAKS() {
param (
[Parameter()]
[String]$ResourceId,
[Parameter()]
[String]$Action
)
$TempID = $ResourceId.Split("/");
#$SubscriptionId = $TempID[2];
$ResourceGroupName = $TempID[4];
$ResourceName = $TempID[-1];
if ($Action -eq "start") {
Start-AzAksCluster -ResourceGroupName $ResourceGroupName `
-Name $ResourceName `
-NoWait `
-WarningAction SilentlyContinue;
}
elseif ($Action -eq "stop") {
Stop-AzAksCluster -ResourceGroupName $ResourceGroupName `
-Name $ResourceName `
-NoWait `
-WarningAction SilentlyContinue;
}
}
Connect-AzAccount -Identity -ErrorAction Stop -ErrorVariable AccountNotConnected -WarningAction SilentlyContinue;
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure");
Write-Host $AccountNotConnected;
}
$ResourceTypes = @("Microsoft.Compute/virtualMachines", "Microsoft.ContainerService/managedClusters");
$SubscriptionList = (Get-AzSubscription);
foreach ($Subscription in $SubscriptionList) {
Write-Host ("[$(GetDate)] Selecionando assinatura $($Subscription.Id)");
$SelectedSubscription = (Select-AzSubscription -SubscriptionId $Subscription.Id);
Write-Host ("[$(GetDate)] Assinatura `"$($SelectedSubscription.Subscription.Name)`" selecionada");
Write-Host ("[$(GetDate)] Listando recursos com o schedule gerenciado");
$ResourceList = (Get-AzResource -Tag @{ managedSchedule = 'Yes' });
Write-Host ("[$(GetDate)] $($ResourceList.Count) recursos encontrados com o schedule gerenciado");
foreach ($Resource in $ResourceList) {
if ($ResourceTypes -icontains $Resource.Type) {
$TagsTable = $Resource.TagsTable;
$Tags = $Resource.Tags;
$ResourceId = $Resource.Id;
$TempID = $ResourceId.Split("/");
$ResourceGroupName = $TempID[4];
$ResourceName = $TempID[-1];
$KeepStatus = "";
if ($TagsTable.Contains("keepStatus")) {
$KeepStatus = $Tags["keepStatus"];
}
$Action = DesiredState -StartAt $Tags["startAt"].Split("|") -StopAt $Tags["stopAt"].Split("|") -KeepStatus $KeepStatus;
if ($Resource.Type -ieq "Microsoft.Compute/virtualMachines") {
$CurrentStatus = ((Get-AzVM -Name $ResourceName -ResourceGroupName $ResourceGroupName -Status).Statuses.code[1]).Split("/")[1];
if ( ($CurrentStatus -ieq "running") -and ($Action -eq "start") ) {
Write-Host ("[$(GetDate)] VM `"$($ResourceName)`" já está com o estado esperado: $($CurrentStatus)");
}
elseif ( ($CurrentStatus -ieq "running") -and ($Action -eq "stop") ) {
Write-Host ("[$(GetDate)] Parando VM `"$($ResourceName)`"");
StartStopVM -ResourceId $ResourceId -Action "stop";
}
elseif ( ($CurrentStatus -ine "running") -and ($Action -eq "start") ) {
Write-Host ("[$(GetDate)] Ligando VM `"$($ResourceName)`"");
StartStopVM -ResourceId $ResourceId -Action "start";
}
elseif ( ($CurrentStatus -ine "running") -and ($Action -eq "stop") ) {
Write-Host ("[$(GetDate)] VM `"$($ResourceName)`" já está com o estado esperado: $($CurrentStatus)");
}
else {
Write-Host ("[$(GetDate)] Erro. VM: `"$($ResourceName)`". Estado: $($CurrentStatus). Action: $($Action)");
}
}
elseif ($Resource.Type -ieq "Microsoft.ContainerService/managedClusters") {
$CurrentStatus = ((Get-AzAKSCluster -Name $ResourceName -ResourceGroupName $ResourceGroupName -WarningAction SilentlyContinue).PowerState.Code);
if ( ($CurrentStatus -ieq "Running") -and ($Action -eq "start") ) {
Write-Host ("[$(GetDate)] AKS `"$($ResourceName)`" já está com o estado esperado: $($CurrentStatus)");
}
elseif ( ($CurrentStatus -ieq "Running") -and ($Action -eq "stop") ) {
Write-Host ("[$(GetDate)] Parando AKS `"$($ResourceName)`"");
StartStopAKS -ResourceId $ResourceId -Action "stop";
}
elseif ( ($CurrentStatus -ine "Running") -and ($Action -eq "start") ) {
Write-Host ("[$(GetDate)] Ligando AKS `"$($ResourceName)`"");
StartStopAKS -ResourceId $ResourceId -Action "start";
}
elseif ( ($CurrentStatus -ine "Running") -and ($Action -eq "stop") ) {
Write-Host ("[$(GetDate)] AKS `"$($ResourceName)`" já está com o estado esperado: $($CurrentStatus)");
}
else {
Write-Host ("[$(GetDate)] Erro. AKS: `"$($ResourceName)`". Estado: $($CurrentStatus). Action: $($Action)");
}
}
}
}
}
<#
.SYNOPSIS
Script para start/stop de VM
.DESCRIPTION
O script recebe como parâmetros a Assinatura (ID ou nome), Grupo de Recursos, nome da VM e ação (Start ou Stop) e executa conforme o especificado
Para iniciar, é necessário ter instalado o módulo Az
Install-Module -Name Az
É necessário estar conectado à conta do Azure em que a(s) sua(s) Assinatura(s) existe(m)
Se executado no Cloud Shell, os comandos abaixo não são necessários
Para conectar, utilize o comando abaixo:
Connect-AzAccount
Caso você possua mais de um diretório na mesma conta, pode ser especificado o TenantID em que as Assinaturas escolhidas existem
Connect-AzAccount -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Caso a página de login não abra automaticamente, pode ser utilizado o comando abaixo para gerar um código que deve ser inserido na URL "https://microsoft.com/devicelogin" para possibilitar o login
Connect-AzAccount -UseDeviceAuthentication
.PARAMETER Subscription
Id ou Nome da Assinatura quem contém o recurso
.PARAMETER ResourceGroupName
Grupo de Recursos que contém o recurso
.PARAMETER VMName
Nome do recurso
.PARAMETER StartStop
Ação desejada (Start ou Stop)
.PARAMETER ConnectionType
Tipo de conexão que será utilizada na Automation Account (Managed Identity ou Run As Account)
.EXAMPLE
PS C:\> Start_Stop_VMs.ps1 `
-Subscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx `
-ResourceGroupName grupo `
-VMName vm001 `
-StartStop start `
-ConnectionType Identity
Com os parâmetros acima, o script irá executar a ação de start na VM "vm001" do Grupo de Recursos "grupo" da Assinatura "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" utilizando a managed identity da Automation Account
.NOTES
Filename: Start_Stop_VMs.ps1
Author: Caio Souza do Carmo
Modified date: 2022-08-11
Version 1.0 - Start e Stop do VM
Version 1.1 - Autenticação
#>
param(
[Parameter(Mandatory = $true, HelpMessage = "Please specify the Subscription")]
[String]$Subscription,
[Parameter(Mandatory = $true, HelpMessage = "Please specify the Resource Group Name")]
[String]$ResourceGroupName,
[Parameter(Mandatory = $true, HelpMessage = "Please specify the VM Name")]
[String]$VMName,
[Parameter(Mandatory = $true, HelpMessage = "Start or Stop?")]
[ValidateSet("start", "stop", IgnoreCase = $true)]
[String]$StartStop,
[Parameter(Mandatory = $true, HelpMessage = "Connection Type")]
[ValidateSet("Identity", "RunAs", "Local", IgnoreCase = $true)]
[String]$ConnectionType
)
function GetDate() {
$tDate = (Get-Date).ToUniversalTime();
$TimeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById("E. South America Standard Time");
$tCurrentTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($tDate, $TimeZone);
$DateInfo = @{
"UFormat" = "%Y-%m-%d %H:%M:%S"
"Date" = $tCurrentTime
}
return Get-Date @DateInfo;
}
if (@("Identity", "RunAs") -contains $ConnectionType) {
Import-Module Az;
if ($ConnectionType -eq "Identity") {
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
Connect-AzAccount -Identity -ErrorAction Stop -ErrorVariable AccountNotConnected;
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
elseif ($ConnectionType -eq "RunAs") {
Write-Host ("[$(GetDate)] Obtendo conexão da Automation Account") -ForegroundColor Yellow;
$ServicePrincipalConnection = (Get-AutomationConnection -Name "AzureRunAsConnection");
$AzAccountParams = @{
"ServicePrincipal" = $True
"Tenant" = $ServicePrincipalConnection.TenantID
"ApplicationId" = $ServicePrincipalConnection.ApplicationID
"CertificateThumbprint" = $ServicePrincipalConnection.CertificateThumbprint
"ErrorAction" = "Stop"
"ErrorVariable" = "AccountNotConnected"
}
Write-Host ("[$(GetDate)] Tenant Id: $($ServicePrincipalConnection.TenantID)") -ForegroundColor Cyan;
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
(Connect-AzAccount @AzAccountParams);
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
else {
Exit;
}
}
Write-Host ("[$(GetDate)] Selecionando assinatura $($Subscription)") -ForegroundColor Yellow;
if ($VMSubscription -match '^[a-zA-Z0-9]{8}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{12}$') {
Select-AzSubscription -SubscriptionId $Subscription;
}
else {
Select-AzSubscription -SubscriptionName $Subscription;
}
if ($startStop.ToLower() -eq "start") {
Write-Host ("[$(GetDate)] Iniciando VM $($VMName)") -ForegroundColor Yellow;
Start-AzVM -ResourceGroupName $ResourceGroupName `
-Name $VMName `
-NoWait;
}
elseif ($startStop.ToLower() -eq "stop") {
Write-Host ("[$(GetDate)] Parando VM $($VMName)") -ForegroundColor Yellow;
Stop-AzVM -ResourceGroupName $ResourceGroupName `
-Name $VMName `
-NoWait;
}
<#
.SYNOPSIS
Script para start/stop de Azure Database for MariaDB server
.DESCRIPTION
O script recebe como parâmetro as informações do server, junto com a ação desejada (start ou stop) e realiza a ação solicitada
Atualmente (2022-06-02) o script funciona realizando uma chamada na API do Azure, pois ainda não há o comando equivalente no módulo do Powershell
O comando existe no CLI, no entanto não pode ser utilizado em Automation Accounts
https://docs.microsoft.com/en-us/cli/azure/mariadb/server?view=azure-cli-latest#az-mariadb-server-stop
Para iniciar, é necessário ter instalado o módulo Az
Install-Module -Name Az
É necessário estar conectado à conta do Azure em que a(s) sua(s) Assinatura(s) existe(m)
Se executado no Cloud Shell, os comandos abaixo não são necessários
Para conectar, utilize o comando abaixo:
Connect-AzAccount
Caso você possua mais de um diretório na mesma conta, pode ser especificado o TenantID em que as Assinaturas escolhidas existem
Connect-AzAccount -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Caso a página de login não abra automaticamente, pode ser utilizado o comando abaixo para gerar um código que deve ser inserido na URL "https://microsoft.com/devicelogin" para possibilitar o login
Connect-AzAccount -UseDeviceAuthentication
.PARAMETER SubscriptionID
O ID da Assinaturas contendo o recurso
.PARAMETER ResourceGroupName
O nome do Grupo de Recursos contendo o recurso
.PARAMETER MariaDBName
O nome do recurso
.PARAMETER StartStop
Ação à ser realizada (start ou stop)
.PARAMETER ConnectionType
Tipo de conexão que será utilizada na Automation Account (Managed Identity ou Run As Account)
.EXAMPLE
PS C:\> Start_Stop_MariaDB.ps1 `
-SubscriptionID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx `
-ResourceGroupName xxxxxxxx `
-MariaDBName "exemplo" `
-StartStop "stop" `
-ConnectionType Identity
No exemplo acima, o MariaDB "exemplo" da Assinatura xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx do Grupo de Recursos xxxxxxxx será parado utilizando a managed identity da Automation Account
.NOTES
Filename: Start_Stop_MariaDB.ps1
Author: Caio Souza do Carmo
Modified date: 2022-06-02
Version 1.0 - Start/Stop de MariaDB
#>
param(
[Parameter(Mandatory = $true, HelpMessage = "Please specify the Subscription id")]
[String]$SubscriptionID,
[Parameter(Mandatory = $true, HelpMessage = "Please specify the Resource Group Name")]
[String]$ResourceGroupName,
[Parameter(Mandatory = $true, HelpMessage = "Please specify the MariaDB Name")]
[String]$MariaDBName,
[Parameter(Mandatory = $true, HelpMessage = "Start or Stop?")]
[ValidateSet("start", "stop", IgnoreCase = $true)]
[String]$StartStop,
[Parameter(Mandatory = $true, HelpMessage = "Connection Type")]
[ValidateSet("Identity", "RunAs", "Local", IgnoreCase = $true)]
[String]$ConnectionType
)
function GetDate() {
$tDate = (Get-Date).ToUniversalTime();
$TimeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById("E. South America Standard Time");
$tCurrentTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($tDate, $TimeZone);
$DateInfo = @{
"UFormat" = "%Y-%m-%d %H:%M:%S"
"Date" = $tCurrentTime
}
return Get-Date @DateInfo;
}
function GetAccessToken() {
$AzContext = (Get-AzContext);
$AzProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile;
$ProfileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($AzProfile);
$Token = $ProfileClient.AcquireAccessToken($AzContext.Subscription.TenantId);
return $Token;
}
if (@("Identity", "RunAs") -contains $ConnectionType) {
Import-Module Az;
if ($ConnectionType -eq "Identity") {
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
Connect-AzAccount -Identity -ErrorAction Stop -ErrorVariable AccountNotConnected;
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
elseif ($ConnectionType -eq "RunAs") {
Write-Host ("[$(GetDate)] Obtendo conexão da Automation Account") -ForegroundColor Yellow;
$ServicePrincipalConnection = (Get-AutomationConnection -Name "AzureRunAsConnection");
$AzAccountParams = @{
"ServicePrincipal" = $True
"Tenant" = $ServicePrincipalConnection.TenantID
"ApplicationId" = $ServicePrincipalConnection.ApplicationID
"CertificateThumbprint" = $ServicePrincipalConnection.CertificateThumbprint
"ErrorAction" = "Stop"
"ErrorVariable" = "AccountNotConnected"
}
Write-Host ("[$(GetDate)] Tenant Id: $($ServicePrincipalConnection.TenantID)") -ForegroundColor Cyan;
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
(Connect-AzAccount @AzAccountParams);
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
else {
Exit;
}
}
$InformationPreference = "SilentlyContinue";
Write-Host ("[$(GetDate)] Obtendo token") -ForegroundColor Yellow;
$Token = GetAccessToken;
$AccessToken = $Token.AccessToken;
$authHeader = @{
'Content-Type' = 'application/json'
'Authorization' = 'Bearer ' + $AccessToken
}
Write-Host ("[$(GetDate)] $($AccessToken.Length)") -ForegroundColor Green;
$StartStop = $StartStop.ToLower();
Write-Host ("[$(GetDate)] Resumo da solicitação: ") -ForegroundColor Cyan;
Write-Host ("[$(GetDate)] ID do recurso: `"/subscriptions/$($SubscriptionID)/resourceGroups/$($ResourceGroupName)/providers/Microsoft.DBforMariaDB/servers/$($MariaDBName)`"") -ForegroundColor Cyan;
Write-Host ("[$(GetDate)] Ação: $($StartStop)") -ForegroundColor Cyan;
$restUri = "https://management.azure.com/subscriptions/$($SubscriptionID)/resourceGroups/$($ResourceGroupName)/providers/Microsoft.DBforMariaDB/servers/$($MariaDBName)/$($StartStop)?api-version=2020-01-01-privatepreview";
Invoke-RestMethod -Uri $restUri -Method Post -Headers $authHeader;
<#
.SYNOPSIS
Script para start/stop de AKS
.DESCRIPTION
O script recebe como parâmetros a Assinatura (ID ou nome), Grupo de Recursos, nome do AKS e ação (Start ou Stop) e executa conforme o especificado
Para iniciar, é necessário ter instalado o módulo Az
Install-Module -Name Az
É necessário estar conectado à conta do Azure em que a(s) sua(s) Assinatura(s) existe(m)
Se executado no Cloud Shell, os comandos abaixo não são necessários
Para conectar, utilize o comando abaixo:
Connect-AzAccount
Caso você possua mais de um diretório na mesma conta, pode ser especificado o TenantID em que as Assinaturas escolhidas existem
Connect-AzAccount -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Caso a página de login não abra automaticamente, pode ser utilizado o comando abaixo para gerar um código que deve ser inserido na URL "https://microsoft.com/devicelogin" para possibilitar o login
Connect-AzAccount -UseDeviceAuthentication
.PARAMETER Subscription
Id ou Nome da Assinatura quem contém o recurso
.PARAMETER ResourceGroupName
Grupo de Recursos que contém o recurso
.PARAMETER AKSName
Nome do recurso
.PARAMETER StartStop
Ação desejada (Start ou Stop)
.PARAMETER ConnectionType
Tipo de conexão que será utilizada na Automation Account (Managed Identity ou Run As Account)
.EXAMPLE
PS C:\> Start_Stop_AKS.ps1 `
-Subscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx `
-ResourceGroupName grupo `
-AKSName kubernetes `
-StartStop start `
-ConnectionType Identity
Com os parâmetros acima, o script irá executar a ação de start no AKS "kubernetes" do Grupo de Recursos "grupo" da Assinatura "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" utilizando a managed identity da Automation Account
.NOTES
Filename: Start_Stop_AKS.ps1
Author: Caio Souza do Carmo
Modified date: 2022-06-20
Version 1.0 - Start e Stop do AKS
Version 1.1 - Input aceitando tanto ID quanto nome da Assinatura
#>
param(
[Parameter(Mandatory = $true, HelpMessage = "Please specify the Subscription id")]
[String]$Subscription,
[Parameter(Mandatory = $true, HelpMessage = "Please specify the Resource Group Name")]
[String]$ResourceGroupName,
[Parameter(Mandatory = $true, HelpMessage = "Please specify the AKS Name")]
[String]$AKSName,
[Parameter(Mandatory = $true, HelpMessage = "Start or Stop?")]
[ValidateSet("start", "stop", IgnoreCase = $true)]
[String]$StartStop,
[Parameter(Mandatory = $true, HelpMessage = "Connection Type")]
[ValidateSet("Identity", "RunAs", "Local", IgnoreCase = $true)]
[String]$ConnectionType
)
function GetDate() {
$tDate = (Get-Date).ToUniversalTime();
$TimeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById("E. South America Standard Time");
$tCurrentTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($tDate, $TimeZone);
$DateInfo = @{
"UFormat" = "%Y-%m-%d %H:%M:%S"
"Date" = $tCurrentTime
}
return Get-Date @DateInfo;
}
if (@("Identity", "RunAs") -contains $ConnectionType) {
Import-Module Az;
if ($ConnectionType -eq "Identity") {
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
Connect-AzAccount -Identity -ErrorAction Stop -ErrorVariable AccountNotConnected;
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
elseif ($ConnectionType -eq "RunAs") {
Write-Host ("[$(GetDate)] Obtendo conexão da Automation Account") -ForegroundColor Yellow;
$ServicePrincipalConnection = (Get-AutomationConnection -Name "AzureRunAsConnection");
$AzAccountParams = @{
"ServicePrincipal" = $True
"Tenant" = $ServicePrincipalConnection.TenantID
"ApplicationId" = $ServicePrincipalConnection.ApplicationID
"CertificateThumbprint" = $ServicePrincipalConnection.CertificateThumbprint
"ErrorAction" = "Stop"
"ErrorVariable" = "AccountNotConnected"
}
Write-Host ("[$(GetDate)] Tenant Id: $($ServicePrincipalConnection.TenantID)") -ForegroundColor Cyan;
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
(Connect-AzAccount @AzAccountParams);
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
else {
Exit;
}
}
Write-Host ("[$(GetDate)] Selecionando assinatura $($Subscription)") -ForegroundColor Yellow;
if ($VMSubscription -match '^[a-zA-Z0-9]{8}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{12}$') {
Select-AzSubscription -SubscriptionId $Subscription;
}
else {
Select-AzSubscription -SubscriptionName $Subscription;
}
if ($StartStop.ToLower() -eq "start") {
Write-Host ("[$(GetDate)] Iniciando AKS $($AKSName)") -ForegroundColor Yellow;
Start-AzAksCluster -ResourceGroupName $ResourceGroupName `
-Name $AKSName `
-NoWait `
-WarningAction SilentlyContinue;
}
elseif ($StartStop.ToLower() -eq "stop") {
Write-Host ("[$(GetDate)] Parando AKS $($AKSName)") -ForegroundColor Yellow;
Stop-AzAksCluster -ResourceGroupName $ResourceGroupName `
-Name $AKSName `
-NoWait `
-WarningAction SilentlyContinue;
}
<#
.SYNOPSIS
Script para start/stop de Application Gateway
.DESCRIPTION
O script recebe como parâmetros a Assinatura (ID ou nome), Grupo de Recursos, nome do Application Gateway e ação (Start ou Stop) e executa conforme o especificado
Para iniciar, é necessário ter instalado o módulo Az
Install-Module -Name Az
É necessário estar conectado à conta do Azure em que a(s) sua(s) Assinatura(s) existe(m)
Se executado no Cloud Shell, os comandos abaixo não são necessários
Para conectar, utilize o comando abaixo:
Connect-AzAccount
Caso você possua mais de um diretório na mesma conta, pode ser especificado o TenantID em que as Assinaturas escolhidas existem
Connect-AzAccount -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Caso a página de login não abra automaticamente, pode ser utilizado o comando abaixo para gerar um código que deve ser inserido na URL "https://microsoft.com/devicelogin" para possibilitar o login
Connect-AzAccount -UseDeviceAuthentication
.PARAMETER Subscription
Id ou Nome da Assinatura quem contém o recurso
.PARAMETER ResourceGroupName
Grupo de Recursos que contém o recurso
.PARAMETER ApplicationGatewayName
Nome do recurso
.PARAMETER StartStop
Ação desejada (Start ou Stop)
.PARAMETER ConnectionType
Tipo de conexão que será utilizada na Automation Account (Managed Identity ou Run As Account)
.EXAMPLE
PS C:\> Start_Stop_Application_Gateway.ps1 `
-Subscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx `
-ResourceGroupName grupo `
-ApplicationGatewayName appgw `
-StartStop start
Com os parâmetros acima, o script irá executar a ação de start no Application Gateway "appgw" do Grupo de Recursos "grupo" da Assinatura "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" utilizando a managed identity da Automation Account
.NOTES
Filename: Start_Stop_Application_Gateway.ps1
Author: Caio Souza do Carmo
Modified date: 2022-07-15
Version 1.0 - Start e Stop do Application Gateway
#>
param(
[Parameter(Mandatory = $true, HelpMessage = "Please specify the Subscription")]
[String]$Subscription,
[Parameter(Mandatory = $true, HelpMessage = "Please specify the Resource Group Name")]
[String]$ResourceGroupName,
[Parameter(Mandatory = $true, HelpMessage = "Please specify the Application Gateway Name")]
[String]$ApplicationGatewayName,
[Parameter(Mandatory = $true, HelpMessage = "Start or Stop?")]
[ValidateSet("start", "stop", IgnoreCase = $true)]
[String]$StartStop,
[Parameter(Mandatory = $true, HelpMessage = "Connection Type")]
[ValidateSet("Identity", "RunAs", "Local", IgnoreCase = $true)]
[String]$ConnectionType
)
function GetDate() {
$tDate = (Get-Date).ToUniversalTime();
$TimeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById("E. South America Standard Time");
$tCurrentTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($tDate, $TimeZone);
$DateInfo = @{
"UFormat" = "%Y-%m-%d %H:%M:%S"
"Date" = $tCurrentTime
}
return Get-Date @DateInfo;
}
if (@("Identity", "RunAs") -contains $ConnectionType) {
Import-Module Az;
if ($ConnectionType -eq "Identity") {
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
Connect-AzAccount -Identity -ErrorAction Stop -ErrorVariable AccountNotConnected;
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
elseif ($ConnectionType -eq "RunAs") {
Write-Host ("[$(GetDate)] Obtendo conexão da Automation Account") -ForegroundColor Yellow;
$ServicePrincipalConnection = (Get-AutomationConnection -Name "AzureRunAsConnection");
$AzAccountParams = @{
"ServicePrincipal" = $True
"Tenant" = $ServicePrincipalConnection.TenantID
"ApplicationId" = $ServicePrincipalConnection.ApplicationID
"CertificateThumbprint" = $ServicePrincipalConnection.CertificateThumbprint
"ErrorAction" = "Stop"
"ErrorVariable" = "AccountNotConnected"
}
Write-Host ("[$(GetDate)] Tenant Id: $($ServicePrincipalConnection.TenantID)") -ForegroundColor Cyan;
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
(Connect-AzAccount @AzAccountParams);
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
else {
Exit;
}
}
Write-Host ("[$(GetDate)] Selecionando assinatura $($Subscription)") -ForegroundColor Yellow;
if ($Subscription -match '^[a-zA-Z0-9]{8}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{4}[-][a-zA-Z0-9]{12}$') {
Select-AzSubscription -SubscriptionId $Subscription;
}
else {
Select-AzSubscription -SubscriptionName $Subscription;
}
Write-Host ("[$(GetDate)] Obtendo informações do Application Gateway `"$($ApplicationGatewayName)`"") -ForegroundColor Yellow;
$AppGateway = (Get-AzApplicationGateway -Name $ApplicationGatewayName -ResourceGroupName $ResourceGroupName)
if ($StartStop.ToLower() -eq "start") {
Write-Host ("[$(GetDate)] Iniciando Application Gateway $($ApplicationGatewayName)") -ForegroundColor Yellow;
Start-AzApplicationGateway -ApplicationGateway $AppGateway;
}
elseif ($StartStop.ToLower() -eq "stop") {
Write-Host ("[$(GetDate)] Parando Application Gateway $($ApplicationGatewayName)") -ForegroundColor Yellow;
Stop-AzApplicationGateway -ApplicationGateway $AppGateway;
}
<#
.SYNOPSIS
Script para remover fazer o expurgo de logs do Log Analytics workspace
.DESCRIPTION
O script recebe como input o ID do Log Analytics workspace, as tabelas que serão expurgadas e a quantidade de dias de logs que será mantida
Documentação da API:
https://docs.microsoft.com/en-us/rest/api/loganalytics/workspace-purge/purge
O usuário ou serviço que executar esse script precisa da role "Data Purger" no recurso de destino, ter role de Contributor ou Owner não é o suficiente, é necessário essa role especifica, mais informações em:
https://docs.microsoft.com/en-us/services-hub/health/purge_assessment_data_in_log_analytics
Para iniciar, é necessário ter instalado o módulo Az
Install-Module -Name Az
É necessário estar conectado à conta do Azure em que a(s) sua(s) Assinatura(s) existe(m)
Se executado no Cloud Shell, os comandos abaixo não são necessários
Para conectar, utilize o comando abaixo:
Connect-AzAccount
Caso você possua mais de um diretório na mesma conta, pode ser especificado o TenantID em que as Assinaturas escolhidas existem
Connect-AzAccount -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Caso a página de login não abra automaticamente, pode ser utilizado o comando abaixo para gerar um código que deve ser inserido na URL "https://microsoft.com/devicelogin" para possibilitar o login
Connect-AzAccount -UseDeviceAuthentication
.PARAMETER ResourceId
ID do Log Analytics workspace
.PARAMETER Tables
Tabelas que serão expurgadas
.PARAMETER RetentionDays
Dias de log que serão mantidos
.PARAMETER ConnectionType
Tipo de conexão que será utilizada na Automation Account (Managed Identity ou Run As Account)
.EXAMPLE
PS C:\> PurgeLogAnalytics.ps1`
-ResourceId /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.OperationalInsights/workspaces/workspace1`
-Tables "Perf" `
-RetentionDays 7 `
-ConnectionType Identity
No exemplo acima, serão removidos todos logs com data superior à 7 dias, da tabela "Perf" do Log Analytics "workspace1" utilizando a managed identity da Automation Account
.NOTES
Filename: PurgeLogAnalytics.ps1
Author: Caio Souza do Carmo
Modified date: 2022-08-10
Version 1.0 - Expurgar logs
#>
#Requires -Version 7
param(
[Parameter(Mandatory = $true, HelpMessage = "Log Analytics workspace Id")]
[String]$ResourceId,
[Parameter(Mandatory = $true, HelpMessage = "Tables to purge")]
[String[]]$Tables,
[Parameter(Mandatory = $true, HelpMessage = "Days to retain")]
[Int]$RetentionDays,
[Parameter(Mandatory = $true, HelpMessage = "Connection Type")]
[ValidateSet("Identity", "RunAs", "Local", IgnoreCase = $true)]
[String]$ConnectionType
)
function GetDate() {
$tDate = (Get-Date).ToUniversalTime();
$TimeZone = [System.TimeZoneInfo]::FindSystemTimeZoneById("E. South America Standard Time");
$tCurrentTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($tDate, $TimeZone);
$DateInfo = @{
"UFormat" = "%Y-%m-%d %H:%M:%S"
"Date" = $tCurrentTime
}
return Get-Date @DateInfo;
}
function NormalizeDate {
param (
[Parameter()]
$DateString,
[Parameter()]
[String]$InputDateFormat,
[Parameter()]
[String]$OutputDateFormat = "yyyy-MM-dd HH:mm:ss"
)
$NormalizedDate = "";
if (($DateString).Length -gt 0) {
$TempDate = [datetime]::parseexact($DateString, $InputDateFormat, [Globalization.CultureInfo]::CreateSpecificCulture('pt-BR'));
$NormalizedDate = $TempDate.ToString($OutputDateFormat);
}
return $NormalizedDate;
}
function GetAccessToken() {
$AzContext = (Get-AzContext);
$AzProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile;
$ProfileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($AzProfile);
$Token = $ProfileClient.AcquireAccessToken($AzContext.Subscription.TenantId);
return $Token;
}
function BuildUri() {
param (
[Parameter()]
[String]$ResourceID,
[Parameter()]
[String]$URLQuery = "api-version=2020-08-01"
)
$RestUriBuilder = New-Object System.UriBuilder;
$RestUriBuilder.Host = "management.azure.com";
$RestUriBuilder.Path = ($ResourceID, "purge" -join '/');
$RestUriBuilder.Port = 443;
$RestUriBuilder.Scheme = 'https';
$RestUriBuilder.Query = $URLQuery;
return $RestUriBuilder.ToString();
}
if (@("Identity", "RunAs") -contains $ConnectionType) {
Import-Module Az;
if ($ConnectionType -eq "Identity") {
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
Connect-AzAccount -Identity -ErrorAction Stop -ErrorVariable AccountNotConnected;
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
elseif ($ConnectionType -eq "RunAs") {
Write-Host ("[$(GetDate)] Obtendo conexão da Automation Account") -ForegroundColor Yellow;
$ServicePrincipalConnection = (Get-AutomationConnection -Name "AzureRunAsConnection");
$AzAccountParams = @{
"ServicePrincipal" = $True
"Tenant" = $ServicePrincipalConnection.TenantID
"ApplicationId" = $ServicePrincipalConnection.ApplicationID
"CertificateThumbprint" = $ServicePrincipalConnection.CertificateThumbprint
"ErrorAction" = "Stop"
"ErrorVariable" = "AccountNotConnected"
}
Write-Host ("[$(GetDate)] Tenant Id: $($ServicePrincipalConnection.TenantID)") -ForegroundColor Cyan;
Write-Host ("[$(GetDate)] Conectando ao Azure") -ForegroundColor Yellow;
(Connect-AzAccount @AzAccountParams);
if ($AccountNotConnected) {
Write-Host ("[$(GetDate)] Falha ao conectar ao Azure") -ForegroundColor Red;
}
else {
Write-Host ("[$(GetDate)] Conexão realizada com sucesso") -ForegroundColor Green;
}
}
else {
Exit;
}
$Tables = $Tables.Split("/");
}
$DateLimit = (Get-Date).AddDays(-$RetentionDays).ToString("yyyy-MM-ddTHH:mm:ss");
Write-Host ("[$(GetDate)] Logs anteriores à $($DateLimit) serão expurgados") -ForegroundColor Yellow;
Write-Host ("[$(GetDate)] Obtendo token de acesso") -ForegroundColor Yellow;
$Token = GetAccessToken;
$AccessToken = $Token.AccessToken;
Write-Host ("[$(GetDate)] O token irá expirar em: $(NormalizeDate -DateString $Token.ExpiresOn.LocalDateTime -InputDateFormat "MM/dd/yyyy HH:mm:ss" -OutputDateFormat "dd/MM/yyyy HH:mm:ss")") -ForegroundColor Green;
$AuthHeader = @{
"Content-Type" = "application/json"
"Authorization" = "Bearer $($AccessToken)"
}
foreach ($Table in $Tables) {
$PurgeUrl = (BuildUri -ResourceID $ResourceId);
$Body = @{
"table" = $Table
"filters" = @(
@{
"column" = "TimeGenerated"
"operator" = "<="
"value" = $DateLimit
}
)
}
$BodyJson = ($Body | ConvertTo-Json);
Write-Host ("[$(GetDate)] Expurgando logs da tabela `"$($Table)`" ") -ForegroundColor Yellow;
$Request = (Invoke-WebRequest -Uri $PurgeUrl -Method POST -Body $BodyJson -Headers $AuthHeader -ContentType "application/json");
Write-Host ("[$(GetDate)] Status da requisição: $($Request.StatusCode) - $($Request.StatusDescription)") -ForegroundColor Cyan;
}