【IDM】MSMQ を使って確実なユーザー登録を行う その4 ~ メッセージの送信


MSMQを使用してユーザー登録を工夫しようシリーズの第4回目です。

前回の登録から..なんと半年...Tech・Ed 2008 では「続き待ってます」と言われておりました...すみませんです。他にも書きかけの記事があったりもして...えーと、えーと、干支が変わる前になんとかしたいかなぁと思う今日この頃です(あ、なんか今日 冴えてるかも!)。

前回までの記事は以下の通りです。

今回は、VBScript(PowerShellじゃないところがニクいじゃぁありませんか)を使用してMSMQでメッセージを送信してみます。

■メッセージを送信してジョブを作成する

第3回の後半で使用したスクリプトを見てみましょう。拡張子はvbsです。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

Const MQ_RECEIVE_ACCESS  = 1 
Const MQ_SEND_ACCESS     = 2 
Const MQ_PEEK_ACCESS     = 32 
Const MQ_ADMIN_ACCESS    = 128
Const MQ_DENY_NONE           = 0 
Const MQ_DENY_RECEIVE_SHARE  = 1

set objQueueInfo = CreateObject("MSMQ.MSMQQueueInfo")
set objMsgQueue = CreateObject("MSMQ.MSMQQueue")
set objMessage = CreateObject("MSMQ.MSMQMessage")

objQueueInfo.PathName = "junichia03\private$\Input"

'objQueueInfo.Formatname = "DIRECT=OS:junichia03\private$\Input"
'objQueueInfo.Formatname = "DIRECT=HTTP://junichia03/msmq/private$\Input"

set objDist = objQueueInfo.Open(MQ_SEND_ACCESS ,MQ_DENY_NONE)

objMessage.Label = "msg" & date & time
objMessage.Body = "メッセージボディ"
objMessage.Delivery = 1
objMessage.Send(objDist)

objDist.Close

上のスクリプトで重要なのは、2点です。

1点目は、12行目および14/15行目で指定している、キューのパスです。MSMQQueueInfo オブジェクトをいずれかのキューと対応付けるため、PathNameプロパティまたは FormatNamtプロパティを使用してキューのパスを設定しなければなりません。ここで設定したキューは、17行目のOpenメソッドによって初期化され、22行目のSendメソッドでメッセージ送信の宛先として使用されます。

12行目と14/15行目の違いは、パスの設定に PathName を使用しているか、FormatName を使用しているかです。このスクリプトでは、14/15行目がコメントアウトされているので、12行目が使われます。

ローカルコンピューターのプライベートキューをスクリプトから操作する場合には PathNameでもよいのですが、リモートコンピュータのプライベートキューを操作する場合には FormatName を使用します。

まずは PathName から見てみましょう。

PathNameに必要な情報は、「コンピュータ名(NetBios名またはDNS名)」と「キューの名前」です。例えば、Compuer01 に Input という名前のプライベートキューを作成した場合には以下のような指定になります。

  • Computer01\private$\input
  • .\private$\input

private$ は、プライベートキューであることを現しています。MSMQのインストール時に「ディレクトリサービス統合」も同時に組み込んでおり、キューを ActiveDirectory に公開している場合には「パブリックキュー」を作成することが可能です。パブリックキューの場合には、Private$は必要ありません。

また、どうせローカルコンピュータなので、指定を省略して「.\」とすることも可能です。このほうがいろいろなサーバーで使用する場合には汎用的ではあります。

プライベートキューとパブリックキューの違いについて、詳しくはこちらをご覧ください。

さて、次に FormatName です。

リモートコンピュータからプライベートキューにメッセージを発信する場合には、FormatName を使用しなければなりません。おそらく、より汎用的なアプリケーションにするために FormatName を使用することが多くなると思います。MSMQを使用するアプリケーションの場合、メッセージを発信するのはリモートコンピュータとなることが多いでしょうから、FormatName を使うものと覚えてしまってもよいかもしれません。

また FormatNameプロパティを使用すると Direct Format Name という記述形式が使えます。この形式はプライベートキューとパブリックキューのいずれにも使用可能ですが、面白いのはパブリックキューにアクセスする場合に、一旦ディクレクトリサービスから情報を収集することなく「直接」キューと通信が行える形式であるということです。

例えば、インターネット上のコンピュータからキューに対してメッセージを送信することを考えてみると、Active Directory をインターネット上のコンピュータに公開するというのは、ひとまず現実的ではありません。

ただ、ディレクトリサービスにアクセスしないということは、逆にいえば、メッセージをルーティングしたり、メッセージ送信時に認証したり暗号化する際には使用できないということでもありますので注意してください。

FormatName を使用したパスの指定例は以下の通りです。

  • DIRECT=IPX:00000012:00a0234f7500\private$\Input
  • DIRECT=TCP:192.168.1.1\private$\Input
  • DIRECT=OS:Computer01\private$\Input
  • DIRECT=HTTP://Computer01.microsoft.com/msmq/private$\input
  • DIRECT=HTTPS://Computer01.microsoft.com/msmq/private$\input

Direct Format Name を使用すると、プライベートキュー、パブリックキューを問わず、 HTTP やHTTPSを使用してメッセージを送信できるところが便利です。HTTP/HTTPS を使用すると、ファイアウォールの設定でMSMQサービスへの通信が止められていてもメッセージが受け取れるところもよいですね。

ただ、HTTP/HTTPSはメッセージのSendでのみ使用可能であり、PeekやReceive時には使用できないことに注意してください。

参考までに、MSMQで使用されるポート番号についてはこちらをご覧ください。

2点目は17行目です。ここでは、Open メソッドを使用してキューをオープンしていますが、この時にキューのアクセスモードと共有モードを指定します。

Open(アクセスモード, シェアモード)

指定できる値は以下の通りで、これらを用途に応じて組み合わせます。

アクセスモード

  • 1(MQ_RECEIVE_ACCESS):キューからメッセージを読み取った後で削除する
  • 2(MQ_SEND_ACCESS):キューにメッセージを送信する
  • 32(MQ_PEEK_ACCESS):メッセージを参照する(削除しない)
  • 128(MQ_ADMIN_ACCESS):ローカルのキューに対して指定できるモードで、outgoingキュー(メッセージが送信先に出される前に一時的に格納されるローカルのキュー)にスタックされたメッセージを参照したり削除する際に使用する。MQ_PEEK_ACCESS および MQ_RECEIVE_ACCESS ともに指定する。

共有モード

  • 0(MQ_DENY_NONE):すべてのユーザーがキューにアクセス可能
  • 1(MQ_DENY_RECEIVE_SHARE):MQ_RECEIVE_ACCESSで指定可能なオプションで、既にキューがオープンされている場合には他のプロセスからのアクセスを拒否する

このスクリプト例では、メッセージを送信するためにキューをオープンするので、MQ_SEND_ACCESSとMQ_DENY_NONEを指定しています。

19行目~22行目では実際にメッセージを送信していますが、例えばこの部分を以下のように修正すれば、CSVファイルから読み込んだレコードを 1行=1メッセージ としてキューに登録することができます。

Const MQ_RECEIVE_ACCESS  = 1 
Const MQ_SEND_ACCESS     = 2 
Const MQ_PEEK_ACCESS     = 32 
Const MQ_ADMIN_ACCESS    = 128
Const MQ_DENY_NONE           = 0 
Const MQ_DENY_RECEIVE_SHARE  = 1 

set objQueueInfo = CreateObject("MSMQ.MSMQQueueInfo")
set objMsgQueue = CreateObject("MSMQ.MSMQQueue")
set objMessage = CreateObject("MSMQ.MSMQMessage")

objQueueInfo.Formatname = "DIRECT=HTTP://junichia03/msmq/private$\Input"

set objDist = objQueueInfo.Open(MQ_SEND_ACCESS ,MQ_DENY_NONE)

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInputFile = objFSO.OpenTextfile("userlist.csv", 1, false)

Do Until objInputFile.AtEndOfStream

    Rec = objInputFile.ReadLine
    Wscript.Echo Rec
    strUserName = Split(Rec, ",")(0)
    objMessage.Label = "USERADD " & _
               strUserName & " " & _
               date & " " & _
               time
    objMessage.Body = Rec
    objMessage.Delivery = 1
    objMessage.Send(objDist)

Loop

objInputFile.Close
Set objFSO = Nothing

objDist.Close

上記スクリプトを拡張子 vbs で保存し、以下のようなCSVファイルを用意して useerlist.csv というファイル名で保存してください。

testuser001,Password,\\servername\share\testuser001
testuser002,Password,\\servername\share\testuser002
testuser003,Password,\\servername\share\testuser003
testuser004,Password,\\servername\share\testuser004
testuser005,Password,\\servername\share\testuser005
testuser006,Password,\\servername\share\testuser006
testuser007,Password,\\servername\share\testuser007
testuser008,Password,\\servername\share\testuser008
testuser009,Password,\\servername\share\testuser009
testuser010,Password,\\servername\share\testuser010

コマンドプトンプトでスクリプトを実行すると、CSVファイルから読み込まれたレコードが以下のようにキューに登録されます。

csv2msmq

Comments (6)

  1. 匿名 より:

    明日23日が休みだってことに、いま気付きました。 MSMQでユーザー登録シリーズです。で、すいません。最終回じゃないです。 【IDM】MSMQ を使って確実なユーザー登録を行う その1 ~ MSMQ って何してくれるの?

  2. 匿名 より:

    いまさらですが、「忘れられた日本人」という本がおもしろくてたまりません。民俗学なんて高尚な話はひとまずおいといても、面白いです。そして思うことは、はたして自分が80歳になったとき、人に語って聞かせる話を持っているだろうか…Message

  3. 匿名 より:

    さてもう一息ですね。第8回です。 #これまでの投稿一覧はこの投稿の最下段に書いておきます。 前回 作成したスクリプトをキューのルールとして登録する前に、MSMQ運用に必要な知識について書いておきます。知識というよりも、クセですね。

  4. 匿名 より:

    MSMQでユーザーを登録するシリーズです。もうすこしで完結します。 【IDM】MSMQ を使って確実なユーザー登録を行う その1 ~ MSMQ って何してくれるの? 【IDM】MSMQ を使って確実なユーザー登録を行う

  5. 奥主 洋 より:

    私も今MSMQプログラムを作ることになって色々と触っていますが、、、

    汎用性のために

    ◎Set WshNetwork = WScript.CreateObject("WScript.Network")

    WshNetwork.ComputerName を使う

    ◎MSMQApplication.IsDSEnabledをチェックしたほうがいいですね。

    私はExcelで加工してから送る必要があるスキームなのでcsvじゃなくてExcelのVBAで送信をしようとしていますが、ExcelのVBAの場合にはいくつか追加点があります。

    ◎MSMQのライブラリに参照設定をする。この場合、4つあるのでV4の奴(mqoa.tlb)を選ぶ。

    ◎変数はライブラリがConst宣言を含んでいるので不要。MQ_RECEIVE_ACCESSとかです。

    安納がやっているようにVBScriptでやった方がExcelを環境に必要としないので機動性が高く、運用管理面ではお薦めです。

    ただ、VBAを使うと最初にDimで変数宣言をちゃんとやればインテリセンスが使えるのでロジックを書く上では私はVBAの方が楽ですね。もちろんCOMの世界なんですごーくいっぱいVB6を書ける人もいるとは思うのでもちろんVB6で一回書くっちゅうのもありですが。

Skip to main content