[Azure]使用Powershell清理ARM中的无效资源

60 篇文章 0 订阅
59 篇文章 0 订阅

Azure ARM模式将资源进一步细化,比经典模式要更为灵活,但是带来的的问题是,资源整理和维护起来就要更为琐碎。举一个比较实际的例子,创建了一台虚拟机,会为虚拟机指定虚拟网络(对应子网会生成网络接口),存储账号,公网IP地址,NSG(网络安全组),可用性集,当然还可能有其他资源与其关联。如果删除这台虚拟机,默认虚拟机的所有磁盘会被保留,存储账号会保留,容器会保留,公网IP地址,网络接口会保留,NSG和可用性集也都还在订阅中。一方面是费用上,可能这些保留下来的资源不会再用了,而有些可能仍然会继续计费,另一方面管理上会很混乱,有一大堆“游离”的资源在订阅下,让人眼花缭乱,而且这些资源可能还会占用订阅的配额。


我们可以使用下面的脚本进行这些资源的清理工作,除此之外,脚本中还有对花销比较大的资源(DS虚拟机,高级存储,应用程序网关)的停止和删除逻辑,并且在脚本开始时,我们通过一些布尔变量进行整个脚本逻辑的控制(例如是否关停,是否删除),可以进行一个“test run”来看一下脚本的执行结果(利用脚本中的输出语句和前面的布尔变量控制),这样可以保证我们执行出我们想要的结果,避免关闭或删除掉我们希望保留的资源。同时脚本也定义了一些例外规则(有兴趣的同学可以仿照添加其他例外资源的逻辑)。

对整个脚本进行一些学习,也可以熟悉和掌握遍历订阅下的ARM常见资源的语句和方法。

脚本如下:

#True: Real run/ False: Test run
$doActions = $TRUE;

#True: Real rum/ False: Test run
$doCleanUnusedResources = $TRUE;

#True: Real rum/ False: Test run
$doShutdowns = $TRUE;

#switch for delete/shutdown expensive resources
$doDeleteAppGateway = $TRUE;
$doDeletePremiumStorageAccounts = $TRUE;

#Login Credentials
$e1=Get-AzureRmEnvironment -Name AzureChinaCloud
$Cred = New-Object System.Management.Automation.PSCredential(“XXXX@XXX.parter.onmschina.cn”, (ConvertTo-SecureString “XXXXX” -AsPlainText -Force));

#exceptions
$VMExceptions = @{
    #<ResourceGroupName> = "<VM Name 1>;<VM Name 2>;<VM Name 3> ..."; 
    #"Example 1"="VM1;VM2;VM3"; 
    #"Example 2"="VM1;VM2" 
    };
    
$AppGWExceptions = @{
    #<ResourceGroupName> = "<Application Gateway 1>;<Application Gateway 2>;<Application Gateway 3> ..."; 
    #"Example 1"="ApplicationGateway1;ApplicationGateway2;ApplicationGateway3"; 
    #"Example 2"="ApplicationGateway1;ApplicationGateway2" 
    };
   
#Login
$AzureRMCred = Get-Credential -Credential $Cred;
Login-AzureRmAccount -Environment $e1 -Credential $AzureRMCred;

#get all subscriptions
$subscriptions = Get-AzureRmSubscription;

#loop every subscriptions
foreach ($subscription in $subscriptions)
{ 
    #skip disabled subscriptions 
    if ($subscription.State -eq "Disabled") { continue; } 
    
    Write-Host "========== Switched to subscription " + $subscription.SubscriptionName + " =========="; 
    Select-AzureRmSubscription -SubscriptionName $subscription.SubscriptionName; 
    
    #================================================ #Begin# shut down/remove expensive resources ================================================ 
    
    #shutdown/delete Application Gateways 
    $applicationGateways = Get-AzureRmApplicationGateway; 
    foreach ($applicationGateway in $applicationGateways) 
    { 
        if ($doDeleteAppGateway) 
        { 
            Write-Host " [ApplicationGateway]Removing ApplicationGateway " + $applicationGateway.Name + "..."; 
            if ($doActions) 
            { 
                Remove-AzureRmApplicationGateway -Name $applicationGateway.Name -ResourceGroupName $applicationGateway.ResourceGroupName -Force; 
            } 
            Write-Host " [ApplicationGateway]ApplicationGateway " + $applicationGateway.Name + " removed."; 
        } elseif ($doShutdowns) 
        { 
            Write-Host " [ApplicationGateway]Stopping ApplicationGateway " + $applicationGateway.Name + "..."; 
            if ($doActions) 
            { 
                Stop-AzureRmApplicationGateway -ApplicationGateway $applicationGateway; 
            } 
            Write-Host " [ApplicationGateway]ApplicationGateway " + $applicationGateway.Name + " stopped."; 
        } 
    } 
        
    #stop ARM VMs 
    $DSVMs = @{}; 
    $vms = Get-AzureRmVM; 
    foreach ($vm in $vms) 
    { 
            $except = $FALSE; 
            foreach ($resourceGroupName in $VMExceptions.Keys) 
            { 
                if ($vm.ResourceGroupName.ToLower().Equals($resourceGroupName.ToLower())) 
                { 
                    $vmnames = $VMExceptions[$resourceGroupName].Split(";"); 
                    foreach ($vmname in $vmnames) 
                    { 
                        if($vmname.ToLower().Equals($vm.Name.ToLower())) 
                        { 
                            $except = $true; 
                            break; 
                        } 
                    } 
                } 
            } 

            if ($vm.HardwareProfile.VmSize.Contains("DS")) 
            { 
                #add to DSVM dict to be deleted 
                if ($DSVMs.ContainsKey($vm.ResourceGroupName)) 
                { 
                    $DSVMs[$vm.ResourceGroupName] += ";"; 
                    $DSVMs[$vm.ResourceGroupName] += $vm.Name; 
                } else 
                { 
                    $DSVMs.Add($vm.ResourceGroupName, $vm.Name); 
                } 
            } 
            
            if ($except) 
            { 
                Write-Host " [VirtualMachine]Virtual Machine" + $vm.Name + " skipped(In exception list)"; 
            } else 
            { 
                $vmStatuses = (Get-AzureRmVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status).Statuses; 
                $status = ""; 
                foreach ($code in $vmStatuses.Code) 
                { 
                    if ($code.Contains("PowerState")) 
                    { 
                        $status = $code.Substring($code.LastIndexOf('/') + 1); 
                    } 
                } 
                
                if (($status -eq "running") -or ($status -eq "stopped")) 
                { 
                    Write-Host " [VirtualMachine]Stoping VirtualMachine " + $vm.Name + "..."; 
                    if ($doActions -and $doShutdowns) 
                    { 
                        Stop-AzureRmVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Force; 
                    } 
                    Write-Host " [VirtualMachine]Virtual Machine " + $vm.Name + " stopped."; 
                } else 
                { 
                    Write-Host " [VirtualMachine]Virtual Machine " + $vm.Name + " status is " + $status + ", skipped"; 
                } 
            } 
        } 
    
    #remove ARM DS VMs 
    foreach ($resoruceGroupName in $DSVMs.Keys) 
    { 
            $vmNames = $DSVMs[$resoruceGroupName].Split(';'); 
            foreach ($vmName in $vmNames) 
            { 
                Write-Host " [VirtualMachine]Removing DS VirtualMachine " + $vmName + "..."; 
                if ($doActions) 
                { 
                    Remove-AzureRmVM -ResourceGroupName $resoruceGroupName -Name $vmName -Force; 
                } 
                Write-Host " [VirtualMachine]DS VirtualMachine " + $vmName + " Removed."; 
            } 
        } 
    
    #remove Premium Storage Account 
    $storageAccounts = Get-AzureRmStorageAccount; 
    foreach ($storageAccount in $storageAccounts) 
    { 
            if($storageAccount.Sku.Tier -eq "Premium") 
            { 
                $storageName = $storageAccount.StorageAccountName; 
                $context = $storageAccount.Context; 
                $containers = Get-AzureStorageContainer -Context $context; 
                foreach ($container in $containers) 
                { 
                    $blobs = Get-AzureStorageBlob -Container $container.Name -Context $context; 
                    if ($blobs.Count -ne 0) 
                    { 
                        #Remove blobs 
                        foreach ($blob in $blobs) 
                        { 
                            Write-Host " [Blob]Removing Blob " + $blob.Name + " in container " + $storageName + "\\" + $container.Name + "..."; 
                            if ($doActions -and $doDeletePremiumStorageAccounts) 
                            { 
                                Remove-AzureStorageBlob -Blob $blob.Name -Container $container.Name -Context $context -Force; 
                            } 
                            
                            sleep(5); 
                            
                            $blobTest = Get-AzureStorageBlob -Blob $blob.Name -Container $container.Name -Context $context; 
                            if ($blobTest -ne $NULL) 
                            { 
                                Write-Host " [Blob]Failed to remove Blob " + $blob.Name; 
                            } else 
                            { 
                                Write-Host " [Blob]Blob " + $blob.Name + " Removed."; 
                            } 
                        } 
                    } 

                    #Remove container 
                    Write-Host " [Container]Removing Container " + $container.Name + " under storage account " + $storageName + "..."; 
                    if ($doActions -and $doDeletePremiumStorageAccounts) 
                    { 
                        Remove-AzureStorageContainer -Name $container.Name -Context $context -Force; 
                    } 
                    
                    sleep(5); 
                    
                    $containerTest = Get-AzureStorageContainer -Name $container.Name -Context $context; 
                    if ($containerTest -ne $NULL) 
                    { 
                        Write-Host " [Container]Failed to remove Container " + $container.Name; 
                    } else 
                    { 
                        Write-Host " [Container]Container " + $container.Name + " Removed."; 
                    } 
                } 
                
                #Remove storage account 
                Write-Host " [PremiumStorageAccount]Removing Premium Storage Account " + $storageName; 
                if ($doActions -and $doDeletePremiumStorageAccounts) 
                { 
                    Remove-AzureRmStorageAccount -ResourceGroupName $storageAccount.ResourceGroupName -Name $storageName -Force; 
                } 
                
                sleep(5); 
                
                $storageTest = Get-AzureRmStorageAccount -StorageAccountName $storageName -ResourceGroupName $storageAccount.ResourceGroupName; 
                if ($storageTest -ne $NULL) 
                { 
                    Write-Host " [PremiumStorageAccount]Failed to remove Premium Storage Account " + $storageName; 
                } else 
                { 
                    Write-Host " [PremiumStorageAccount]Premium Storage Account " + $storageName + " Removed."; 
                } 
            } 
        } 
    
    #================================================ #End# shut down/remove expensive resources ================================================ 
    
    #================================================ #Begin# clean unused resources ================================================ 
    #clear unused network interfaces 
    $nics = Get-AzureRmNetworkInterface; 
    foreach ($nic in $nics) 
    { 
            if ($nic.VirtualMachine -eq $NULL) 
            { 
                Write-Host " [NIC]Removing unused NIC " + $nic.Name + "..."; 
                if ($doActions -and $doCleanUnusedResources) 
                { 
                    Remove-AzureRmNetworkInterface -Name $nic.Name -ResourceGroupName $nic.ResourceGroupName -Force; 
                } 
                Write-Host " [NIC]NIC " + $nic.Name + " removed."; 
            } else 
            { 
                Write-Host " [NIC]NIC " + $nic.Name + " is in use, skipped"; 
            } 
        } 
    
    #clear unused public IPAddresses 
    $ips = Get-AzureRmPublicIpAddress; 
    foreach ($ip in $ips) 
    { 
            if ($ip.IpConfiguration -eq $NULL) 
            { 
                Write-Host " [IP]Removing unused IPAddress " + $ip.Name + "..."; 
                if ($doActions -and $doCleanUnusedResources) 
                { 
                    Remove-AzureRmPublicIpAddress -Name $ip.Name -ResourceGroupName $ip.ResourceGroupName -Force; 
                } 
                Write-Host " [IP]IPAddress " + $ip.Name + " removed."; 
            } else 
            { 
                Write-Host " [IP]IPAddress " + $ip.Name + " is in use, skipped"; 
            } 
        } 
    
    #clear unused NSGs 
    $nsgs = Get-AzureRmNetworkSecurityGroup; 
    foreach ($nsg in $nsgs) 
    { 
        if ($nsg.Subnets.Count -eq 0 -and $nsg.NetworkInterfaces.Count -eq 0) 
        { 
            Write-Host " [NSG]Removing unused NetworkSecurityGroup " + $nsg.Name + "..."; 
            if ($doActions -and $doCleanUnusedResources) 
            { 
                Remove-AzureRmNetworkSecurityGroup -Name $nsg.Name -ResourceGroupName $nsg.ResourceGroupName -Force; 
            } 
            Write-Host " [NSG]NetworkSecurityGroup " + $nsg.Name + " removed."; 
        } else 
        { 
            Write-Host " [NSG]NetworkSecurityGroup " + $nsg.Name + " is in use, skipped"; 
        } 
    } 
    
    $resourceGroups = Get-AzureRmResourceGroup; 
    foreach ($resourceGroup in $resourceGroups) 
    { 
        #clear unused AvailabilitySets 
        $avaSets = Get-AzureRmAvailabilitySet -ResourceGroupName $resourceGroup.ResourceGroupName; 
        foreach ($avaSet in $avaSets) 
        { 
            if ($avaSet.VirtualMachinesReferences.Count -eq 0) 
            { 
                Write-Host " [AvaSet]Removing unused AvailabilitySet " + $avaSet.Name + "..."; 
                if ($doActions -and $doCleanUnusedResources) 
                { 
                    Remove-AzureRmAvailabilitySet -ResourceGroupName $resourceGroup.ResourceGroupName -Name $avaSet.Name -Force; 
                } 
                Write-Host " [AvaSet]AvailabilitySet " + $avaSet.Name + " removed."; 
            } else 
            { 
                Write-Host " [AvaSet]AvailabilitySet " + $avaSet.Name + " is in use, skipped";
            } 
        } 
        
        #shutdown Vmss 
        $vmsses = Get-AzureRmVmss -ResourceGroupName $resourceGroup.ResourceGroupName; 
        foreach ($vmssName in $vmsses.Name) 
        { 
            Write-Host " [Vmss]Stopping Vmss " + $vmssName + "..."; 
            if ($doActions -and $doShutdowns) 
            { 
                Stop-AzureRmVmss -ResourceGroupName $resourceGroup.ResourceGroupName -VMScaleSetName $vmssName; 
            } 
            Write-Host " [Vmss]Vmss " + $vmssName + " stopped."; 
        } 
    } 
    
    #clear unused Disks 
    $storages = Get-AzureRmStorageAccount; 
    foreach ($storage in $storages) 
    { 
        $context = $storage.Context; 
        #get page blobs under container vhds 
        $blobs = Get-AzureStorageBlob -Context $context -Container "vhds" | where {$_.BlobType -eq "PageBlob"}; 
        foreach ($blob in $blobs) 
        { 
            if ($blob.Name.EndsWith(".vhd") -and $blob.ICloudBlob.Properties.LeaseState -eq "Available" -and $blob.ICloudBlob.Properties.LeaseStatus -eq "Unlocked") 
            { 
                Write-Host " [VHD]Removing unused VHD " + $blob.Name + "..."; 
                if ($doActions -and $doCleanUnusedResources) 
                { 
                    Remove-AzureStorageBlob -Blob $blob.Name -Container vhds -Context $context -Force; 
                } 
                Write-Host " [VHD]VHD " + $blob.Name + " removed."; 
            } else 
            { 
                Write-Host " [VHD]VHD " + $blob.Name + " is in use, skipped"; 
            } 
        } 
    } 
    
    #clear empty storages 
    foreach ($storage in $storages) 
    { 
        $context = $storage.Context; 
        #get containers 
        $containers = Get-AzureStorageContainer -Context $context; 
        
        #clear empty containers 
        foreach ($container in $containers) 
        { 
            $blobs = Get-AzureStorageBlob -Container $container.Name -Context $context; 
            if ($blobs.Count -eq 0) 
            { 
                Write-Host " [Container]Removing empty Container " + $container.Name + "..."; 
                if ($doActions -and $doCleanUnusedResources) 
                { 
                    Remove-AzureStorageContainer -Name $container.Name -Context $context -Force; 
                } 
                Write-Host " [Container]Container " + $container.Name + " removed."; 
            } else 
            { 
                Write-Host " [Container]Container " + $container.Name + " is not empty, skipped"; 
            } 
        } 
        
        #get containers 
        $containers = Get-AzureStorageContainer -Context $context; 
        if ($containers.Count -eq 0) 
        { 
            Write-Host " [Storage]Removing empty Storage " + $storage.StorageAccountName + "..."; 
            if ($doActions -and $doCleanUnusedResources) 
            { 
                Remove-AzureRmStorageAccount -ResourceGroupName $storage.ResourceGroupName -Name $storage.StorageAccountName -Force; 
            } 
            Write-Host " [Storage]Storage " + $storage.StorageAccountName + " removed."; 
        } else 
        { 
            Write-Host " [Storage]Storage " + $storage.StorageAccountName + " is not empty, skipped"; 
        } 
    } 
    
    #clear empty resourcegroups 
    $resourceGroups = Get-AzureRmResourceGroup; 
    $resources = Get-AzureRmResource; 
    foreach ($resourceGroup in $resourceGroups) 
    { 
        $resourcesInGroup = $resources | where {$_.ResourceGroupName.Equals($resourceGroup.ResourceGroupName)} 
        if ($resourcesInGroup.Count -eq 0) 
        {
            Write-Host " [ResourceGroup]Removing empty ResourceGroup " + $resourceGroup.ResourceGroupName + "..."; 
            if ($doActions -and $doCleanUnusedResources) 
            { 
                Remove-AzureRmResourceGroup -Name $resourceGroup.ResourceGroupName -Force; 
            } 
            Write-Host " [ResourceGroup]ResourceGroup " + $resourceGroup.ResourceGroupName + " removed."; 
        } else 
        { 
            Write-Host " [ResourceGroup]ResourceGroup " + $resourceGroup.ResourceGroupName + " is not empty, skipped"; 
        } 
    } 
    
    #================================================ #End# clean unused resources ================================================
}

Write-Host "Task finished..."; 




  • 86
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值