Extensão de script personalizado para o Windows
A extensão de script personalizado baixa e executa scripts em VMs (máquinas virtuais) do Azure. Use essa extensão para a configuração pós-implantação, instalação de software ou qualquer outra tarefa de configuração ou gerenciamento. Você pode baixar scripts do Armazenamento do Azure ou do GitHub ou fornecê-los ao portal do Azure no runtime de extensão.
A extensão de Script personalizado se integra com os modelos do Azure Resource Manager. Você também pode executá-la usando a CLI do Azure, o PowerShell do Azure, o portal do Azure ou a API REST de Máquinas Virtuais do Azure.
Este artigo descreve como utilizar a Extensão de Script Personalizado usando o módulo do Azure PowerShell e os modelos do Azure Resource Manager. Ele também fornece as etapas de solução de problemas em sistemas Windows.
Pré-requisitos
Observação
Não use a Extensão de Script Personalizado para executar oUpdate-AzVM
com a mesma VM que o respectivo parâmetro. A extensão irá esperar por si mesma.
Sistemas operacionais Windows compatíveis
Sistema operacional Windows | x64 |
---|---|
Windows 10 | Com suporte |
Windows 11 | Com suporte |
Windows Server 2008 SP2 | Com suporte |
Windows Server 2008 R2 | Com suporte |
Windows Server 2012 | Com suporte |
Windows Server 2012 R2 | Com suporte |
Windows Server 2016 | Com suporte |
Windows Server 2016 Core | Com suporte |
Windows Server 2019 | Com suporte |
Windows Server 2019 Core | Com suporte |
Windows Server 2022 | Com suporte |
Windows Server 2022 Core | Com suporte |
Local do script
Você pode configurar a extensão para usar suas credenciais do Armazenamento de Blobs do Azure para acessar esse armazenamento. O local do script pode ser qualquer um, desde que a VM possa rotear para esse ponto de extremidade, como, por exemplo, o GitHub ou um servidor de arquivos interno.
Conectividade com a Internet
Para baixar um script externamente, como, por exemplo, do GitHub ou do Armazenamento do Azure, você precisará abrir outras portas de firewall ou do grupo de segurança de rede (NSG). Por exemplo, se o script estiver localizado no Armazenamento do Azure, você poderá permitir o acesso usando marcas de serviço para armazenamento do NSG do Azure.
A Extensão de Script Personalizado não tem nenhuma forma de ignorar a validação de certificado. Se estiver baixando a partir de um local seguro com, por exemplo, um certificado autoassinado, você pode obtendo erros como O certificado remoto é inválido de acordo com o procedimento de validação. Certifique-se de que o certificado foi instalado corretamente no repositório Autoridades Confiáveis de Certificação Raiz da máquina virtual.
Se o seu script estiver em um servidor local, talvez você continue precisando abrir outras portas de firewall ou de NSG.
Dicas
- A saída está limitada aos últimos 4.096 bytes.
- Fazer o escape correto de caracteres ajudará a garantir que as cadeias de caracteres sejam analisadas corretamente. Por exemplo, ao lidar com caminhos de arquivo, é necessário usar duas barras invertidas para escapar uma única barra invertida literal. Exemplo:
{"commandToExecute": "C:\\Windows\\System32\\systeminfo.exe >> D:\\test.txt"}
- A taxa de falha mais alta para essa extensão ocorre devido a erros de sintaxe no script. Verifique se o script está sendo executado sem erros. Coloque mais registros em log no script para facilitar a detecção de falhas.
- Escreva scripts idempotentes, de modo que executá-los mais de uma vez inadvertidamente não cause alterações no sistema.
- Verifique se os scripts não exigem entrada de usuário quando são executados.
- O script tem permissão para ser executado em 90 minutos. Qualquer coisa além disso resultará em falha no provisionamento da extensão.
- Não inclua reinicializações dentro do script. Essa ação causará problemas com outras extensões que estiverem sendo instaladas e a extensão não continuará após a reinicialização.
- Se tiver um script que cause uma reinicialização antes de instalar aplicativos e executar scripts, agende a reinicialização usando uma Tarefa Agendada do Windows ou usando ferramentas como o DSC, o Chef ou extensões do Puppet.
- Não execute um script que cause uma parada ou atualização do agente de VM. Isso poderá deixar a extensão em um estado de transição e fazer com que o tempo limite seja excedido.
- A extensão executa um script apenas uma vez. Se você quiser executar um script em cada inicialização, use a extensão para criar uma Tarefa Agendada do Windows.
- Se quiser agendar quando um script é executado, use a extensão para criar uma Tarefa Agendada do Windows.
- Quando o script estiver sendo executado, você verá apenas um status da extensão em transição no portal do Azure ou na CLI do Azure. Se quiser atualizações de status mais frequentes para um script em execução, crie sua própria solução.
- A extensão de script personalizado não dá suporte nativo a servidores proxy. No entanto, você pode usar uma ferramenta de transferência de arquivos que dê suporte a servidores proxy dentro do seu script, como a Invoke-WebRequest.
- Esteja ciente dos locais de diretório não padrão dos quais seus scripts ou comandos poderão depender. Tenha uma lógica para lidar com essa situação.
- Verifique se você não tem nenhuma configuração personalizada na chave do Registro
HKLM\SOFTWARE\Microsoft\Command Processor\AutoRun
(detalhada aqui). Isso seria disparado durante a instalação da extensão de script personalizado ou habilitaria fases e causaria um erro como'XYZ is not recognized as an internal or external command, operable program or batch file'
. - A Extensão de Script Personalizado é executada no âmbito da conta do
LocalSystem
. - Se você planeja usar as propriedades
storageAccountName
estorageAccountKey
, coloque-as emprotectedSettings
. - Você só pode ter uma versão de uma extensão aplicada à VM. Para executar um segundo script personalizado, você pode atualizar a extensão existente com uma nova configuração. Alternativamente, você pode remover a extensão de script personalizado e reaplicá-la com o script atualizado
Esquema de extensão
A configuração de extensão de script personalizado especifica itens como localização de script e o comando a ser executado. Você pode armazenar essa configuração em arquivos de configuração, especificá-la na linha de comando ou especificá-la em um modelo do Azure Resource Manager.
Você pode armazenar dados confidenciais em uma configuração protegida que é criptografada e descriptografada somente dentro da VM. A configuração protegida é útil quando o comando de execução inclui segredos como uma senha ou uma referência de arquivo SAS (assinatura de acesso compartilhado). Veja um exemplo:
{
"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"
]
}
}
}
Observação
A propriedade managedIdentity
não pode ser usada em conjunto com a propriedade storageAccountName
ou storageAccountKey
.
Somente uma versão de uma extensão pode ser instalada em uma VM de cada vez. Especificar um script personalizado duas vezes no mesmo modelo do Azure Resource Manager para a mesma VM irá falhar.
Você pode usar esse esquema dentro do recurso de VM ou como um recurso autônomo. Se essa extensão for usada como um recurso autônomo no modelo do Azure Resource Manager, o nome do recurso deverá estar no formato virtualMachineName/extensionName.
Valores de propriedade
Nome | Valor ou exemplo | Tipo de dados |
---|---|---|
apiVersion | 2015-06-15 |
date |
publicador | 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 |
Inteiro de 32 bits |
commandToExecute | powershell -ExecutionPolicy Unrestricted -File configure-music-app.ps1 |
string |
storageAccountName | examplestorageacct |
string |
storageAccountKey | TmJK/1N3AbAZ3q/+hOXoi/l73zOqsaxXDhqa9Y83/v5UpXQp2DQIBuv2Tifp60cE/OaHsJZmQZ7teQfczQj8hg== |
Cadeia de caracteres |
managedIdentity | { } ou { "clientId": "31b403aa-c364-4240-a7ff-d85fb6cd7232" } ou { "objectId": "12dd289c-0583-46e5-b9b4-115d5c19ef4b" } |
Objeto JSON |
Observação
Esses nomes de propriedade diferenciam maiúsculas de minúsculas. Para evitar problemas de implantação, use os nomes conforme mostrado aqui.
Detalhes de valor de propriedade
Propriedade | Opcional ou obrigatório | Detalhes |
---|---|---|
fileUris | Opcional | URLs para arquivos a serem baixados. Se os URLs forem confidenciais, como, por exemplo, se contiverem chaves, esse campo deverá ser especificado nas protectedSettings . |
commandToExecute | Obrigatório | O script de ponto de entrada a ser executado. Use essa propriedade se o comando contiver segredos como senhas ou se os URIs de arquivo forem confidenciais. |
timestamp | Opcional | Altere esse valor apenas para disparar uma nova repetição do script. Qualquer valor inteiro é aceitável, desde que seja diferente do valor anterior. |
storageAccountName | Opcional | O nome da conta de armazenamento. Se você especificar credenciais de armazenamento, todos os valores de fileUris precisarão ser URLs de blobs do Azure. |
storageAccountKey | Opcional | A chave de acesso da conta de armazenamento. |
managedIdentity | Opcional | A identidade gerenciada para baixar arquivos. Os valores válidos são clientId (opcional, cadeia de caracteres), que é a ID de cliente da identidade gerenciada, e objectId (opcional, cadeia de caracteres), que é a ID de objeto da identidade gerenciada. |
As configurações públicas são enviadas em texto não criptografado para a VM em que o script será executado. As configurações protegidas são criptografadas por meio de uma chave conhecida apenas pelo Azure e pela VM. As configurações são salvas na VM conforme são enviadas. Ou seja, se as configurações forem criptografadas, elas serão salvas criptografadas na VM. O certificado que é usado para descriptografar os valores criptografados é armazenado na VM. O certificado também é usado para descriptografar as configurações no runtime, se necessário.
O uso de configurações públicas pode ser útil para depuração, mas recomendamos que você use as configurações protegidas.
Você pode definir os seguintes valores em configurações públicas ou protegidas. A extensão rejeita qualquer configuração em que esses valores estejam definidos em ambas as configurações, pública e protegida.
commandToExecute
fileUris
Propriedade: managedIdentity
Observação
Essa propriedade precisa ser especificada somente em configurações protegidas.
A Extensão de Script Personalizado versão, 1.10 e posterior, dá suporte a identidades gerenciadas para baixar arquivos de URLs fornecidas na configuração fileUris
. A propriedade permite que a Extensão de Script Personalizado acesse os blobs ou contêineres privados do Armazenamento do Azure sem que o usuário precise transmitir segredos como tokens SAS ou chaves de conta de armazenamento.
Para usar esse recurso, o usuário precisa adicionar uma identidade atribuída pelo sistema ou atribuída pelo usuário à VM ou ao Conjunto de Dimensionamento de Máquinas Virtuais nos quais a Extensão de Script Personalizado é executada. A seguir, conceda o acesso de identidade gerenciada ao contêiner ou blob de Armazenamento do Azure.
Para usar a identidade atribuída pelo sistema na VM ou no Conjunto de Dimensionamento de Máquinas Virtuais de destino, defina managedidentity
como um objeto JSON vazio.
{
"fileUris": ["https://mystorage.blob.core.windows.net/privatecontainer/script1.ps1"],
"commandToExecute": "powershell.exe script1.ps1",
"managedIdentity" : {}
}
Para usar a identidade atribuída pelo usuário na VM ou no Conjunto de Dimensionamento de Máquinas Virtuais de destino, configure managedidentity
com a ID de cliente ou a ID de objeto da identidade gerenciada.
{
"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" }
}
Observação
A propriedade managedIdentity
não pode ser usada em conjunto com a propriedade storageAccountName
ou storageAccountKey
.
Implantação de modelo
É possível implantar extensões de VM do Azure com os modelos do Azure Resource Manager. O esquema JSON detalhado na seção anterior pode ser usado em um modelo do Azure Resource Manager para executar a extensão de script personalizado durante a implantação do modelo. Os seguintes exemplos mostram como usar a extensão de script personalizado:
- Implantar extensões de máquina virtual com modelos do Azure Resource Manager
- Implantar um aplicativo de duas camadas no Windows e no Banco de Dados SQL do Azure
Implantação do PowerShell
Você pode usar o comando Set-AzVMCustomScriptExtension
para adicionar a extensão de script personalizado a uma máquina virtual existente. Para obter mais informações, confira Set-AzVMCustomScriptExtension.
Set-AzVMCustomScriptExtension -ResourceGroupName <resourceGroupName> `
-VMName <vmName> `
-Location myLocation `
-FileUri <fileUrl> `
-Run 'myScript.ps1' `
-Name DemoScriptExtension
Exemplos
Usando vários scripts
Esse exemplo usa três scripts para criar seu servidor. A propriedade commandToExecute
chama o primeiro script. Depois, há opções para chamar os outros. Por exemplo, você pode ter um script principal que controla a execução, com o tratamento de erro, o registro em log e o gerenciamento de estado corretos. Os scripts são baixados no computador local para serem executados.
Por exemplo, em 1_Add_Tools.ps1, você chamaria 2_Add_Features.ps1 adicionando .\2_Add_Features.ps1
ao script. Repita esse processo para os outros scripts que você definir em $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;
Executando scripts de um compartilhamento local
Neste exemplo, você poderia usar um servidor local do protocolo SMB como local do script. Depois, você não precisará fornecer outras configurações, exceto 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
Como executar um script personalizado mais de uma vez usando a CLI
O manipulador da Extensão de Script Personalizado impedirá uma nova execução de um script se as exatamente as mesmas configurações forem transmitidas. Esse comportamento impede a nova execução acidental, o que poderá causar comportamentos inesperados se o script não for idempotente. Para confirmar se o manipulador bloqueou a execução novamente, verifique emC:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\<HandlerVersion>\CustomScriptHandler.log*
. Procure um aviso parecido com esse:
Current sequence number, <SequenceNumber>, is not greater than the sequence number
of the most recently executed configuration. Exiting...
Se você quiser executar a extensão de script personalizado mais de uma vez, faça isso somente sob estas condições:
- O parâmetro da extensão
Name
é o mesmo que o da implantação anterior da extensão. - Você atualizou a configuração. Você pode adicionar uma propriedade dinâmica ao comando, como um carimbo de data/hora. Se detectar uma alteração nas definições de configuração, o manipulador vai interpretar essa alteração como um desejo explícito de executar o script novamente.
Como alternativa, você pode definir a propriedade ForceUpdateTag como true
.
Como usar Invoke-WebRequest
Se você estiver usando Invoke-WebRequest no script, especifique o parâmetro -UseBasicParsing
. Se não especificar o parâmetro, você obterá o seguinte erro ao verificar o status detalhado:
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.
Conjuntos de Dimensionamento de Máquinas Virtuais
Se você implantar a extensão de script personalizado usando o portal do Azure, não terá controle sobre a expiração do token SAS para acessar o script na conta de armazenamento. A implantação inicial funciona, mas quando o token SAS da conta de armazenamento expirar, as próximas operações de dimensionamento irão falhar porque a Extensão de Script Personalizado não poderá mais acessar a conta de armazenamento.
Recomendamos que você use o PowerShell, a CLI do Azure ou um modelo do Azure Resource Manager ao implantar a Extensão de Script Personalizado em um Conjunto de Dimensionamento de Máquinas Virtuais. Assim, você pode usar uma identidade gerenciada ou ter controle direto da expiração do token SAS para acessar o script na conta de armazenamento durante o tempo que for necessário.
Solução de problemas e suporte
Você pode recuperar dados sobre o estado das implantações de extensão por meio do portal do Azure e do módulo do Azure PowerShell. Para ver o estado de implantação das extensões de uma VM, execute o seguinte comando:
Get-AzVMExtension -ResourceGroupName <resourceGroupName> `
-VMName <vmName> -Name myExtensionName
A saída da extensão é registrada nos arquivos localizados na seguinte pasta, na máquina virtual de destino:
C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension
Os arquivos especificados são baixados na seguinte pasta, na máquina virtual de destino:
C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.*\Downloads\<n>
No caminho anterior, <n>
é um inteiro decimal que pode ser alterado entre as execuções da extensão. O valor 1.*
corresponde ao valor typeHandlerVersion
atual e real da extensão. Por exemplo, o diretório real pode ser C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.8\Downloads\2
.
Quando você executa o comando commandToExecute
, a extensão define esse diretório, como, por exemplo, ...\Downloads\2
, como o diretório de trabalho atual. Esse processo permite o uso de caminhos relativos para localizar os arquivos baixados usando a propriedade fileURIs
. Aqui estão exemplos de arquivos baixados:
URI em fileUris |
Local de download relativo | Local de download absoluto |
---|---|---|
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 |
Os caminhos de diretório absolutos mudam ao longo do tempo de vida da VM, mas não dentro de uma única execução da Extensão de Script Personalizado.
Como o caminho de download absoluto pode variar ao longo do tempo, é melhor optar por caminhos relativos de script/arquivo na cadeia de caracteres commandToExecute
, sempre que possível. Por exemplo:
"commandToExecute": "powershell.exe . . . -File \"./scripts/myscript.ps1\""
As informações de caminho após o primeiro segmento do URI são retidas para os arquivos baixados usando a lista de propriedades fileUris
. Conforme mostrado na tabela anterior, os arquivos baixados são mapeados em subdiretórios de download para refletir a estrutura dos valores de fileUris
.
Suporte
Se precisar de ajuda com qualquer parte deste artigo, entre em contato com os especialistas do Azure no Suporte da Comunidade do Azure.
Para registrar um incidente de suporte do Azure, acesse o site de Suporte do Azure e selecione Obter Suporte.
Para saber mais sobre como usar o suporte do Azure, leia as Perguntas frequentes sobre o suporte do Microsoft Azure.