System Center OrchestratorからPowerShellでAzure管理コマンドを実行する

PowerShellのAzure管理用モジュールを実行するにはPowerShell3.0以上が必要になります。最新のOSで作業していると気づかない人もいるかもしれませんが、むりやりVersion 2のPowerShellで実行してみるとエラーメッセージにしっかり書かれています。

requires a minimum PowerShell version of '3.0' to execute.

PS > powershell -v 2 -c Import-Module Azure
import-module : The version of the loaded PowerShell is '2.0'. The module 'C:\Program Files\Microso
ft SDKs\Azure\PowerShell\ServiceManagement\azure\azure.psd1' requires a minimum PowerShell version
of '3.0' to execute. Please verify the installation of the PowerShell and try again.
At line:1 char:14
+ import-module <<<<  azure
    + CategoryInfo          : ResourceUnavailable: (C:\Program File...zure\azure.psd1:String) [Imp
   ort-Module], InvalidOperationException
    + FullyQualifiedErrorId : Modules_InsufficientPowerShellVersion,Microsoft.PowerShell.Commands.
   ImportModuleCommand

 
 
新しいOS使っている分には普段は困らないのですが、System Center OrchestratorのRunbookでよく使う、「.NETスクリプトの実行」のActivityからPowerShellでAzureを管理しようとすると同じエラーになります。

というのも「.NETスクリプトの実行」で実行するPowerShellはバージョン2なのです。

実際に以下のスクリプトでバージョンを確認してみます。

$Version = $PSVersionTable.PSVersion.Major

f:id:yomon8:20141225191051p:plain
 
このようにバージョン2のPowerShellが内部で実行されていることがわかります。
f:id:yomon8:20141225191054p:plain

 
 
これをOSの最新のバージョンのPowerShellで実行するようにするにはスクリプトブロックを使う方法があります。具体的には以下のような書き方になります。

$Version = PowerShell -Command {
    return $PSVersionTable.PSVersion.Major
}

f:id:yomon8:20141225191057p:plain
 
これで実行するとVersionが4になっていることがわかります。実際にAzure関連のコマンドレットも使えるようになります。
f:id:yomon8:20141225191101p:plain



例えば、このようなPowerShell組めば、Azureコマンドを「.NETスクリプトの実行」から実行できます。

#Get-AzurePublishSettingsFileで取得したファイル
$SettingFile = "C:\work\xxx-credentials.publishsettings"
$SubscriptionName = "subscriptionName"

$ResultArray = PowerShell -args $SettingFile,$SubscriptionName -command {
    param($SettingFile,$SubscriptionName)
    $Message = @()
    $VMs = $null
    try
    {
        $Message += "Azure接続処理"
        Import-Module Azure
        Import-AzurePublishSettingsFile $SettingFile
        Select-AzureSubscription $SubscriptionName

        $Message += "Azure仮想マシン取得"
        $VMs = Get-AzureVM 
    }
    catch
    {
        $Message += $error[0].Exception.tostring() + $error[0].InvocationInfo.PositionMessage
    }
    $ResultHashTable = @{Message=$Message;VMInfo = $VMs}
    return $ResultHashTable
}


#スクリプトブロック内の標準出力も返り値に入るので
#必要な部分だけ取得
foreach($item in $ResultArray)
{
    $item.GetType()
    if($item.GetType().Name -eq "HashTable")
    {
        $Message = $item["Message"]
        $VM = $item["VMInfo"]
    }
}