Make renewing your certificates on Windows VMs easier.

VM Key Vault Certificate Deployment

Deploy TLS certificates from Azure Key Vault to Windows VMs via the AKVVM extension and configure IIS HTTPS bindings with automatic renewal.

Usage

.\Deploy-KVCertToWinVm.ps1

On startup, the script prompts you to select:

  1. Key Vault - from all vaults in the current subscription (Out-GridView)
  2. Certificate - from the selected vault’s certificates (Out-GridView)
  3. Target VMs - from all VMs in the subscription (Out-GridView, multi-select)

Then presents an interactive menu to run each step. Steps can be run in any order, re-run safely, and errors don’t kill the session.

Prerequisites

  • Azure PowerShell (Az module) authenticated to the correct subscription
  • IIS Certificate Rebind enabled on each target VM BEFORE step 4 (installing the extension), step 3 will take care of this.

Permissions Required

Azure Key Vault has two permission layers: control plane (managing the vault) and data plane (accessing secrets inside it).

Control Plane (your identity - to run the script)

PermissionScopeWhy
ContributorVM resource groupsEnable managed identity, install extensions
User Access Administrator or OwnerKey Vault resourceAssign RBAC roles to VM MIs (RBAC vaults)
Key Vault ContributorKey Vault resourceModify access policies (access policy vaults)

Data Plane (VM managed identities - assigned by the script)

PermissionIdentityScopeWhy
Key Vault Secrets User (RBAC)Each VM’s system-assigned MIKey VaultExtension needs secrets/get to download cert
Secrets: Get (access policy)Each VM’s system-assigned MIKey VaultSame, for vaults using access policies

The script auto-detects RBAC vs access policies and assigns the correct data plane permission.

OptionDescription
1Enable Managed Identity on VMs
2Grant Key Vault Access (auto-detects RBAC vs policies)
3Check IIS Certificate Rebind status
4Install AKVVM Extension
5Verify Certificate in WebHosting store
6Discover IIS Sites and bindings
7Update HTTPS Bindings (rebind to WebHosting, enable SNI for hostname sites, update IP for catch-all sites)
8Test HTTPS (interactive hostname input)
CCheck Extension Status
VView Cert Stores on VMs
SRe-select target VMs
QQuit

Renewal Flow (fully automatic once deployed)

Cert renewed in Key Vault (new version)
  -> AKVVM extension detects on next poll (hourly)
  -> Downloads to WebHosting store
  -> Fires Event ID 1001
  -> IIS-AutoCertRebind task triggers
  -> Bindings updated to new thumbprint

Requirements for auto-renewal:

  • IIS Certificate Rebind enabled (menu option 3 checks this)
  • linkOnRenewal: true (set by default in step 4)
  • Bindings reference WebHosting store (menu option 7 ensures this)

Known Issues

IssueDetail
RBAC vs Access PoliciesScript auto-detects. Access policies ignored when RBAC enabled.
Extension v3.0 only on Server 2019v4.0 doesn’t install on 2019 or earlier
IIS Rebind must be pre-enabledWithout it, bindings won’t auto-update on renewal
Unicode in Run CommandScript uses ASCII only in remote commands
Cloudflare/CDNCan’t test backend certs externally
SNI vs IP-based bindingsStep 7 creates SNI bindings and enables SslFlags:1 on the web binding when a host header is present (Microsoft recommended). Sites without a hostname (healthcheck/catch-all) stay IP-based. Orphaned IP SSL bindings are cleaned up only if no site legitimately uses that port without a hostname.

References