30 天后自动终止 Azure VM

Terminate Azure VM after 30 days automatically

我今天 activity 我在 Azure 中创建了测试虚拟机,然后将其删除。由于某种原因,这次我打算创建100个测试vms,我想实现一个调度机制(通过powershell或AzureRunbook),以便创建的服务器可以在30天后自动删除...

问题是我可以使用 Powershell 找到云服务的创建日期,但不能找到 VM 的创建日期。很少有云服务包含我不想删除的旧虚拟机。

我正在考虑 vm 的不同命名约定,以便我可以将其用于删除时间使用-

if($vm.name -like "mypattern*")
{
     $out1 = $vm.Name
     $out2 = $vm.ServiceName
     Remove-AzureVM -Name $out1 -ServiceName $out2 -DeleteVHD
     sleep -Seconds 60
 } 

我相信除了这个之外肯定还有更多的方法。有什么可以替代的选择。我更喜欢powershell。

这里 https://social.msdn.microsoft.com/forums/azure/en-US/3da7750a-1a7d-4c62-b58a-a4b427b2520d/get-azure-vm-creationprovision-date 以前有人问过类似的问题。

简而言之,使用 PowerShell,您可以检查附加到 VM 的 VHD 的名称(仅当您从映像创建 VM 时才如此)。从 VHD 名称可以确定相关 VM 的创建时间。

运行 以下 cmdlet 获取 VHD 名称:

Get-AzureVM <cloud service name> <VM name> | Get-AzureOSDisk | select medialink.

作为 PowerShell 的替代品,您还可以使用 Microsoft Azure Management Libraries 获取云服务和虚拟机相关信息。但是,此方法不会带来任何附加信息。

请参阅 https://github.com/kimpihlstrom/azure/tree/master/Azure.Management.ListHostedServices 作为用法示例以及可以获得哪些信息。

目前除了从 VHD 的文件名中提取 VM 的创建日期外,似乎没有任何其他方法可以获取 VM 的创建日期,这仅在某些情况下才有可能。

您可以通过为它们添加标签来找到您正在搜索的虚拟机。

在 Azure Powershell 中,您可以添加资源管理器 Cmdlet Install-Module AzureRM Install-AzureRM

https://msdn.microsoft.com/en-us/library/azure/mt125356.aspx

这是一篇来自 Microsoft 的关于标记 VM 的完整文章(Powershell 在底部)

https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-tagging-arm/

然后当你创建这100个测试虚拟机的时候。一定要在那时标记它们,因为在创建时你会知道哪个是哪个。 使用 Set-AzureResource

$tags =@{Name="LaunchDate";Value="09-01-2015"}

Set-AzureResource -Name MyWindowsVM -ResourceGroupName MyResourceGroup -ResourceType "Microsoft.Compute/VirtualMachines" -ApiVersion 2015-05-01-preview -Tag $tags

您可能想查看 Azure DevTest Labs。我没有找到太多关于它的文档,但是 link 提供的功能之一是能够 设置自动关闭以最小化成本

根据我所了解的情况,您正在尝试查找虚拟机的创建日期。有问题的虚拟机是 "Classic" 个虚拟机,这意味着它们被部署到云服务容器,而不是通过 Azure 资源管理器创建。一些 VM 已经创建,一些将由您的脚本创建。一些云服务容器也已经存在了一段时间,有些可能更新。

我无法通过服务管理找到检索虚拟机创建日期的方法API;然而,如果我们能够到达实际的虚拟机,那么我们还有更多的事情要做。下面的脚本假定 VM 创建日期与 VM 上的 OS 安装日期相同(我认为这应该是一个很好的指标,我验证了它不是源图像的日期,而是VM 创建的日期)。为此,您需要在 VM 上启用 PowerShell 远程端点,这在您创建 VM 时默认存在,并且您必须 运行 本地管理员权限下的脚本,因为它会混淆证书存储。

$remoteCreds = Get-Credential
$maxVMAgeInDays = 30
#Classic VMs
Get-AzureVM | ForEach-Object { 
    #Need to ensure we have the self-signed VM certificate installed to authenticate and secure the connection.
    $winRmCertThumbprint = $_.Vm.DefaultWinRmCertificateThumbprint 
    $certPath = "Cert:\LocalMachine\Root$winRmCertThumbprint"
    if (!(Test-Path -Path $certPath)){
        #Cert for VM isn't found, importing.
        $winRmCert = Get-AzureCertificate -ServiceName $_.ServiceName -Thumbprint $winRmCertThumbprint -ThumbprintAlgorithm sha1

        $certTempFile = [IO.Path]::GetTempFileName()
        $winRmCert.Data | Out-File $certTempFile

        # Target The Cert That Needs To Be Imported
        $CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile

        $store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
        $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
        $store.Add($CertToImport)
        $store.Close()

        "Imported cert: $certPath"

        #clean up temp file
        Remove-Item $certTempFile
    } 

    #Retrieve the powerShell Remote port for this machine.
    $remoteUri = Get-AzureWinRMUri -ServiceName $_.ServiceName -Name $_.Name

    $osInstallDate = Invoke-Command -ConnectionUri $remoteUri -Credential $remoteCreds -ScriptBlock { ([WMI]'').ConvertToDateTime((Get-WmiObject Win32_OperatingSystem).InstallDate)  }

    $vmAgeInDays = (New-TimeSpan -Start $osInstallDate  -End (Get-Date)).Days
    if ($vmAgeInDays -gt $maxVMAgeInDays) {
        "$($_.Name) VM in $($_.ServiceName) cloud service is older than $maxVMAgeInDays ... you can remove it."
        #Add your code to remove the VM
    } else {
        "$($_.Name) VM in $($_.ServiceName) cloud service is only $($vmAgeInDays) old."        
        #Do soemthing else or just remove the else.
    }
}

该脚本假定您已经执行了 Add-AzureAccount 并选择了您要使用的订阅。它将提示您输入 VM 的凭据,此特定脚本假设您拥有一个已设置为适用于每个 VM 的凭据。这可以是您在创建 VM 时提供的凭据,也可以是您之后添加到每个 VM 的正确权限的凭据。由于您说的是通过脚本创建 100 多个虚拟机,我猜它们都将拥有相同的管理员凭据。对于您现有的虚拟机,您可能必须手动向它们添加帐户(这可能会很痛苦,具体取决于您拥有的虚拟机数量)。

该脚本遍历每个 VM 并检查本地计算机上是否加载了 WinRM 证书。如果没有,它将把它拉下来并安装它。这是保护远程 PowerShell 会话所必需的。我从 Michael Washam's script on TechNet 中获取了代码。

在我们知道我们有证书来保护连接后,他们执行远程 PowerShell 命令来检索 OS 安装日期(我在 ScioSoft blog 上找到的提示)。最后,它会根据该日期检查 VM 的年龄,然后可以执行您希望它执行的任何操作。在您的情况下,您可以删除它。您需要确保在删除 VM 时也清理了底层磁盘等,如果您真的想清理的话。

最后,为了改进我建议您删除的任何 VM 的脚本,您可以通过指纹删除证书来清理您的证书存储。

这将适用于经典 VM,听起来您已经拥有了。有人已经为您提供了一种通过标记来处理基于 ARM 的 VM 的方法,这将消除实际处理远程命令的需要。