简体   繁体   中英

Azure ARM Template - Running DSC script without triggering extension install?

I am trying to deploy a Active Directory forest with two DCs. I've managed to deploy the DCs and install the ADDS features on both VMs. The "PDC" had a DSC script that runs and configures the forest, again that works great. The issue I have is trying to run a second DSC script on the second DC, this script runs the ADDS configuration to promote the VM to a DC and join it to the forest. I've created a nested JSON template that gets called by the main template. But I am hitting this error:

"Multiple VMExtensions per handler not supported for OS type 'Windows'. VMExtension 'PrepareBDC' with handler 'Microsoft.Powershell.DSC' already added or specified in input."

I've spent the last hour or so whizzing around the internet looking for answers and everyone seems to say the same thing...you can't install the same extension twice. Ok, I can see why that would make sense, my question is can I configure the nested template so it doesn't try and install the extension, just uses what's already installed on the VM?

Main template snippet:

{
    "type": "Microsoft.Compute/virtualMachines/extensions",
    "name": "[concat(variables('dc2name'), '/PrepareDC2AD')]",
    "apiVersion": "2018-06-01",
    "location": "[resourceGroup().location]",
    "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachines', variables('dc2name'))]"
    ],
    "properties": {
        "publisher": "Microsoft.Powershell",
        "type": "DSC",
        "typeHandlerVersion": "2.19",
        "autoUpgradeMinorVersion": true,
        "settings": {
            "ModulesUrl": "[concat(parameters('Artifacts Location'), '/dsc/PrepareADBDC.zip', parameters('Artifacts Location SAS Token'))]",
            "ConfigurationFunction": "PrepareADBDC.ps1\\PrepareADBDC",
            "Properties": {
                "DNSServer": "[variables('dc1ipaddress')]"
            }
        }
    }
},
{
    "name": "ConfiguringDC2",
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2016-09-01",
    "dependsOn": [
        "[concat('Microsoft.Compute/virtualMachines/',variables('dc1name'),'/extensions/CreateADForest')]",
        "[concat('Microsoft.Compute/virtualMachines/',variables('dc2name'),'/extensions/PrepareDC2AD')]"
    ],
    "properties": {
        "mode": "Incremental",
        "templateLink": {
            "uri": "[concat(parameters('Artifacts Location'), '/nestedtemplates/configureADBDC.json', parameters('Artifacts Location SAS Token'))]",
            "contentVersion": "1.0.0.0"
        },
        "parameters": {
            "adBDCVMName": {
                "value": "[variables('dc2name')]"
            },
            "location": {
                "value": "[resourceGroup().location]"
            },
            "adminUsername": {
                "value": "[parameters('Administrator User')]"
            },
            "adminPassword": {
                "value": "[parameters('Administrator Password')]"
            },
            "domainName": {
                "value": "[parameters('Domain Name')]"
            },
            "adBDCConfigurationFunction": {
                "value": "ConfigureADBDC.ps1\\ConfigureADBDC"
            },
            "adBDCConfigurationModulesURL": {
                "value": "[concat(parameters('Artifacts Location'), '/dsc/ConfigureADBDC.zip', parameters('Artifacts Location SAS Token'))]"
            }
        }
    }
},

The nested template:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "adBDCVMName": {
            "type": "string"
        },
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]"
        },
        "adminUsername": {
            "type": "string"
        },
        "adminPassword": {
            "type": "securestring"
        },
        "domainName": {
            "type": "string"
        },
        "adBDCConfigurationFunction": {
            "type": "string"
        },
        "adBDCConfigurationModulesURL": {
            "type": "string"
        }
    },
    "resources": [
        {
            "type": "Microsoft.Compute/virtualMachines/extensions",
            "name": "[concat(parameters('adBDCVMName'),'/PrepareBDC')]",
            "apiVersion": "2016-03-30",
            "location": "[parameters('location')]",
            "properties": {
                "publisher": "Microsoft.Powershell",
                "type": "DSC",
                "typeHandlerVersion": "2.21",
                "autoUpgradeMinorVersion": true,
                "forceUpdateTag": "1.0",
                "settings": {
                    "modulesURL": "[parameters('adBDCConfigurationModulesURL')]",
                    "wmfVersion": "4.0",
                    "configurationFunction": "[parameters('adBDCConfigurationFunction')]",
                    "properties": {
                        "domainName": "[parameters('domainName')]",
                        "adminCreds": {
                            "userName": "[parameters('adminUsername')]",
                            "password": "privateSettingsRef:adminPassword"
                        }
                    }
                },
                "protectedSettings": {
                    "items": {
                        "adminPassword": "[parameters('adminPassword')]"
                    }
                }
            }
        }
    ]
}

this error means exactly what it says: you cannot have multiple copies of the same extension, what you need to do is apply the same extension to the vm, all the inputs have to be the same. you can have a look at this example which does exactly that. This particular template installs the extension for the second time to join bdc to the domain.

But, I don't like that approach. I use Powershell DSC to just wait for the domain to get created and join the bdc to the domain in one go. you would use this powershell dsc snippet:

xWaitForADDomain DscForestWait {
    DomainName           = $DomainName
    DomainUserCredential = $DomainCreds
    RetryCount           = $RetryCount
    RetryIntervalSec     = $RetryIntervalSec
}

Here's a complete example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM