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 Server 2008 R2
  • Windows Server 2012
  • Windows Server 2012 R2
  • Windows 10
  • Windows Server 2016
  • Windows Server 2016 Core
  • Windows Server 2019
  • Windows Server 2019 Core
  • Windows Server 2022
  • Windows Server 2022 Core
  • Windows 11

スクリプトの場所

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

インターネット接続

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

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

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

ヒントとテクニック

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

拡張機能のスキーマ

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

機微なデータは、保護された構成に格納できます。この構成は暗号化され、仮想マシン内だけで復号化されます。 保護された構成は、実行コマンドにパスワードや 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 つだけです。 同じ VM に対して、同じ Resource Manager テンプレートにカスタム スクリプトを 2 回指定すると失敗します。

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

プロパティ値

名前 値または例 データ型
apiVersion 2015-06-15 日付
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

clientId (省略可能、文字列): マネージド ID のクライアント ID。

objectId (省略可能、文字列): マネージド ID のオブジェクト ID。

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

  • commandToExecute
  • fileUris

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

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

プロパティ: managedIdentity

Note

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

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

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

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

例:

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

ターゲット仮想マシンまたは仮想マシン スケール セットでユーザー割り当て 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.

仮想マシン スケール セット

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

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

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

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

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

サポート

この記事のいずれかの部分に関するヘルプが必要な場合は、Azure コミュニティ サポートで Azure のエキスパートに問い合わせることができます。

Azure サポート インシデントを送信することもできます。 その場合は、 Azure サポートのサイト に移動して、 [サポートの要求] をクリックします。 Azure サポートの使用方法の詳細については、「Microsoft Azure サポートに関する FAQ」を参照してください。