You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为Azure虚拟机设置自动定时关机?避免闲置付费咨询

针对你的需求,我整理了几个实用方案,既能实现Azure VM启动后倒计时自动停止(解除分配,这样就不会产生计算费用),还支持手动延长运行时间,完美解决你不想为闲置时段付费又容易忘关机的问题:

方案1:Azure自动化账户 + 本地计时器脚本(推荐,灵活可控)

这个方案结合Azure云端的自动化能力和VM本地的交互计时器,既能保证关机逻辑可靠,又能让你直观看到剩余时间并手动延长。

步骤1:配置Azure自动化账户与关机Runbook

  • 先在Azure门户创建一个自动化账户,启用系统托管标识,并给这个标识分配虚拟机参与者权限到目标VM所在的资源组(确保它有权限停止VM)。
  • 创建一个PowerShell Runbook,功能是停止指定VM并解除分配:
param(
    [Parameter(Mandatory=$true)]
    [string]$VMName,
    [Parameter(Mandatory=$true)]
    [string]$ResourceGroupName
)

# 停止VM并解除分配(此状态下不产生计算费用)
Stop-AzVM -Name $VMName -ResourceGroupName $ResourceGroupName -Force

发布这个Runbook后,先手动测试一次,确认能正常停止你的VM。

步骤2:在Windows 10 VM上编写计时器脚本

在VM本地创建一个PowerShell脚本(比如C:\Scripts\VMRuntimeTimer.ps1),实现启动弹窗倒计时、手动延长、到期触发关机的逻辑:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# 默认设置1小时倒计时(可自行修改为7200秒=2小时)
$totalSeconds = 3600
$remainingSeconds = $totalSeconds

# 创建计时器窗口
$form = New-Object System.Windows.Forms.Form
$form.Text = "VM运行倒计时"
$form.Size = New-Object System.Drawing.Size(320,160)
$form.StartPosition = "CenterScreen"
$form.TopMost = $true

# 剩余时间显示标签
$timeLabel = New-Object System.Windows.Forms.Label
$timeLabel.Size = New-Object System.Drawing.Size(300,30)
$timeLabel.Font = New-Object System.Drawing.Font("Arial",10,[System.Drawing.FontStyle]::Bold)
$timeLabel.Text = "剩余运行时间:$([math]::Floor($remainingSeconds/3600))小时$([math]::Floor(($remainingSeconds%3600)/60))分钟"
$timeLabel.Location = New-Object System.Drawing.Point(10,15)
$form.Controls.Add($timeLabel)

# 延长30分钟按钮
$extendBtn = New-Object System.Windows.Forms.Button
$extendBtn.Text = "延长30分钟"
$extendBtn.Size = New-Object System.Drawing.Size(130,35)
$extendBtn.Location = New-Object System.Drawing.Point(10,60)
$extendBtn.Add_Click({
    $remainingSeconds += 1800
    $timeLabel.Text = "剩余运行时间:$([math]::Floor($remainingSeconds/3600))小时$([math]::Floor(($remainingSeconds%3600)/60))分钟"
})
$form.Controls.Add($extendBtn)

# 倒计时计时器
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000
$timer.Add_Tick({
    $remainingSeconds--
    if ($remainingSeconds -le 0) {
        $timer.Stop()
        $form.Close()
        # 调用Azure自动化Runbook停止VM
        $runbookName = "你的Runbook名称"
        $automationAccount = "你的自动化账户名"
        $automationRG = "自动化账户所在资源组名"
        Start-AzAutomationRunbook -AutomationAccountName $automationAccount -Name $runbookName -ResourceGroupName $automationRG -Parameters @{VMName="你的VM名称"; ResourceGroupName="VM所在资源组名"}
    } else {
        $timeLabel.Text = "剩余运行时间:$([math]::Floor($remainingSeconds/3600))小时$([math]::Floor(($remainingSeconds%3600)/60))分钟"
    }
})
$timer.Start()

$form.ShowDialog()

步骤3:设置脚本开机自启

  • 右键脚本,创建快捷方式,修改快捷方式目标为:powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\VMRuntimeTimer.ps1"
  • 把这个快捷方式放到C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp目录下,这样VM启动时会自动弹出计时器窗口。
方案2:Azure自带自动关机 + 手动延长(极简方案)

如果不需要本地弹窗,只想用Azure原生功能,可以试试这个:

  • 在Azure门户找到你的VM,进入自动关机设置,设置每天的关机时间(比如固定在每天10点关机)。但注意这个是固定时间,不是基于VM启动时间的倒计时,适合你启动时间规律的场景。
  • 如果你需要延长时间,直接在VM概览页点击取消自动关机,用完后再重新设置即可;也可以用Azure CLI命令快速操作:
# 取消自动关机
az vm auto-shutdown disable --name <你的VM名> --resource-group <资源组名>

# 重新设置自动关机(比如2小时后)
az vm auto-shutdown enable --name <你的VM名> --resource-group <资源组名> --time 120
方案3:纯本地脚本调用Azure CLI(无需自动化账户)

不想用Azure自动化账户的话,可以在VM本地安装Azure CLI,直接用脚本触发关机:

  1. 在VM上安装Azure CLI,然后用服务主体非交互式登录(避免每次手动登录):
az login --service-principal -u <服务主体ID> -p <服务主体密码> --tenant <租户ID>
  1. 修改方案1中的计时器脚本,把调用Runbook的部分替换为Azure CLI命令:
# 停止VM并解除分配
az vm deallocate --name "你的VM名" --resource-group "VM所在资源组名"
  1. 同样设置开机自启即可。

注意事项

  • 不管用哪个方案,都要确保执行关机操作的身份(托管标识/服务主体)有足够的权限停止VM,避免权限不足导致失败。
  • 用本地脚本时,建议把服务主体的凭证加密存储,不要明文写在脚本里,比如用Azure Key Vault托管凭证。

内容的提问来源于stack exchange,提问作者user2429448

火山引擎 最新活动