Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Activate Azure Benefits for Windows Arc Machines

> **Looking for SQL Server instead?** To configure the **license type for Arc-enabled SQL Server** (Paid / PAYG / LicenseOnly), use the companion sample: **[Configure Arc-enabled SQL Server license type](https://github.com/microsoft/sql-server-samples/tree/master/samples/manage/azure-arc-enabled-sql-server/compliance/arc-sql-license-type-compliance)**. This policy is for **Windows Server** machines only.

This policy activates Azure benefits for **Windows Server** machines managed by Azure Arc (`Microsoft.HybridCompute/machines`):

- **Windows Server 2025** with a **pay-as-you-go (PGS)** license → enables the pay-as-you-go product profile (ticks *Pay-as-you-go*).
- **2025 without PGS**, or **any pre-2025** Windows Server → enables **Software Assurance** (ticks *Software Assurance*).
- Only **licensed Windows Server** resources are evaluated; unlicensed servers are ignored.

> **Compliance note:** enabling Software Assurance is an attestation that the machine is covered by active Software Assurance. Only assign this where that is true for your estate.

## What's in this folder

| File | Purpose |
|---|---|
| `azurepolicy.json` | The **complete** definition, ARM-wrapped (`name`, `type`, `properties`). Use with `az` / PowerShell / pipelines. |
| `azurepolicy.rules.json` | Just the `policyRule` block. |
| `azurepolicy.parameters.json` | Just the `parameters` block. |
| `azurepolicy.portal.json` | **Portal paste** version — the `properties` contents only, ready for the portal's *Policy rule* box. |

## Choose your deployment path

### Option A — Command line / pipeline

Use the split files as-is.

**Azure CLI:**

```bash
az policy definition create \
--name "activate-azure-benefits-windows-arc" \
--display-name "Activate Azure Benefits for Windows Arc Machines" \
--rules azurepolicy.rules.json \
--params azurepolicy.parameters.json \
--mode Indexed
```

**PowerShell:**

```powershell
New-AzPolicyDefinition `
-Name "activate-azure-benefits-windows-arc" `
-DisplayName "Activate Azure Benefits for Windows Arc Machines" `
-Policy "azurepolicy.rules.json" `
-Parameter "azurepolicy.parameters.json" `
-Mode Indexed
```

Then assign and (because the effect is `DeployIfNotExists`) create a remediation task.

### Option B — Azure Portal (copy & paste)

The portal's **Policy definition → Policy rule** box expects **only the contents of `properties`**. Pasting the ARM-wrapped `azurepolicy.json` fails with:
*"Could not find member 'name' on object of type 'PolicyDefinitionProperties'."*

Steps:

1. **Policy → Definitions → + Policy definition.**
2. Set **Definition location**, **Name**, and **Category** = `Compute`.
3. Open [`azurepolicy.portal.json`](./azurepolicy.portal.json) in this folder, copy its entire contents, clear the **Policy rule** box and paste it in.
4. **Save**, then **Assign**. Because the effect is `DeployIfNotExists`, the assignment needs a **system-assigned managed identity + location** (the portal grants the Contributor role used for remediation). Create a **remediation task** for existing machines.

## Why three files, then?

The split (`rules` + `parameters`) exists for automation that consumes them separately. For the **portal**, you only ever paste the single `azurepolicy.portal.json` file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
{
"displayName": "Activate Azure Benefits for Windows Arc Machines",
"description": "Activate Azure benefits for Windows ARC Machines\n\nFor 2025 server, if license type is Pay-as-you-go, then this will check Pay-as-you-go box in license menu. If 2025 and not Pay-as-you-go license or not 2025 server then check Software Assurance box. This policy only checks Windows Server resources and will NOT check unlicensed servers",
"metadata": {
"version": "1.0.0",
"category": "Compute"
},
"mode": "Indexed",
"parameters": {
"effect": {
"type": "String",
"metadata": {
"displayName": "Effect",
"description": "DeployIfNotExists, AuditIfNotExists or Disabled the execution of the Policy"
},
"allowedValues": [
"DeployIfNotExists",
"AuditIfNotExists",
"Disabled"
],
"defaultValue": "DeployIfNotExists"
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.HybridCompute/machines"
},
{
"field": "Microsoft.HybridCompute/machines/osType",
"equals": "windows"
},
{
"field": "Microsoft.HybridCompute/machines/licenseProfile.licenseStatus",
"equals": "Licensed"
}
]
},
"then": {
"effect": "[parameters('effect')]",
"details": {
"type": "Microsoft.HybridCompute/machines",
"name": "[field('name')]",
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
],
"existenceCondition": {
"anyOf": [
{
"allOf": [
{
"field": "Microsoft.HybridCompute/machines/osSku",
"contains": "2025"
},
{
"field": "Microsoft.HybridCompute/machines/licenseProfile.licenseChannel",
"contains": "PGS"
},
{
"anyOf": [
{
"field": "Microsoft.HybridCompute/machines/licenseProfile.productProfile.subscriptionStatus",
"equals": "Enabled"
},
{
"field": "Microsoft.HybridCompute/machines/licenseProfile.productProfile.productFeatures[*].subscriptionStatus",
"equals": "Enabled"
}
]
}
]
},
{
"allOf": [
{
"field": "Microsoft.HybridCompute/machines/osSku",
"contains": "2025"
},
{
"not": {
"field": "Microsoft.HybridCompute/machines/licenseProfile.licenseChannel",
"contains": "PGS"
}
},
{
"field": "Microsoft.HybridCompute/machines/licenseProfile.softwareAssurance.softwareAssuranceCustomer",
"equals": true
}
]
},
{
"allOf": [
{
"not": {
"field": "Microsoft.HybridCompute/machines/osSku",
"contains": "2025"
}
},
{
"field": "Microsoft.HybridCompute/machines/licenseProfile.softwareAssurance.softwareAssuranceCustomer",
"equals": true
}
]
}
]
},
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vmName": {
"type": "string"
},
"location": {
"type": "string"
},
"osSku": {
"type": "string"
},
"licenseChannel": {
"type": "string"
},
"status": {
"type": "string"
},
"productType": {
"type": "string"
}
},
"resources": [
{
"condition": "[and(equals(parameters('status'), 'Connected'), contains(parameters('licenseChannel'), 'PGS'))]",
"name": "[concat(parameters('vmName'), '/default')]",
"type": "Microsoft.HybridCompute/machines/licenseProfiles",
"location": "[parameters('location')]",
"apiVersion": "2025-01-13",
"properties": {
"productProfile": {
"productType": "[parameters('productType')]",
"subscriptionStatus": "Enabled"
}
}
},
{
"condition": "[and(equals(parameters('status'), 'Connected'), not(contains(parameters('licenseChannel'), 'PGS')))]",
"name": "[concat(parameters('vmName'), '/default')]",
"type": "Microsoft.HybridCompute/machines/licenseProfiles",
"location": "[parameters('location')]",
"apiVersion": "2025-01-13",
"properties": {
"softwareAssurance": {
"softwareAssuranceCustomer": true
}
}
}
],
"outputs": {
"policy": {
"type": "string",
"value": "[concat('Enabled Software Assurance for VM', ': ', parameters('vmName'))]"
}
}
},
"parameters": {
"vmName": {
"value": "[field('name')]"
},
"location": {
"value": "[field('location')]"
},
"osSku": {
"value": "[field('Microsoft.HybridCompute/machines/osSku')]"
},
"licenseChannel": {
"value": "[field('Microsoft.HybridCompute/machines/licenseProfile.licenseChannel')]"
},
"status": {
"value": "[field('Microsoft.HybridCompute/machines/status')]"
},
"productType": {
"value": "[field('Microsoft.HybridCompute/machines/licenseProfile.productProfile.productType')]"
}
}
}
}
}
}
}
}
Loading