You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure VM删除或自定义脚本扩展卸载时执行自定义脚本的问题

问题描述

能否在卸载Azure VM自定义脚本扩展 或 删除VM时,执行与安装阶段不同的独立脚本?
我们的使用场景如下:

  • 扩展安装时:使用install.ps1安装软件并激活许可
  • 扩展卸载时:使用uninstall.ps1注销许可
    我们暂未找到可在扩展卸载/VM删除时自动执行清理脚本的合理方案。

以下是我们用于创建VM的Terraform示例,标注部分为我们无法正常实现的问题区域:
当前遇到的报错:

timeout - last error: http response error: 401 - invalid content type

Terraform版本信息:

Terraform v1.0.9
on windows_amd64
+ provider registry.terraform.io/hashicorp/azurerm v2.82.0

解决方案

1 修复配置错误

你当前的401和超时问题全部来自配置错误,依次修改即可:

1.1 修正自动登录XML的用户名密码错位

你当前的additional_unattend_content中把用户名和密码的取值写反了,导致自动登录失败,WinRM身份验证返回401,修改如下:

additional_unattend_content {
  setting = "AutoLogon"
  content = "<AutoLogon><Password><Value>${local.password}</Value></Password><Enabled>true</Enabled><LogonCount>1</LogonCount><Username>${local.username}</Username></AutoLogon>"
}
1.2 新增NSG的WinRM HTTP端口放行规则

你当前的NSG只放行了HTTPS的5986端口,但你用的是HTTP WinRM的5985端口,端口未开导致连接超时,新增以下规则:

resource "azurerm_network_security_rule" "AllowWinRMHTTP" {
  access                      = "Allow"
  destination_address_prefix  = "*"
  destination_port_range      = "5985"
  direction                   = "Inbound"
  name                        = "AllowWinRMHTTP"
  network_security_group_name = azurerm_network_security_group.test.name
  priority                    = 300
  protocol                    = "Tcp"
  resource_group_name         = azurerm_resource_group.test.name
  source_address_prefix       = "*" # 生产环境建议替换为运行Terraform的设备公网出口IP,降低安全风险
  source_port_range           = "*"
}
1.3 完善首次登录的WinRM配置

你当前的首次登录脚本只开了防火墙端口,没有配置WinRM服务本身,补充配置:

first_logon_script = <<-SCRIPT
  # 启用WinRM服务并完成基础配置
  winrm quickconfig -force
  # 允许非加密的HTTP连接
  winrm set winrm/config/service @{AllowUnencrypted="true"}
  # 开启基础身份验证支持
  winrm set winrm/config/service/auth @{Basic="true"}
  # 放行WinRM HTTP端口防火墙规则
  netsh advfirewall firewall add rule name=WinRM_HTTP_5985 protocol=TCP dir=in localport=5985 action=allow
SCRIPT
1.4 修正文件复制路径和执行逻辑

你当前的文件provisioner把脚本复制成了.txt后缀,后续执行.ps1文件时会找不到目标,同时指定PowerShell执行策略避免脚本被拦截:

# 复制安装脚本
provisioner "file" {
  source      = local_file.install_script.filename
  destination = "C:/install.ps1"
  when        = create
}

# 执行安装脚本
provisioner "remote-exec" {
  when   = create
  inline = ["powershell -ExecutionPolicy Bypass -File C:/install.ps1"]
}

# 复制卸载脚本
provisioner "file" {
  source      = local_file.uninstall_script.filename
  destination = "C:/uninstall.ps1"
  when        = create
}

# 销毁时执行卸载脚本
provisioner "remote-exec" {
  when   = destroy
  inline = ["powershell -ExecutionPolicy Bypass -File C:/uninstall.ps1"]
}

2 额外注意事项

  1. 如果你的Terraform是在本地运行,无法直接访问Azure VM的私有IP,需要为VM绑定公网IP,并将connection块中的host改为VM的公网IP,否则仍然会连接超时。
  2. Terraform的destroy provisioner仅在执行terraform destroy命令时触发,如果你直接在Azure门户/API中删除VM,卸载脚本不会执行。如果需要覆盖全场景的许可注销,建议搭配Azure Event Grid监听VM删除事件,触发Azure Function或自动化账户执行注销逻辑,可靠性更高。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 23:39:04