Estensione script personalizzata per Windows

L'estensione per script personalizzati scarica ed esegue script sulle macchine virtuali di Azure. Usare questa estensione è utile per la configurazione post-distribuzione, l'installazione di software o altre attività di configurazione o gestione. Gli script possono essere scaricati dall'archiviazione di Azure o da GitHub oppure possono essere forniti al portale di Azure durante il runtime dell'estensione.

L'estensione per script personalizzati è integrabile con i modelli di Azure Resource Manager. È anche possibile eseguirla tramite l'interfaccia della riga di comando di Azure, Azure PowerShell, il portale di Azure o l'API REST di Macchine virtuali di Azure.

Questo articolo descrive come usare l'estensione per script personalizzati usando il modulo Azure PowerShell e i modelli di Azure Resource Manager. Sono inoltre illustrate le procedure di risoluzione dei problemi per i sistemi Windows.

Prerequisiti

Nota

Non usare l'estensione per script personalizzati per eseguire Update-AzVM con la stessa macchina virtuale del relativo parametro. L'estensione attenderà se stessa.

Sistemi operativi Windows supportati

Sistema operativo Windows x64
Windows 10 Supportata
Windows 11 Supportata
Windows Server 2008 SP2 Supportata
Windows Server 2008 R2 Supportata
Windows Server 2012 Supportata
Windows Server 2012 R2 Supportata
Windows Server 2016 Supportata
Windows Server 2016 Core Supportata
Windows Server 2019 Supportata
Windows Server 2019 Core Supportata
Windows Server 2022 Supportata
Windows Server 2022 Core Supportata

Posizione degli script

È possibile impostare l'estensione per utilizzare le credenziali di Archiviazione BLOB di Azure per accedere ad Archiviazione BLOB di Azure. La posizione dello script può essere ovunque, purché la macchina virtuale sia in grado di connettersi con l'endpoint, ad esempio GitHub o un file server interno.

Connettività Internet

Per scaricare uno script dall'esterno, ad esempio da GitHub o Archiviazione di Azure, è necessario aprire altri firewall o porte NSG del gruppo di sicurezza di rete. Ad esempio, se lo script si trova in Archiviazione di Azure, è possibile consentire l'accesso utilizzando i tag del servizio Azure NSG per Archiviazione.

L'estensione script personalizzata non ha alcun modo per ignorare la convalida del certificato. Se si esegue il download da un percorso protetto con, ad esempio, un certificato autofirmato, è possibile che si verifichino errori come Il certificato remoto non è valido in base alla procedura di convalida. Assicurarsi che il certificato sia installato correttamente nell'archivi Autorità di certificazione radice attendibili disponibile nell'elenco locale nella macchina virtuale.

Se lo script si trova su un server locale, potrebbe essere necessario aprire altri firewall o porte NSG.

Suggerimenti

  • L'output è limitato agli ultimi 4096 byte.
  • Il carattere di escape corretto consente di garantire che le stringhe vengano analizzate correttamente. Ad esempio, sono sempre necessarie due barre rovesciate per eseguire l'escape di una singola barra rovesciata letterale quando si gestiscono i percorsi dei file. Esempio: {"commandToExecute": "C:\\Windows\\System32\\systeminfo.exe >> D:\\test.txt"}
  • La frequenza di errore più elevata per questa estensione è dovuta a errori di sintassi nello script. Verificare che lo script funzioni senza errori. Inserire un maggior numero di registrazioni nello script per rendere più facile l'individuazione dei problemi.
  • Scrivere script idempotenti, in modo che la loro esecuzione accidentale non causi modifiche al sistema.
  • Controllare che gli script non richiedano l'input dell'utente durante l'esecuzione.
  • Il tempo di esecuzione dello script è di 90 minuti. Una durata superiore comporta il fallimento della fornitura dell'estensione.
  • Non inserire riavvio all'interno dello script. Questa azione causa problemi con altre estensioni in fase di installazione e l'estensione non continua dopo il riavvio.
  • Se si utilizza uno script che causa un riavvio prima di installare le applicazioni e di eseguire lo script, pianificare il riavvio utilizzando Task Scheduler di Windows o strumenti come DSC, Chef o le estensioni di Puppet.
  • Non eseguire uno script che provochi l'arresto o l'aggiornamento di Agente macchina virtuale. Potrebbe lasciare l'estensione in uno stato di transizione e portare a un time-out.
  • L'estensione esegue lo script una sola volta. Se si desidera eseguire uno script a ogni avvio, utilizzare l'estensione per creare una task pianificata di Windows.
  • Se si desidera programmare l'esecuzione di uno script, utilizzare l'estensione per creare una task pianificata di Windows.
  • Quando lo script è in esecuzione, lo stato dell'estensione in transizione viene visualizzato solo dal portale Azure o dalla CLI di Azure. Se si desiderano aggiornamenti di stato più frequenti per uno script in esecuzione, creare la propria soluzione.
  • L'estensione Script personalizzato non supporta nativamente i server proxy. Tuttavia, è possibile utilizzare uno strumento di trasferimento di file, come Invoke-WebRequest, che supporta i server proxy all'interno dello script.
  • Tenere presente le posizioni delle directory non predefinite su cui potrebbero fare affidamento gli script o i comandi. e includere la logica necessaria per gestirli.
  • Assicurarsi di non avere alcuna impostazione personalizzata nella chiave del Registro di sistema HKLM\SOFTWARE\Microsoft\Command Processor\AutoRun (dettagliata qui). Questa operazione viene attivata durante l'installazione o le fasi di abilitazione dell'estensione script personalizzata e genera un errore del tipo 'XYZ is not recognized as an internal or external command, operable program or batch file'.
  • L'estensione Script personalizzato viene eseguita sotto l'LocalSystemaccount.
  • Se si vogliono utilizzare le storageAccountNameproprietà,storageAccountKey queste devono essere collocateprotectedSettings.
  • È possibile avere una sola versione dell'estensione sulla macchina virtuale. Per eseguire un secondo script personalizzato, è possibile aggiornare l'estensione esistente con una nuova configurazione. In alternativa, è possibile rimuovere l'estensione Script personalizzato e riapplicarla con lo script aggiornato.

Schema dell'estensione

La configurazione dell'estensione script personalizzata specifica informazioni come il percorso dello script e il comando da eseguire. È possibile archiviare queste informazioni in file di configurazione, specificarle sulla riga di comando o definirle in un modello di Azure Resource Manager.

I dati sensibili possono essere archiviati in una configurazione protetta, che viene crittografata e decrittografata solo all'interno della macchina virtuale. La configurazione protetta è utile quando il comando di esecuzione include segreti, ad esempio una password o un riferimento a un file di firma di accesso condiviso. Ecco un esempio:

{
    "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"
            ]
        }
    }
}

Nota

LamanagedIdentity proprietànon deve essere utilizzata insieme alla proprietà storageAccountName o storageAccountKey.

È possibile installare una sola versione di un'estensione in una macchina virtuale alla volta. La specifica di uno script personalizzato due volte nello stesso modello di Azure Resource Manager per la stessa macchina virtuale ha esito negativo.

È possibile usare questo schema all'interno della risorsa macchina virtuale o come risorsa autonoma. Se questa estensione viene usata come risorsa autonoma nel modello di Azure Resource Manager, il nome della risorsa deve essere nel formato nomeMacchinaVirtuale/NomeEstensione.

Valori delle proprietà

Nome Valore o esempio Tipo di dati
apiVersion 2015-06-15 data
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 array
timestamp 123456789 Intero a 32 bit
commandToExecute powershell -ExecutionPolicy Unrestricted -File configure-music-app.ps1 string
storageAccountName examplestorageacct string
storageAccountKey TmJK/1N3AbAZ3q/+hOXoi/l73zOqsaxXDhqa9Y83/v5UpXQp2DQIBuv2Tifp60cE/OaHsJZmQZ7teQfczQj8hg== string
managedIdentity { } o { "clientId": "31b403aa-c364-4240-a7ff-d85fb6cd7232" } o { "objectId": "12dd289c-0583-46e5-b9b4-115d5c19ef4b" } Oggetto JSON

Nota

Questi nomi di proprietà fanno distinzione tra maiuscole e minuscole. Per evitare problemi nella distribuzione, usare i nomi come indicato di seguito.

Dettagli sui valori delle proprietà

Proprietà Facoltativo o obbligatorio Dettagli
fileUris Facoltativo URL per i file da scaricare. Se gli URL sono sensibili, ad esempio se contengono chiavi, questo campo deve essere specificato in protectedSettings.
commandToExecute Richiesto Script del punto di ingresso da eseguire. Usare questa proprietà se il comando contiene segreti, ad esempio password, oppure se gli URI di file sono sensibili.
timestamp Facoltativo Modificare questo valore solo per attivare una riesecuzione dello script. Qualsiasi valore intero è accettabile, purché sia diverso dal valore precedente.
storageAccountName Facoltativo Nome dell'account di archiviazione. Se si specificano credenziali di archiviazione, tutti i valori di fileUris devono essere URL relativi a BLOB di Azure.
storageAccountKey Facoltativo La chiave di accesso per l'account di archiviazione.
managedIdentity Facoltativo L’identità gestita per il download dei file. I valori validi sono clientId (facoltativo, stringa), ovvero l'ID client dell'identità gestita e objectId (facoltativo, stringa), ovvero l'ID oggetto dell'identità gestita.

Le impostazioni pubbliche vengono inviate in testo non crittografato alla macchina virtuale in cui viene eseguito lo script. Le impostazioni protette vengono crittografate tramite una chiave nota solo alla macchina virtuale e ad Azure. Le impostazioni vengono salvate nella macchina virtuale a mano a mano che vengono inviate. Ovvero, se le impostazioni sono state crittografate, vengono salvate crittografate nella macchina virtuale. Il certificato usato per decrittografare i valori crittografati viene archiviato nella macchina virtuale. Il certificato viene usato anche per decrittografare le impostazioni, se necessario, in fase di esecuzione.

Le impostazioni pubbliche possono essere utili per il debug, ma è consigliabile usare impostazioni protette.

È possibile impostare i valori seguenti in impostazioni pubbliche o protette. L'estensione rifiuta qualsiasi configurazione in cui questi valori vengono impostati in impostazioni pubbliche e protette.

  • commandToExecute
  • fileUris

Proprietà: managedIdentity

Nota

Questa proprietà deve essere specificata solo nelle impostazioni protette.

L'estensione per script personalizzati, versione 1.10 e successive, supporta identità gestite per scaricare i file dagli URL forniti nell'impostazione fileUris. La proprietà consente all'estensione per script personalizzati di accedere a BLOB o contenitori privati di Archiviazione di Azure senza che l'utente debba passare segreti come i token di firma di accesso condiviso o le chiavi dell'account di archiviazione.

Per usare questa funzionalità, aggiungere un’identità assegnata dal sistema o assegnata dall'utente alla macchina virtuale o al set di scalabilità di macchine virtuali in cui viene eseguita l'estensione script personalizzata. Quindi concedere all'identità gestita l'accesso al contenitore o al BLOB di Archiviazione di Azure.

Per usare l'identità assegnata dal sistema nella macchina virtuale o nel set di scalabilità di macchine virtuali di destinazione, impostare managedidentity su un oggetto JSON vuoto.

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

Per usare l'identità assegnata dall'utente nella macchina virtuale o nel set di scalabilità di macchine virtuali di destinazione, configurare managedidentity con l'ID client o l'ID oggetto dell'identità gestita.

{
  "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" }
}

Nota

LamanagedIdentity proprietànon deve essere utilizzata insieme alla proprietà storageAccountName o storageAccountKey.

Distribuzione modelli

Le estensioni macchina virtuale di Azure possono essere distribuite usando i modelli di Azure Resource Manager. Lo schema JSON indicato nella sezione precedente può essere usato in un modello di Azure Resource Manager per eseguire l'estensione per gli script personalizzati durante la distribuzione. Gli esempi seguenti illustrano come usare l'estensione Script personalizzato:

Distribuzione PowerShell

È possibile usare il comando Set-AzVMCustomScriptExtension per aggiungere l'estensione di script personalizzata a una macchina virtuale esistente. Per altre informazioni, vedere Set-AzVMCustomScriptExtension.

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

Esempi

Uso di più script

In questo esempio vengono usati tre script per compilare il server. La proprietà commandToExecute chiama il primo script. Si hanno quindi opzioni su come vengono chiamati gli altri. È ad esempio possibile avere uno script master che controlla l'esecuzione, con gestione, registrazione e gestione dello stato degli errori corrette. Gli script vengono scaricati nel computer locale per l'esecuzione.

Ad esempio, in 1_Add_Tools.ps1chiamare 2_Add_Features.ps1 aggiungendo .\2_Add_Features.ps1 allo script. Ripetere questo processo per gli altri script definiti in $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;

Esecuzione di script da una condivisione locale

In questo esempio potrebbe essere necessario usare un Server Message Block (SMB) locale per la posizione dello script. Non è quindi necessario fornire altre impostazioni, ad eccezione di 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

Esecuzione di uno script personalizzato più volte usando l'interfaccia della riga di comando

Il gestore dell'estensione per script personalizzati impedisce di rieseguire uno script se sono state passate le stesse identiche impostazioni. Questo comportamento impedisce l'esecuzione accidentale, che potrebbe causare comportamenti imprevisti se lo script non è idempotent. Per verificare se il gestore ha bloccato la riesecuzione, esaminare C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\<HandlerVersion>\CustomScriptHandler.log*. Ricerca di un avviso simile al seguente:

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

Si può eseguire più volte l'estensione script personalizzata solo nelle condizioni seguenti:

  • Il parametro Name dell'estensione è lo stesso usato nella distribuzione precedente dell'estensione.
  • La configurazione è stata aggiornata. È possibile, ad esempio, aggiungere al comando una proprietà dinamica, come un timestamp. Se il gestore rileva una modifica nelle impostazioni di configurazione, considera tale modifica come un desiderio esplicito di rieseguire lo script.

In alternativa, è possibile impostare la proprietà ForceUpdateTag su true.

Uso di Invoke-WebRequest

Se si usa Invoke-WebRequest nello script, è necessario specificare il parametro -UseBasicParsing. Se non si specifica il parametro , viene visualizzato l'errore seguente durante il controllo dello stato dettagliato:

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.

Set di scalabilità di macchine virtuali

Se si distribuisce l'estensione script personalizzata dal portale di Azure, non si ha il controllo sulla scadenza del token di firma di accesso condiviso per l'accesso allo script nell'account di archiviazione. La distribuzione iniziale funziona, ma quando scade il token di firma di accesso condiviso dell'account di archiviazione, qualsiasi operazione di ridimensionamento successiva ha esito negativo perché l'estensione per script personalizzati non può più accedere all'account di archiviazione.

È consigliabile usare PowerShell, l'interfaccia della riga di comando di Azureo un modello di Azure Resource Manager quando si distribuisce l'estensione script personalizzata in un set di scalabilità di macchine virtuali. In questo modo, è possibile scegliere di usare un'identità gestita o di avere il controllo diretto della scadenza del token di firma di accesso condiviso per l'accesso allo script nell'account di archiviazione, purché sia necessario.

Risoluzione dei problemi e supporto

È possibile recuperare i dati sullo stato delle distribuzioni dell'estensione nel portale di Azure e tramite Azure PowerShell e il modulo Azure PowerShell. Per visualizzare lo stato di distribuzione delle estensioni per una macchina virtuale, eseguire il comando seguente:

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

L'output dell'estensione viene registrato nei file presenti nella cartella seguente nella macchina virtuale di destinazione:

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

I file specificati vengono scaricati nella cartella seguente nella macchina virtuale di destinazione:

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

Nel percorso precedente <n> è un numero intero decimale che può variare nelle diverse esecuzioni dell'estensione. Il valore 1.* corrisponde al valore effettivo attuale typeHandlerVersion dell'estensione. Ad esempio, la directory effettiva potrebbe essere C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.8\Downloads\2.

Quando si esegue il comando commandToExecute, nell'estensione viene impostata questa directory, ad esempio ...\Downloads\2, come directory di lavoro attuale. In questo modo viene abilitato l'uso di percorsi relativi per individuare i file scaricati usando la proprietà fileURIs. Ecco alcuni esempi di file scaricati:

URI in fileUris Percorso di download relativo Percorso di download assoluto
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

I percorsi assoluti delle directory cambiano durante il ciclo di vita della macchina virtuale, ma non durante una singola esecuzione dell'estensione CustomScript.

Poiché il percorso di download assoluto può variare nel tempo, quando è possibile è preferibile optare per percorsi relativi di script/file nella stringa commandToExecute. Ad esempio:

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

Le informazioni sul percorso dopo il primo segmento URI vengono mantenute per i file scaricati usando l'elenco delle proprietà fileUris. Come illustrato nella tabella precedente, per i file scaricati viene eseguito il mapping nelle sottodirectory di download per riflettere la struttura dei valori fileUris.

Supporto tecnico