Extension de script personnalisé pour Windows

L’extension de script personnalisé télécharge et exécute des scripts sur des machines virtuelles Azure. Utilisez cette extension pour la configuration post-déploiement, l’installation de logiciels ou toute autre tâche de configuration ou de gestion. Vous pouvez télécharger des scripts à partir du Stockage Azure ou de GitHub, ou les fournir au portail Azure au moment de l’exécution de l’extension.

L’extension de script personnalisé est compatible avec les modèles Azure Resource Manager. Vous pouvez aussi l’exécuter avec Azure CLI, Azure PowerShell, le portail Azure et l’API REST Machines virtuelles Azure.

Cet article explique comment utiliser l’extension de script personnalisé à partir du module Azure PowerShell et des modèles Azure Resource Manager. Il fournit également des étapes de résolution de problèmes pour les systèmes Windows.

Prérequis

Notes

N’utilisez pas l’extension de script personnalisé pour exécuter Update-AzVM avec la même machine virtuelle comme paramètre. L’extension s’attend elle-même.

Systèmes d’exploitation Windows pris en charge

Système d’exploitation Windows x64
Windows 10 Prise en charge
Windows 11 Prise en charge
Windows Server 2008 SP2 Prise en charge
Windows Server 2008 R2 Prise en charge
Windows Server 2012 Prise en charge
Windows Server 2012 R2 Prise en charge
Windows Server 2016 Prise en charge
Windows Server 2016 Core Prise en charge
Windows Server 2019 Prise en charge
Windows Server 2019 Core Prise en charge
Windows Server 2022 Prise en charge
Windows Server 2022 Core Prise en charge

Emplacement du script

Vous pouvez définir l’extension pour utiliser vos informations d’identification de Stockage Blob Azure afin d’accéder au Stockage Blob Azure. Le script peut être placé n’importe où, tant que la machine virtuelle peut router le trafic vers ce point de terminaison, par exemple, GitHub ou un serveur de fichiers interne.

Connectivité Internet

Pour télécharger un script en externe, par exemple, à partir de GitHub ou du Stockage Azure, vous devez ouvrir d’autres ports de pare-feu ou de groupe de sécurité réseau (NSG). Par exemple, si votre script se trouve dans le Stockage Azure, vous pouvez autoriser l’accès en utilisant des étiquettes de service de NSG Azure pour le stockage.

L’extension de script personnalisé n’a aucun moyen de contourner la validation du certificat. Si vous effectuez le téléchargement à partir d’un emplacement sécurisé avec, par exemple, un certificat auto-signé, vous risquez d’obtenir des erreurs du type Le certificat distant n’est pas valide selon la procédure de validation. Assurez-vous que le certificat est correctement installé dans le magasin Autorités de certification racines de confiance sur la machine virtuelle.

Si votre script se trouve sur un serveur local, vous devez peut-être encore ouvrir d’autres ports NSG ou de pare-feu.

Conseils

  • La sortie est limitée aux derniers 4 096 octets.
  • Échapper correctement les caractères permettra de garantir que les chaînes sont correctement analysées. Par exemple, vous avez toujours besoin de deux barres obliques inverses pour échapper à une seule barre oblique inverse littérale lorsque vous traitez des chemins de fichiers. Exemple : {"commandToExecute": "C:\\Windows\\System32\\systeminfo.exe >> D:\\test.txt"}
  • Le taux d’échec le plus élevé pour cette extension est dû à des erreurs de syntaxe dans le script. Vérifiez que le script s’exécute sans erreur. Ajoutez de la journalisation supplémentaire dans le script pour faciliter la recherche des échecs.
  • Écrivez des scripts idempotents, pour que même si vous les exécutez plusieurs fois par inadvertance, aucun changement ne se produise sur le système.
  • Vérifiez que l’exécution des scripts ne nécessite pas d’entrée utilisateur.
  • La durée d’exécution autorisée du script est 90 minutes. Toute opération dépassant cette durée entraîne l’échec du provisionnement de l’extension.
  • Ne placez pas de redémarrages à l’intérieur du script. Cette action entraîne des problèmes avec d’autres extensions en cours d’installation, et l’extension ne continue pas après le redémarrage.
  • Si vous avez un script qui doit déclencher un redémarrage avant d’installer des applications et d’exécuter des scripts, planifiez le redémarrage en utilisant une tâche planifiée Windows ou des outils comme les extensions DSC, Chef ou Puppet.
  • N’exécutez pas de script pouvant provoquer l’arrêt ou la mise à jour de l’agent de machine virtuelle. Ce type de script peut laisser l’extension dans un état de transition et entraîner l’expiration du délai d’attente.
  • L’extension exécute une seule fois un script. Si vous voulez exécuter un script à chaque démarrage, utilisez l’extension pour créer une tâche planifiée Windows.
  • Si vous souhaitez planifier l’exécution d’un script, utilisez l’extension pour créer une tâche planifiée Windows.
  • Lors de l’exécution du script, vous voyez seulement l’état de l’extension transition en cours dans le portail Azure ou l’interface Azure CLI. Si vous voulez des mises à jour plus fréquentes de l’état d’un script en cours d’exécution, créez votre propre solution.
  • L’extension de script personnalisé ne prend pas en charge en mode natif les serveurs proxy. Toutefois, vous pouvez utiliser un outil de transfert de fichiers, comme Invoke-WebRequest, qui prend en charge les serveurs proxy au sein de votre script.
  • Tenez compte du fait que vos scripts ou commandes sont susceptibles d’utiliser des emplacements de répertoire autres que ceux par défaut. Gérez cette situation en suivant une logique.
  • L’extension de script personnalisé s’exécute sous le compte LocalSystem.
  • Si vous voulez utiliser les propriétés storageAccountName et storageAccountKey, ces propriétés doivent être colocalisées dans protectedSettings.
  • Vous pouvez appliquer seulement une version d’une extension à la machine virtuelle. Pour exécuter un deuxième script personnalisé, vous pouvez mettre à jour l’extension existante avec une nouvelle configuration. Sinon, vous pouvez supprimer l’extension de script personnalisé et la réappliquer avec le script mis à jour

Schéma d’extensions

La configuration de l’extension de script personnalisé spécifie des éléments tels que l’emplacement du script et la commande à exécuter. Cette configuration peut être stockée dans des fichiers de configuration, ou spécifiée en ligne de commande ou dans un modèle Azure Resource Manager.

Les données sensibles peuvent être stockées dans une configuration protégée qui n’est chiffrée et déchiffrée qu’à l’intérieur de la machine virtuelle. La configuration protégée est utile quand la commande d’exécution comprend des secrets, comme un mot de passe ou une référence à un fichier de signature d’accès partagé (SAS). Voici un exemple :

{
    "apiVersion": "2018-06-01",
    "type": "Microsoft.Compute/virtualMachines/extensions",
    "name": "virtualMachineName/config-app",
    "location": "[resourceGroup().location]",
    "dependsOn": [
        "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'),copyindex())]",
        "[variables('musicstoresqlName')]"
    ],
    "tags": {
        "displayName": "config-app"
    },
    "properties": {
        "publisher": "Microsoft.Compute",
        "type": "CustomScriptExtension",
        "typeHandlerVersion": "1.10",
        "autoUpgradeMinorVersion": true,
        "settings": {
            "timestamp":123456789
        },
        "protectedSettings": {
            "commandToExecute": "myExecutionCommand",
            "storageAccountName": "myStorageAccountName",
            "storageAccountKey": "myStorageAccountKey",
            "managedIdentity" : {},
            "fileUris": [
                "script location"
            ]
        }
    }
}

Notes

La propriété managedIdentityne doit pas être utilisée conjointement avec la propriété storageAccountName ou storageAccountKey.

Une seule version d’une extension peut être installée à la fois sur une machine virtuelle. La spécification d’un script personnalisé à deux reprises dans le même modèle Azure Resource Manager pour la même machine virtuelle échoue.

Nous pouvons utiliser ce schéma au sein de la ressource VM ou comme ressource autonome. Si cette extension est utilisée comme ressource autonome dans le modèle Azure Resource Manager, le nom de la ressource doit être au format nom_machine_virtuelle/nom_extension.

Valeurs de propriétés

Nom Valeur ou exemple Type de données
apiVersion 2015-06-15 Date
publisher Microsoft.Compute string
type CustomScriptExtension string
typeHandlerVersion 1.10 int
fileUris https://raw.githubusercontent.com/Microsoft/dotnet-core-sample-templates/master/dotnet-core-music-windows/scripts/configure-music-app.ps1 tableau
timestamp 123456789 Entier de 32 bits
commandToExecute powershell -ExecutionPolicy Unrestricted -File configure-music-app.ps1 string
storageAccountName examplestorageacct string
storageAccountKey TmJK/1N3AbAZ3q/+hOXoi/l73zOqsaxXDhqa9Y83/v5UpXQp2DQIBuv2Tifp60cE/OaHsJZmQZ7teQfczQj8hg== string
managedIdentity { } ou { "clientId": "31b403aa-c364-4240-a7ff-d85fb6cd7232" } ou { "objectId": "12dd289c-0583-46e5-b9b4-115d5c19ef4b" } Objet JSON

Notes

Ces noms de propriétés respectent la casse. Pour éviter des problèmes de déploiement, utilisez les noms présentés ici.

Détails des valeurs de propriété

Propriété Facultatif ou obligatoire Détails
fileUris Facultatif URL des fichiers à télécharger. Si les URL sont sensibles, par exemple, si elles contiennent des clés, ce champ doit être spécifié dans protectedSettings.
commandToExecute Obligatoire Script de point d’entrée à exécuter. Utilisez cette propriété si votre commande contient des secrets comme des mots de passe ou si vos URI de fichier sont sensibles.
timestamp Facultatif Changez cette valeur uniquement pour déclencher une réexécution du script. Toute valeur entière est acceptable, à condition qu’elle soit différente de la valeur précédente.
storageAccountName Facultatif Nom du compte de stockage. Si vous spécifiez des informations d’identification de stockage, toutes les valeurs fileUris doivent être des URL de blobs Azure.
storageAccountKey Facultatif Clé d’accès du compte de stockage.
managedIdentity Facultatif Identité managée pour le téléchargement de fichiers. Les valeurs valides sont clientId (facultatif, chaîne), qui correspond à l’ID client de l’identité managée, et objectId (facultatif, chaîne), qui correspond à l’ID d’objet de l’identité managée.

Les paramètres publics sont envoyés en texte clair à la machine virtuelle sur laquelle le script est exécuté. Les paramètres protégés sont chiffrés avec une clé connue uniquement d’Azure et de la machine virtuelle. Les paramètres sont enregistrés sur la machine virtuelle quand ils sont envoyés. Autrement dit, si les paramètres sont chiffrés, ils sont enregistrés chiffrés sur la machine virtuelle. Le certificat utilisé pour déchiffrer les valeurs chiffrées est stocké sur la machine virtuelle. Le certificat est également utilisé pour déchiffrer les paramètres, si nécessaire, au moment de l’exécution.

L’utilisation de paramètres publics peut être utile pour le débogage, mais nous vous recommandons d’utiliser des paramètres protégés.

Vous pouvez définir les valeurs suivantes dans des paramètres public ou protégés. L’extension rejette toutes les configurations où ces valeurs sont définies dans des paramètres publics et protégés.

  • commandToExecute
  • fileUris

Propriété : managedIdentity

Notes

Cette propriété doit uniquement être spécifiée dans les paramètres protégés.

L’extension de script personnalisé, version 1.10 et ultérieure, prend en charge les identités managées pour le téléchargement de fichiers à partir des URL fournies dans le paramètre fileUris. La propriété permet à l’extension de script personnalisé d’accéder aux blobs ou conteneurs privés de Stockage Azure sans que l’utilisateur transmette des secrets, comme des jetons SAP ou des clés de compte de stockage.

Pour utiliser cette fonctionnalité, ajoutez une identité affectée par le système ou attribuée par l’utilisateur à la machine virtuelle ou au groupe de machines virtuelles identiques où l’extension de script personnalisé s’exécute. Ensuite, accordez à l’identité managée l’accès au conteneur ou au blob Stockage Azure.

Pour utiliser l’identité affectée par le système sur la machine virtuelle ou le groupe de machines virtuelles identiques cible, définissez managedidentity sur un objet JSON vide.

{
  "fileUris": ["https://mystorage.blob.core.windows.net/privatecontainer/script1.ps1"],
  "commandToExecute": "powershell.exe script1.ps1",
  "managedIdentity" : {}
}

Pour utiliser l’identité attribuée par l’utilisateur sur la machine virtuelle ou le groupe de machines virtuelles identiques cible, configurez managedidentity avec l’ID client ou l’ID d’objet de l’identité managée.

{
  "fileUris": ["https://mystorage.blob.core.windows.net/privatecontainer/script1.ps1"],
  "commandToExecute": "powershell.exe script1.ps1",
  "managedIdentity" : { "clientId": "31b403aa-c364-4240-a7ff-d85fb6cd7232" }
}
{
  "fileUris": ["https://mystorage.blob.core.windows.net/privatecontainer/script1.ps1"],
  "commandToExecute": "powershell.exe script1.ps1",
  "managedIdentity" : { "objectId": "12dd289c-0583-46e5-b9b4-115d5c19ef4b" }
}

Notes

La propriété managedIdentityne doit pas être utilisée conjointement avec la propriété storageAccountName ou storageAccountKey.

Déploiement de modèle

Vous pouvez déployer des extensions VM Azure avec des modèles Azure Resource Manager. Le schéma JSON détaillé dans la section précédente peut être utilisé dans un modèle Azure Resource Manager pour exécuter l’extension de script personnalisé pendant le déploiement du modèle. Les exemples suivants montrent comment utiliser l’extension de script personnalisé :

Déploiement PowerShell

Vous pouvez utiliser la commande Set-AzVMCustomScriptExtension pour ajouter l’extension de script personnalisé sur une machine virtuelle existante. Pour plus d’informations, consultez Set-AzVMCustomScriptExtension.

Set-AzVMCustomScriptExtension -ResourceGroupName <resourceGroupName> `
    -VMName <vmName> `
    -Location myLocation `
    -FileUri <fileUrl> `
    -Run 'myScript.ps1' `
    -Name DemoScriptExtension

Exemples

Utilisation de plusieurs scripts

Cet exemple utilise trois scripts pour générer votre serveur. La propriété commandToExecute appelle le premier script. Vous avez ensuite plusieurs options pour appeler les autres scripts. Par exemple, vous pouvez avoir un script principal qui contrôle l’exécution, avec la gestion des erreurs, la journalisation et la gestion de l’état appropriées. Les scripts sont téléchargés sur l’ordinateur local pour l’exécution.

Par exemple, dans 1_Add_Tools.ps1, vous appelez 2_Add_Features.ps1 en ajoutant .\2_Add_Features.ps1 au script. Répétez ce processus pour les autres scripts que vous définissez dans $settings.

$fileUri = @("https://xxxxxxx.blob.core.windows.net/buildServer1/1_Add_Tools.ps1",
"https://xxxxxxx.blob.core.windows.net/buildServer1/2_Add_Features.ps1",
"https://xxxxxxx.blob.core.windows.net/buildServer1/3_CompleteInstall.ps1")

$settings = @{"fileUris" = $fileUri};

$storageAcctName = "xxxxxxx"
$storageKey = "1234ABCD"
$protectedSettings = @{"storageAccountName" = $storageAcctName; "storageAccountKey" = $storageKey; "commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File 1_Add_Tools.ps1"};

#run command
Set-AzVMExtension -ResourceGroupName <resourceGroupName> `
    -Location <locationName> `
    -VMName <vmName> `
    -Name "buildserver1" `
    -Publisher "Microsoft.Compute" `
    -ExtensionType "CustomScriptExtension" `
    -TypeHandlerVersion "1.10" `
    -Settings $settings `
    -ProtectedSettings $protectedSettings;

Exécution de scripts à partir d’un partage local

Dans cet exemple, vous pouvez utiliser un serveur SMB (Server Message Block) local pour l’emplacement de votre script. Vous n’avez alors pas besoin de fournir d’autres paramètres, à l’exception de commandToExecute.

$protectedSettings = @{"commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File \\filesvr\build\serverUpdate1.ps1"};

Set-AzVMExtension -ResourceGroupName <resourceGroupName> `
    -Location <locationName> `
    -VMName <vmName> `
    -Name "serverUpdate"
    -Publisher "Microsoft.Compute" `
    -ExtensionType "CustomScriptExtension" `
    -TypeHandlerVersion "1.10" `
    -ProtectedSettings $protectedSettings

Exécution d’un script personnalisé plusieurs fois en utilisant l’interface CLI

Le gestionnaire d’extensions de script personnalisé empêche la réexécution d’un script si les mêmes paramètres exactement ont été passés. Ce comportement empêche la réexécution accidentelle, qui peut entraîner des comportements inattendus si le script n’est pas idempotent. Pour vérifier si le gestionnaire a bloqué la réexécution, examinez C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\<HandlerVersion>\CustomScriptHandler.log*. Recherche d’un avertissement comme celui-ci :

Current sequence number, <SequenceNumber>, is not greater than the sequence number
of the most recently executed configuration. Exiting...

Si vous voulez exécuter plusieurs fois l’extension de script personnalisé, vous pouvez le faire seulement dans les conditions suivantes :

  • Le paramètre Name de l’extension est le même que pour le déploiement précédent de l’extension.
  • Vous avez mis à jour la configuration. Vous pouvez ajouter une propriété dynamique dans la commande, comme un horodatage. Si le gestionnaire détecte un changement dans les paramètres de configuration, il le considère comme une volonté explicite de réexécuter le script.

Vous pouvez également définir la propriété ForceUpdateTag sur true.

Utilisation d’Invoke-WebRequest

Si vous utilisez Invoke-WebRequest dans votre script, vous devez spécifier le paramètre -UseBasicParsing. Si vous ne spécifiez pas le paramètre, vous obtenez l’erreur suivante pendant la vérification de l’état détaillé :

The response content cannot be parsed because the Internet Explorer engine
is not available, or Internet Explorer's first-launch configuration
is not complete. Specify the UseBasicParsing parameter and try again.

Virtual Machine Scale Sets

Si vous déployez l’extension de script personnalisé à partir du portail Azure, vous ne contrôlez pas l’expiration du jeton SAS pour accéder au script dans votre compte de stockage. Le déploiement initial fonctionne, mais quand le jeton SAP du compte de stockage expire, toute opération de mise à l’échelle ultérieure échoue, car l’extension de script personnalisé ne peut plus accéder au compte de stockage.

Nous vous recommandons d’utiliser PowerShell, Azure CLI ou un modèle Azure Resource Manager quand vous déployez l’extension de script personnalisé sur un groupe de machines virtuelles identiques. De cette façon, vous pouvez choisir d’utiliser une identité managée ou de contrôler directement l’expiration du jeton SAS pour accéder au script dans votre compte de stockage aussi longtemps que nécessaire.

Dépannage et support technique

Vous pouvez récupérer les données sur l’état des déploiements d’extension à partir du portail Azure et du module Azure PowerShell. Pour voir l’état du déploiement des extensions sur une machine virtuelle, exécutez la commande suivante :

Get-AzVMExtension -ResourceGroupName <resourceGroupName> `
    -VMName <vmName> -Name myExtensionName

La sortie de l’extension est journalisée dans les fichiers qui se trouvent dans le dossier suivant sur la machine virtuelle cible :

C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension

Les fichiers spécifiés sont téléchargés dans le dossier suivant sur la machine virtuelle cible :

C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.*\Downloads\<n>

Dans le chemin précédent, <n> est un entier décimal qui peut changer entre les exécutions de l’extension. La valeur 1.* correspond à la valeurtypeHandlerVersion actuelle et réelle de l’extension. Par exemple, le répertoire réel peut être C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.8\Downloads\2.

Quand vous exécutez la commande commandToExecute, l’extension définit ce répertoire, par exemple, ...\Downloads\2, comme répertoire de travail actif. Ce processus permet d’utiliser des chemins relatifs pour localiser les fichiers téléchargés à l’aide de la propriété fileURIs. Voici des exemples de fichiers téléchargés :

URI dans fileUris Emplacement de téléchargement relatif Emplacement de téléchargement absolu
https://someAcct.blob.core.windows.net/aContainer/scripts/myscript.ps1 ./scripts/myscript.ps1 C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.8\Downloads\2\scripts\myscript.ps1
https://someAcct.blob.core.windows.net/aContainer/topLevel.ps1 ./topLevel.ps1 C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.8\Downloads\2\topLevel.ps1

Les chemins absolus de répertoire évoluent pendant la durée de vie de la machine virtuelle, mais pas au sein d’une même exécution de l’extension de script personnalisé.

Comme le chemin de téléchargement absolu peut varier au fil du temps, optez plutôt pour des chemins de script/fichier relatifs dans la chaîne commandToExecute, si possible. Par exemple :

"commandToExecute": "powershell.exe . . . -File \"./scripts/myscript.ps1\""

Les informations de chemin d’accès après le premier segment d’URI sont conservées pour les fichiers téléchargés à l’aide de la liste de propriétés fileUris. Comme l’indique le tableau précédent, les fichiers téléchargés sont mappés avec des sous-répertoires de téléchargement pour refléter la structure des valeurs fileUris.

Support