PowerShell Twoim przyjacielem jest! Robimy porządki w subskrypcji.

Jeśli korzystasz z chmury i nadal tylko klikasz w portal… to daleko tak nie zajedziesz:) Nawet jeśli nie lubisz PowerShell czy Azure CLI to bez nich automatyzacja większy zadań kosztuje naprawdę masę niepotrzebnie utraconego czasu i kilometrów myszki. Dziś pokażę Ci dwa proste skrypty bez których ostatnio nie mogłem się obejść. Do dzieła!

UWAGA: skryptów używasz na własną odpowiedzialność. Jeśli masz wątpliwość, napisz mi maila lub zostaw posta na grupie FB. Upewnij się, że na pewno używasz swojej subskrypcji. Jeśli masz ich podpiętych wiele to polecenie Get-AzureRmSubscription i Select-AzureRmSubscription pomogą Ci wybrać tą właściwą.

Przypadek nr 1

    • Prowadzisz warsztat.
    • Potrzebujesz utworzyć 25 kont w Azure AD.
    • Potrzebujesz utworzyć 25 Resource Group
    • Każdy użytkownik dostaje swoją grupę zasobów, każdy tylko do grupy zasobów ma uprawnienie „Contributor”. Jak wolisz inną rolę to rzuć okiem w dokumenty.
    • Za 16 godzin wszystkie te grupy zasobów muszą wylecieć w powietrze, zasoby nie będą Ci dłużej potrzebne

Gotowy skrypt masz poniżej. Po komentarzach dojdziesz o co chodzi. Ja korzystam głównie z North Europe, ale jeśli twoim ulubionym DC jest Korea South, zmień skrypt. Polecenie Install-Module AzureAD zostawiam tylko dlatego, że możesz go nie mieć na swojej maszynie.

Install-Module AzureAD
Connect-AzureAD

$PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$PasswordProfile.Password = "bardzoskomplikowanehaslo123!@#"

#id pierwszego użytkownika
$startCounter=30
$counter=$startCounter
#konwencja nazewnicza dla Twoich użytkowników
$userName = "usr"+$counter
#UPN. Uważaj: sprawdź, czy taki UPN istnieje w Twojej domenie w Azure AD. 
$upn = $userName +"@cloudarchitects.pl"
#konwencja nazewnicza dla Twoich grup zasobów
$rgName ="rg"+$counter
#maksymalna liczba użytkowników 
$nrUsers = 30
$maxUsers = $startCounter + $nrUsers

for (;$counter -le $maxUsers; $counter++)
{
    $userName = "usr"+$counter
    $upn = $userName +"@cloudarchitects.pl"
    $rgName ="rg"+$counter
    New-AzureADUser -DisplayName $userName -PasswordProfile $PasswordProfile -UserPrincipalName $upn `
                    -AccountEnabled $true -MailNickName $userName

    New-AzureRmResourceGroup -Name $rgName -Location 'North Europe'

    New-AzureRmRoleAssignment -SignInName $upn `
                              -RoleDefinitionName "Contributor" -ResourceGroupName $rgName
}

Jeśli już przyszedł czas na kasowanie tych wszystkich grup, możesz zrobić to tak.

#kasujemy. 
$startCounter=30
$nrUsers = 1
$maxUsers = $startCounter + $nrUsers
for ($counter=$startCounter; $counter -le $maxUsers; $counter++){
    
    $rgName ="rg"+$counter
    Remove-AzureRmResourceGroup -Name $rgName -Force 
    
}

Przypadek nr 2 czyli zabawa tylko dla dorosłych

  • Twoja subskrypcja zawiera masę grup zasobów, dużo zasobów testowych, wiele nieudanych prób ARM’owych i innych eksperymentów
  • Na pewno nie zawsze wszystko nazywałeś zgodnie z konwencją (…jaką konwencją?;))
  • Nie wszystko trafiało do odpowiednich grup zasobów ect.
  • Brzmi znajomo? Niestety też tak czasem mam. Mając 14 subskrypcji problem dotyka mnie często.

Co robi skrypt?

  • Stara się znaleźć na początek adresy IP, które są przypięte zupełnie do niczego
  • Szuka interfejsów sieciowych (NIC), które są osamotnione
  • Szuka sieci (VNET’ów), które w żadnym subnecie nie mają ani jednego zasobu
  • Szuka porzuconych dysków VHD. Na teraz tylko tych niezarządzanych, zaraz dopiszę i zarządzane.
  • Na końcu szuka pustych grup zasobów i też ich się pozbywa

Mam do Ciebie ogromną prośbę.

Ten skrypt, po tym jak usuniesz odpowiednie komentarze:), naprawdę zacznie kasować. A więc zanim to zrobisz, zobacz jakie zasoby będzie chciał usunąć.

Lepiej to zrobić 3 razy niż potem publiczne narzekać, że Furmankiewicz skasował Ci subskrypcję.

Narzekanie w supporcie Microsoft też nie wiele zmieni.

#Show me NIC's not attached to VM's
Get-AzureRmNetworkInterface | Where { $_.VirtualMachine -eq $null } | Select { $_.Name }

$nics=Get-AzureRmNetworkInterface | Where { $_.VirtualMachine -eq $null } 
foreach($nic in $nics)
{
   Write-Host 'Deleting ' $nic.Name
   #Remove-AzureRmNetworkInterface -Name $nic.Name -ResourceGroupName $nic.ResourceGroupName -Force
}

#Show me PIP's not attached to NIC's

Get-AzureRmPublicIpAddress | Where { $_.IpConfigurationText -eq "null" } | Select { $_.Name }

$ips=Get-AzureRmPublicIpAddress | Where { $_.IpConfigurationText -eq "null" } 
foreach ($ip in $ips)
{
    Write-Host 'Deleting ' $ip.Name
    #Remove-AzureRmPublicIpAddress -Name $ip.Name -ResourceGroup $ip.ResourceGroupName -Force
}


#Remove not used virtual networks (with empty subnets)
$networks = Get-AzureRmVirtualNetwork
foreach ($network in $networks)
{
    $subnets = $network.Subnets.Count
    $toDelete=0;
    for ($i=0; $i -lt $subnets;$i++)
    {
        
        if ($network.Subnets[$i].IpConfigurations.Count -eq 0)
        {
            $toDelete++;
        }
    }
    if ($subnets -eq $toDelete)
    {
        'Deleteing ' $network.Name 
        #Remove-AzureRmVirtualNetwork -Name $network.Name -ResourceGroupName $network.ResourceGroupName -Force
    }
}

#Remove disks not attached to the VM
$sas = Get-AzureRmStorageAccount
foreach ($sa in $sas)
{
    $container = ""
    $container=Get-AzureStorageContainer -Context $sa[0].Context | Where { $_.Name -like 'vhd*' }
    
    if ($container.Name -like "vhd*") 
    {   
        $list=Get-AzureStorageBlob -Context $sa[0].Context -Container $container.Name 
        foreach ($item in $list)
        {
            if ($item.ICloudBlob.Properties.LeaseStatus.ToString() -eq "Unlocked")
            {
                Write-Host 'SA: ' $sa.StorageAccountName 'SKU '$sa.Sku.Name 'Blob ' $item.Name
                #Remove-AzureStorageBlob -Blob $item.Name -Container $container.Name -Force -Context $item.Context
            }
            
        }
    }
}

#Remove empty Resource Groups
$rgs=Get-AzureRmResourceGroup
foreach ($rg in $rgs)
{
        $rs = Find-AzureRmResource -ResourceGroupNameEquals $rg.ResourceGroupName
        if ($rs.Count -eq 0)
        {
            Write-Host 'Deleting ' $rg.ResourceGroupName
            #Remove-AzureRmResourceGroup -Name $rg.ResourceGroupName -Force
        }
}

Powodzenia!

ps. Żeby nie było, że nie ostrzegałem. Potrafię kasować:)

Ten wpis został opublikowany w kategorii PowerShell i oznaczony tagami , , , , . Dodaj zakładkę do bezpośredniego odnośnika.