Windows でのカスタムのスクリプト拡張機能

カスタム スクリプト拡張機能は、スクリプトをダウンロードし、Azure 仮想マシン (VM) で実行します。 この拡張機能は、デプロイ後の構成、ソフトウェアのインストール、その他の構成タスクや管理タスクに使用します。 スクリプトは、Azure Storage や GitHub からダウンロードできます。また、拡張機能の実行時に Azure portal に提供することもできます。

カスタム スクリプト拡張機能は Azure Resource Manager テンプレートと統合します。 また、Azure CLI、PowerShell、Azure portal、または Azure Virtual Machines REST API を使って実行することもできます。

この記事では、Azure PowerShell モジュールと Azure Resource Manager テンプレートを使ってカスタム スクリプト拡張機能を使用する方法について詳しく説明します。 また、Windows システムでのトラブルシューティング手順も説明します。

前提条件

注意

カスタム スクリプト拡張機能を使用して、そのパラメーターと同じ VM で Update-AzVM を実行しないでください。 拡張機能が自身を待機することになります。

サポートされている Windows オペレーティング システム

Windows OS x64
Windows 10 サポート
Windows 11 サポートされています
Windows Server 2008 SP2 サポートされています
Windows Server 2008 R2 サポートされています
Windows Server 2012 サポートされています
Windows Server 2012 R2 サポートされています
Windows Server 2016 サポートされています
Windows Server 2016 Core サポートされています
Windows Server 2019 サポートされています
Windows Server 2019 Core サポートされています
Windows Server 2022 サポートされています
Windows Server 2022 Core サポートされています

スクリプトの場所

Azure Blob Storage の資格情報を使用して Azure Blob Storage にアクセスできるように拡張機能を設定できます。 スクリプトは、そのエンドポイント (GitHub や社内ファイル サーバーなど) に VM をルーティングできる限り、任意の場所に保存できます。

インターネット接続

GitHub や Azure Storage などからスクリプトを外部でダウンロードする場合は、ファイアウォールやネットワーク セキュリティ グループ (NSG) の他のポートを開く必要があります。 たとえば、スクリプトが Azure Storage にある場合、Storage の Azure NSG サービス タグを使用することでアクセスを許可できます。

カスタム スクリプト拡張機能には、証明書の検証を省略する方法はありません。 自己署名証明書などでセキュリティ保護された場所からダウンロードするときに、"検証プロシージャによると、リモート証明書は無効です" などのエラーが発生する可能性があります。 証明書が、VM 上の "信頼されたルート証明機関" ストアに正しくインストールされていることを確認してください。

スクリプトがローカル サーバーにある場合でも、ファイアウォールや NSG の他のポートを開く必要があります。

ヒント

  • 出力は最後の 4,096 バイトに制限されます。
  • 文字を適切にエスケープすると、文字列が正しく解析されるようになります。 たとえば、ファイル パスを処理する場合、1 つのリテラルのバックスラッシュをエスケープするには、常に 2 つのバックスラッシュが必要です。 サンプル: {"commandToExecute": "C:\\Windows\\System32\\systeminfo.exe >> D:\\test.txt"}
  • この拡張機能のエラーで最も多い原因は、スクリプトの構文エラーです。 スクリプトがエラーを出さずに実行されることを確認してください。 スクリプトに追加のログ記録を挿入すると、エラーを見つけやすくなります。
  • 誤って複数回実行された場合でもシステムに変更が加えられないよう、べき等のスクリプトを作成してください。
  • スクリプトの実行時に、ユーザー入力を必要としないように作成してください。
  • スクリプトは、実行されるまでに 90 分かかることがあります。 これを超えると、拡張機能のプロビジョニングに失敗します。
  • スクリプト内で再起動を行わないでください。 このアクションを行うと、インストールされている他の拡張機能に問題が発生し、再起動後に拡張機能が続行されません。
  • アプリケーションをインストールしてスクリプトを実行する前に再起動を引き起こすスクリプトがある場合は、Windows のスケジュールされたタスクを使用するか、DSC、Chef、Puppet 拡張機能などのツールを使用して、再起動をスケジュールしてください。
  • VM エージェントの停止または更新を引き起こすスクリプトを実行しないでください。 実行すると拡張機能が移行中状態になり、タイムアウトにつながることがあります。
  • 拡張機能はスクリプトを 1 回だけ実行します。 起動のたびにスクリプトを実行する必要がある場合は、拡張機能を使用して、Windows のスケジュールされたタスクを作成します。
  • スクリプトを実行するタイミングをスケジュールする場合は、拡張機能を使用して Windows のスケジュールされたタスクを作成してください。
  • スクリプトが実行されているとき、Azure portal または CLI には拡張機能の状態が "移行中" とだけ表示されます。 実行中のスクリプトのステータスをより高い頻度で更新するには、独自のソリューションを作成してください。
  • カスタム スクリプト拡張機能は、ネイティブではプロキシ サーバーをサポートしません。 ただし、スクリプト内のプロキシ サーバーをサポートするファイル転送ツール (Invoke-WebRequest など) を使用できます。
  • スクリプトまたはコマンドで使用している既定以外のディレクトリの場所に注意してください。 この状況を処理するロジックを用意してください。
  • カスタム スクリプト拡張機能は LocalSystem アカウントで実行されます。
  • storageAccountName プロパティと storageAccountKey プロパティを使用する予定がある場合は、これらのプロパティを protectedSettings に併置する必要があります。
  • VM に適用できる拡張機能のバージョンは 1 つだけです。 2 つ目のカスタム スクリプトを実行するために、既存の拡張機能を新しい構成で更新できます。 または、カスタム スクリプト拡張機能を削除し、更新されたスクリプトを使用してそれを再適用できます

拡張機能のスキーマ

カスタム スクリプト拡張機能の構成では、スクリプトの場所や、実行するコマンドなどを指定します。 この構成は、構成ファイルに格納したり、コマンド ラインで指定したり、Azure Resource Manager テンプレートで指定したりできます。

機密データは、保護された構成に格納できます。このデータは暗号化され、VM 内でのみ暗号化解除されます。 保護された構成は、実行コマンドにパスワードや Shared Access Signature (SAS) ファイルの参照などのシークレットが含まれている場合に便利です。 次に例を示します。

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

Note

managedIdentity プロパティは、storageAccountName または storageAccountKey プロパティと組み合わせて使用しないでください

1 つの VM に一度にインストールできる拡張機能のバージョンは 1 つだけです。 同じ Azure Resource Manager テンプレートで同じ VM に対してカスタムスクリプトを 2 回指定すると、失敗します。

このスキーマは、VM リソース内で、またはスタンドアロン リソースとして使用できます。 この拡張機能が Azure Resource Manager テンプレートでスタンドアロン リソースとして使用される場合、リソースの名前は virtualMachineName/extensionName 形式である必要があります。

プロパティ値

名前 値または例 データ型
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 array
timestamp 123456789 32-bit integer
commandToExecute powershell -ExecutionPolicy Unrestricted -File configure-music-app.ps1 string
storageAccountName examplestorageacct string
storageAccountKey TmJK/1N3AbAZ3q/+hOXoi/l73zOqsaxXDhqa9Y83/v5UpXQp2DQIBuv2Tifp60cE/OaHsJZmQZ7teQfczQj8hg== string
managedIdentity { } または { "clientId": "31b403aa-c364-4240-a7ff-d85fb6cd7232" } または { "objectId": "12dd289c-0583-46e5-b9b4-115d5c19ef4b" } JSON オブジェクト

Note

これらのプロパティ名では大文字と小文字が区別されます。 展開の問題を回避するには、次のような名前を使います。

プロパティ値の詳細

プロパティ 省略可能または必須 詳細
fileUris 省略可能 ダウンロードするファイルの URL。 URL の機密性が高い (たとえばキーを含むなど) 場合は、このフィールドを protectedSettings で指定する必要があります。
commandToExecute 必須 実行するエントリ ポイント スクリプト。 コマンドにパスワードなどのシークレットが含まれている場合、またはファイル URI が機密の場合は、このプロパティを使用します。
timestamp 省略可能 この値は、スクリプトの再実行をトリガーするためにのみ変更します。 任意の整数値を使用できますが、前の値とは異なる必要があります。
storageAccountName 省略可能 ストレージ アカウントの名前。 ストレージの資格情報を指定する場合は、すべての fileUris 値が Azure BLOB の URL である必要があります。
storageAccountKey 省略可能 ストレージ アカウントのアクセス キー。
managedIdentity オプション ファイルをダウンロードするためのマネージド ID。 有効な値は、マネージド ID のクライアント ID を示す clientId (省略可能、文字列) と、マネージド ID のオブジェクト ID を示す objectId (省略可能、文字列) です。

"パブリック設定" は、スクリプトが実行される VM にクリア テキストで送信されます。 "保護された設定" は、Azure と VM のみが認識するキーを使用して暗号化されます。 設定は、送信先の仮想マシンに保存されます。 つまり、設定が暗号化された場合は、暗号化された設定が仮想マシンに保存されます。 暗号化された値の暗号化を解除するために使用される証明書は、仮想マシンに格納されます。 証明書は、必要に応じて実行時に設定の暗号化を解除するためにも使用されます。

デバッグにはパブリック設定を使用することが便利な場合もありますが、保護された設定を使用することをお勧めします。

パブリックまたは保護された設定のいずれかで、次の値を設定できます。 拡張機能では、パブリック設定と保護された設定の両方でこれらの値が設定されている構成が拒否されます。

  • commandToExecute
  • fileUris

プロパティ: managedIdentity

Note

このプロパティは、保護された設定でのみ指定する必要があります

カスタム スクリプト拡張機能のバージョン 1.10 以降では、fileUris 設定で指定された URL からファイルをダウンロードするためのマネージド ID がサポートされています。 このプロパティにより、ユーザーが SAS トークンやストレージ アカウント キーなどのシークレットを渡さなくても、カスタム スクリプト拡張機能で Azure Storage プライベート BLOB またはコンテナーにアクセスできるようになります。

この機能を使用するには、カスタム スクリプト拡張機能が実行される VM または仮想マシン スケール セットに、システム割り当て ID またはユーザー割り当て ID を追加します。 その後、Azure Storage コンテナーまたは BLOB へのアクセスをマネージド ID に許可します。

ターゲット VM または仮想マシン スケール セットでシステム割り当て ID を使用するには、managedidentity を空の JSON オブジェクトに設定します。

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

ターゲット VM または仮想マシン スケール セットでユーザー割り当て ID を使用するには、managedidentity を、マネージド ID のクライアント ID またはオブジェクト ID で構成します。

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

Note

managedIdentity プロパティは、storageAccountName または storageAccountKey プロパティと組み合わせて使用しないでください

テンプレートのデプロイ

Azure VM 拡張機能は、Azure Resource Manager テンプレートを使用してデプロイできます。 前のセクションで詳しく説明した JSON スキーマを Azure Resource Manager テンプレートで使用すると、テンプレートのデプロイ時にカスタム スクリプト拡張機能を実行できます。 次のサンプルでは、カスタム スクリプト拡張機能を使用する方法を示します。

PowerShell でのデプロイ

Set-AzVMCustomScriptExtension コマンドを使用して、カスタム スクリプト拡張機能を既存の仮想マシンに追加できます。 詳細については、Set-AzVMCustomScriptExtension を参照してください。

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

複数のスクリプトを使用する

この例では、3 つのスクリプトを使用してサーバーを構築しています。 commandToExecute プロパティでは、最初のスクリプトを呼び出しています。 他の呼び出し方法に関するオプションが与えられます。 たとえば、リード スクリプトで実行を制御し、適切にエラーを処理し、ログを記録し、状態を管理することができます。 スクリプトはローカル コンピューターにダウンロードされ、実行されます。

たとえば、1_Add_Tools.ps1 で、スクリプトに .\2_Add_Features.ps1 を追加することで 2_Add_Features.ps1 を呼び出します。 $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;

ローカルの共有からスクリプトを実行する

この例では、スクリプトの場所にローカル サーバー メッセージ ブロック (SMB) サーバーを使用することをお勧めします。 そうすることで、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

CLI を使用してカスタム スクリプトを複数回実行する

"まったく" 同じ設定が渡された場合、カスタム スクリプト拡張機能ハンドラーはスクリプトの再実行を防止します。 この動作によって、スクリプトがべき等ではない場合に予期しない動作を引き起こす可能性がある誤った再実行を防ぎます。 ハンドラーが再実行をブロックしたかどうかを確認するには、C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\<HandlerVersion>\CustomScriptHandler.log* を参照します。 次のような警告を検索します。

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

カスタム スクリプト拡張機能を複数回実行する場合は、次の条件下でのみ行うことができます。

  • 拡張機能の Name パラメーターは拡張機能の前のデプロイと同じです。
  • 構成が更新されました。 コマンドには、タイムスタンプなどの動的プロパティを追加できます。 ハンドラーによって構成設定の変更が検出された場合は、その変更がスクリプトを再実行する明示的な意志と見なされます。

または、ForceUpdateTag プロパティを true に設定することもできます。

Invoke-WebRequest の使用

スクリプトで Invoke-WebRequest を使っている場合は、パラメーター -UseBasicParsing を指定する必要があります。 パラメーターを指定しないと、詳細な状態をチェックするときに次のエラーを受け取ります。

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

Azure portal からカスタム スクリプト拡張機能をデプロイする場合、ストレージ アカウント内のスクリプトにアクセスするために SAS トークンの有効期限を制御することはできません。 初期デプロイは機能しますが、ストレージ アカウントの SAS トークンの有効期限が切れると、カスタム スクリプト拡張機能がストレージ アカウントにアクセスできなくなるため、後続のスケーリング操作は失敗します。

仮想マシン スケール セットにカスタム スクリプト拡張機能をデプロイする場合は、PowerShellAzure CLI、または Azure Resource Manager テンプレートを使用することをお勧めします。 この方法で、マネージド ID を使用するか、必要に応じてストレージ アカウント内のスクリプトにアクセスするための SAS トークンの有効期限を直接制御するかを選択できます。

トラブルシューティングとサポート

Azure portal から、または Azure PowerShell モジュールを使用して、拡張機能のデプロイ状態に関するデータを取得できます。 VM の拡張機能のデプロイ状態を確認するには、次のコマンドを実行します。

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

ターゲットの仮想マシンの次のフォルダーにあるファイルに拡張機能出力のログが記録されます。

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

ターゲットの仮想マシンの次のフォルダーに指定のファイルがダウンロードされます。

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

前のパスで、<n> は、拡張機能の実行間で変更される可能性がある 10 進数の整数です。 1.* 値は、拡張機能の実際の現在の typeHandlerVersion 値と一致します。 たとえば、実際のディレクトリは、C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.8\Downloads\2 になります。

commandToExecute コマンドを実行すると、拡張機能によってこのディレクトリ (例: ...\Downloads\2) が現在の作業ディレクトリとして設定されます。 この処理により、fileURIs プロパティを使用してダウンロードされたファイルを見つけるときに相対パスを使用できます。 ダウンロードしたファイルの例を次に示します。

fileUris の URI ダウンロードされた相対的な場所 ダウンロードされた絶対的な場所
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

絶対ディレクトリ パスは VM の有効期間を通じて変わりますが、カスタム スクリプト拡張機能の 1 回の実行内では変わりません。

絶対ダウンロード パスは経時的に変わる可能性があるため、可能であれば、commandToExecute 文字列では相対スクリプト/ファイル パスを使用することが推奨されます。 次に例を示します。

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

最初の URI セグメントの後のパス情報は、fileUris プロパティ リストを使用してダウンロードされたファイル用に保持されます。 前の表に示すように、fileUris 値の構造を反映するために、ダウンロードされたファイルはダウンロード サブディレクトリにマップされます。

サポート