PSSnapInを自作する

メモ程度。

1. Visual Studio 2012でクラスライブラリを作る

2. System.Management.Automation と System.Configuration.Install の2つのアセンブリを追加する。(※System.Management.Automation は C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll にあるはず)

3. プロジェクトのプロパティで「ビルド後に実行するコマンドライン」でinstallutil.exeを使ってアセンブリをアンインストールする

c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil.exe $(TargetDir)$(TargetFileName)

※x64なアセンブリの場合はFramework64にしよう

image

※installutilを使ってインストールするので、Visual Studioは管理者権限で起動しておかないとうまくいかない(気がする)

4. デバッグ時に外部プログラムを開始するようにする

C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe

引数は以下のようにしてAdd-PSSnapInで読み込む

-noexit -command add-pssnapin buchizo.SnapinTest

image

5. SnapInクラスを継承したクラスを実装する

using System.ComponentModel;
using System.Management.Automation;

namespace buchizo.SnapInTest
{
	[RunInstaller(true)]
	public class buchizoSnapIn : PSSnapIn
    {
		public override string Description
		{
			get { return "test."; }
		}

		public override string Name
		{
			get { return "buchizo.SnapInTest"; }
		}

		public override string Vendor
		{
			get { return "buchizo"; }
		}
    }
}

 

RunInstaller(true)属性を忘れずに。

6. Cmdletクラスを継承してCmdletを実装する。

using System.Management.Automation;

namespace buchizo.SnapInTest
{
	[Cmdlet("Get", "Test")]
	public class GetTest : Cmdlet
	{
		protected override void ProcessRecord()
		{
			this.WriteObject("Test3");
		}
	}
}

 

細かいのはリファレンス参照で。

とりあえずこれで動く。デバッグ実行もOK

image

Windows AzureのCloud ServicesでVirtual Network

移行とかでDBはやむを得ずそのままでフロントは頑張った系の構成つくろう、つまり Windows Azureのクラウドサービス(Web RoleとかWorker Role)をVirtual Networkに参加させちゃおうという話です。

ついでに同じVirtual NetworkにWindows Azure 仮想マシンも参加させてサービス間通信もしちゃいましょう。

今回想定しているのはざっくり以下のような構成です。

バックエンドのVMはDBとかまぁそういうのを想定。通信の方向性としては双方向で通信できますが、今回はフロントのWebRoleからVMへのアクセスを想定します。

といっても対してすることは無く。Web RoleなどのCloud ServicesでのVirtual Networkへの参加方法と、VMのVirutla Networkへの参加方法、名前解決についてあたりを書こうと思います。

続きを読む →

Windows Azureのホスト名

以前、ロール間通信の話をちょっと書きましたが、なんかもっと簡単にできそうでした。(クラウドサービスが対象です)

Windows Azureのクラウドサービス上で稼働するインスタンスのホスト名は伝統的なピンクぷーどrではなくRedDogの頭文字、RDで始まるランダムなもので、よくわかりませんでした。

ですが、サービス設定ファイル(*.cscfg)のRole要素でvmName属性を使用すると、指定した名前+連番でインスタンスを設定してくれるようです。

サービス設定ファイルの例↓

<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="WindowsAzure18_45" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="3" osVersion="*" schemaVersion="2012-10.1.8">
  <Role name="MvcWebRole1" vmName="KOSMOS">
    <Instances count="3" />
    <ConfigurationSettings>

以下略 

ほうほう。実際にデプロイしてみましょう。

おお、確かにホスト名がvmNameで指定したもの+連番(ゼロオリジン)です!

ちなみにDNSサフィックスは

02158fc001144d09bf43a37f3660d936.penguindrum.3216464207.asiaeast.internal.cloudapp.net

となってますね。

最初の赤字部分はデプロイID、次の青字部分はクラウドサービスの名前です。asiaeastは配置場所(DC)、internal.cloudapp.netはまぁ固定でクラウドサービスの内部って意味でしょうけど、1つよくわからないのがありますね~。普通に考えるとDC内の何かの(たぶん論理)単位ですね。まぁ自身のDNSサフィックス調べれば生成する必要ないのであまり意味はありませんが。

もちろんクラウドサービス内で有効なだけですけど、ちゃんと名前解決もできる=ポートさえ空いていれば通信ができます。

image

これでHOSTSを弄ったり、変なEndpoint定義したりしなくてもいいですね!!

ちなみに、このvmName属性はSDK1.7以降で使えるようです。いろいろ増えてるんだなぁ~。

参考

Azure Guest OS 3.xでARRv3を使う

Windows Azure Advent Calrendar jp: 2012 の #24です。

みなさんご存知の通り、Windows Azureのクラウドサービスおよび仮想マシンでWindows Server 2012が利用できます。

※残念ながらAzure WebサイトはまだWindows Server 2008 R2ベース。

仮想マシンは自分でいろいろ設定して永続化しておけるのでどうってことは無いんですが、みんな大好きクラウドサービスはそういうわけにはいきません。

で、せっかくクラウドサービスのGuest OS 3.xで、Windows Server 2012つまりIIS8が使えるようになったので、ARR(Application Request Router)も対応したものを使いましょーというのが主旨です。

IIS8に対応したARRv3はExternal CacheやURL Rewriteもこれまで通り使えますし、なんといってもWebSocketに対応してるのが嬉しいですね。

とはいえ、IIS8に対応したARRv3はまだBetaなので利用には注意が必要ですが。

続きを読む →

インスタンスのInputEndpointを取得できない

Windows Azure上でインスタンス間通信する場合、相手のIPアドレスがわからないと何もできません。通常IPアドレスはインスタンス起動時に適当に振られるので、RoleEnvironmentを使ってインスタンスのIPEndpointを取得するのですが、どうもInputEndpointから取れなくなったっぽい。

※インスタンスを列挙してそのインスタンスのIPEndpointを取得してIPアドレスをゲットする、という方法ですが他のインスタンスのInputEndpointが取れない。

ぽい、というのは昔とれた気がするんですけど、SDK1.8だと取れないんですよね。いつからか不明だけどVPNが来たりしたSpring Waveのときかなぁ?

というわけでSDK1.8時代のロール間通信はInternalEndpointを明示的に指定して、そいつのIPEndpointを参照しましょう、という感じになります。

取得するコード的にはこんな感じです。

var role = Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CurrentRoleInstance.Role;
foreach (var instance in role.Instances)
{
	foreach (var s in instance.InstanceEndpoints.Values)
	{
		if (s != null)
		{
			Console.WriteLine("{0} = {1}:{2}", s.RoleInstance.Id, s.IPEndpoint.Address.ToString(),
								  s.IPEndpoint.Port);
		}
	}
}

 

サービス定義ファイル(CSDEF)はこんな感じ。

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="WindowsAzure18_45" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2012-10.1.8">
  <WebRole name="MvcWebRole1" vmsize="ExtraSmall">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
          <Binding name="Endpoint2" endpointName="Endpoint2" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
      <InternalEndpoint name="Endpoint2" protocol="http" port="8002" />
    </Endpoints>
    <Imports>
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
    <Runtime executionContext="elevated">
    </Runtime>
  </WebRole>
</ServiceDefinition>

 

テストなので適当にInputEndpointとInternalEndpointを定義してみました。

で、結果はこう。

image

インスタンス0上で実行しました。他のインスタンスのInputEndpointは取れてないですね。でもInternalEndponitは取れてます。

ということで、何かインスタンス間通信したい場合はInternalEndpointをちゃんと定義しましょう、ということで。

ちなみにコンソールアプリとかで

Unhandled Exception: System.TypeInitializationException: The type initializer fo
r ‘Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment’ threw an exception. —
-> System.IO.FileLoadException: Could not load file or assembly ‘msshrtmi.dll’ o
r one of its dependencies.
A dynamic link library (DLL) initialization routine f
ailed. (Exception from HRESULT: 0x8007045A)
   at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeEnvironmen
t()
   at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment..cctor()
   — End of inner exception stack trace —
   at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.get_CurrentRoleInsta
nce()

とか出る場合は以下のようにuseLegacyV2RuntimeActivationPolicyをTrueにすればいいですよ。(結構悩んだ)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">
		<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
	</startup>
</configuration>

 

まぁByDesignという感じみたいです。はい。(外部からの受付用のInputEndpointで内部用のIPアドレスが取れちゃうってのも変な話といえば変ですのでいいんですけどね。)

Visual Studioをあなた好みにしてみよう

 

というわけで Visual Studio Advent Calendar 2012の2日目担当です。何となく作ろうとしてたネタをせっかくだからAdvent Calendarのネタにしちゃおうと思ったら周りが怖い人ばっかりでどうしようでござる。

気を取り直して、2日目の内容は「Visual Studioを自分好みにしちゃいましょう」ということで、拡張機能のご紹介的な内容です。

続きを読む →

ExcelとFiddler使ってTable Storageを視覚化しよう

スバラシイエントリがあったので紹介します。

Windows AzureのTable Storageは便利ですが、視覚化するのはちょっと不便ですね。Visual StudioとかAzure Storage Explorerとか使えば見れますが、普通のオフィスワーカーにはつらいところです。

やっぱりそこはExcelだよね!というところですが、普通にExcel(+PowerPivot)だとTableにアクセスする際の認証を超えることができません。なので、今回のアプローチとしてはFiddlerで認証を中継してExcel PowerPivotでのアクセス時に認証をパスしよう!という感じです。

続きを読む →