Hey, Scripting kiddy! は皆様のPCを通じた悩みなどをScript kiddyのスクリプトで解決しようという企画です。

Script kiddyさんが色んな人の悩みをスクリプトで解決していく様はまさに痛快。関係のない無駄話も彼の魅力の一つです。

※注
これは、Microsoftがやっている「Hey,scripting guy!」のパクリ企画です。

公開日:2008.06.09

横着は世界を救う

Hey, Scripting kiddy! は皆様のPCを通じた悩みなどをScript kiddyのスクリプトで解決しようという企画です。

今日のお便りは南極5号さんからです。

「Script kiddyさん、こんにちは。助けてください。この間事務所に引っ越してきた社員5人のプリンタの設定を変えるようにといわれました。一つ一つ手で設定を変えて行くのは面倒です。どうにかならないでしょうか?」

南極5号さん、こんにちは。Script kiddyは悩んでいます。それは今フリーザーで料理されるのを待っている鶏肉です。Script kiddyはこの鶏肉と2週間前、Script kiddyの家の近くのスーパーマーケットで出会いました。Script kiddyは「彼は絶対にうまい料理になる」そう思いました。そして半額シールが貼られたその肉を家のフリーザーに入れ、今日になってしまったのです。真っ白になった肉、彼は果たしてScript kiddyを許してくれるのでしょうか。ところで、あなたが今プリンタの設定を任されたPCはどれだけ待ってくれるのでしょうか。あなたは引っ越してきた 5人の社員をフリーザーに入れましたか?もし入れていないのなら、数日後あなたは怒り狂った社員に許しを乞うことになるでしょう。しかし、Script kiddyも人のことは言えません。なぜなら、フリーザーは完全ではないからです。今夜Script kiddyは怒り狂った鶏肉に許しを乞うているかもしれません。人間ほどうるさくはないでしょうが。

さて、本題に移りましょう。果たして今迫りくる問題をどう回避するか、Script kiddyはそれを解決するすばらしい方法を持っていますが、ほんの少しの準備が必要になります。

  • プリンタをネットワーク共有しているサーバ
  • ログオンスクリプトが有効なドメインコントローラ

各事務所のプリンタが以下のように設定されているとします。(・がついたものをデフォルトにしたいプリンタとします)

・シアトル本社 - サーバ名: SEATLE01

SEA_CP01(カラープリンタ)
・SEA_MP01(モノクロプリンタ)
SEA_MP02

・ロサンゼルス支社 - サーバ名: LOSANG01

LOS_CP01
LOS_CP02
・LOS_MP01

かつ、各事務所のネットワークセグメントが以下のように設定されているとします。

・シアトル本社
192.168.1.0/24

・ロサンゼルス支社
192.168.2.0/24

次に以下のようなスクリプトを書きましょう。(WSH VBScript)

1:
2: Set objPrinterDic = CreateObject("Scripting.Dictionary")
3:
4: rem プリンタリストの作成
5: printers = Array("SEA_MP01", "SEA_CP01", "SEA_MP02")
6: objPrinterDic.Add "SEATLE01", printers
7: printers = Array("LOS_MP01", "LOS_CP01", "LOS_CP02")
8: objPrinterDic.Add "LOSANG01", printers
9:
10: rem サブネットIPを取り出す
11: ipaddr = GetMaskedIP()
12:
13: rem サブネットIPから接続先のサーバを決定する
14: If ipaddr = "192.168.1.0" Then
15:     serverName = "SEATLE01"
16: ElseIf ipaddr = "192.168.2.0" Then
17:     serverName = "LOSANG01"
18: Else
19:     WScript.Quit 0
20: End If
21:
22: rem プリンタの接続周り
23: Set objNet = CreateObject("WScript.Network")
24:
25: printers = objPrinterDic.Item(serverName)
26:
27: rem エラーが出てても知られたくないの!!
28: rem デバッグの時ははずしてください。
29: On Error Resume Next
30: rem 順にプリンタを接続していく
31: For Each printerName in printers
32:     objNet.AddPrinterConnection printerName, "\\" & serverName & Chr(92) & printerName
33: Next
34:
35: rem 配列の一つ目に設定されているプリンタをデフォルトプリンタにする。
36: objNet.SetDefaultPrinter "\\" & serverName & Chr(92) & printers(0)
37: On Error Goto 0
38:
39: rem 終了
40: WScript.Quit 0
41:
42: rem WMIを使ってPCの設定をぶっこ抜く
43: rem WMIの説明は次回のお楽しみ
44: Function GetMaskedIP()
45:     rem これははずすと途中でエラーが出てまともに動かないのではずさないこと。
46:     rem Errオブジェクトに聞いて対処してください。
47:     On Error Resume Next
48:
49:     Const wbemFlagReturnImmediately = &h10
50:     Const wbemFlagForwardOnly = &h20
51:
52:     strComputer = "."
53:     Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
54:     Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration", "WQL", _
55:                                                                            wbemFlagReturnImmediately + wbemFlagForwardOnly)
56:
57:     For Each objItem In colItems
58:             If objItem.IPEnabled Then
59:                     If Len(Join(objItem.IPSubnet, ",")) > 0 Then
60:                             For Each ip In objItem.IPAddress
61:                                     strIPAddress = ip
62:                                     Exit For
63:                             Next
64:                             For Each ip In objItem.IPSubnet
65:                                     strIPSubnet = ip
66:                                     Exit For
67:                             Next
68:                     End IF
69:             End If
70:     Next
71:
72:     On Error goto 0
73:
74:     rem サブネットIPを返す
75:     GetMaskedIP = CreateMaskedIPAddress(strIPAddress, strIPSubnet)
76: End Function
77:
78: rem IPアドレスとサブネットマスクからサブネットIPを作る
79: Function CreateMaskedIPAddress(ipAddr, subnetMask)
80:     ipBits=Array("", "", "", "")
81:     ipaddressbits = Split(ipAddr, ".")
82:     subnetmaskbits = Split(subnetMask, ".")
83:
84:     For i = 0 to 3
85:             ip=ipaddressbits(i)
86:             subnet=subnetmaskbits(i)
87:             rem 論理Andでマスク
88:             maskedbits=(CInt(ip) And CInt(subnet))
89:             ipBits(i)=CStr(maskedbits)
90:     Next
91:
92:     CreateMaskedIPAddress=Join(ipBits, ".")
93: End Function

できましたか?このスクリプトはクライアントPCのネットワークアダプタから有効なIPアドレスを取り出し、サブネットからプリンタ接続先を決定します。このスクリプトをあなたがシアトル本社から実行し、複数のプリンタがプリンタの一覧に意図した通りに表示されればOKです。それをログオンスクリプトに追加してください。

ちなみにコード中に出てくるChr(92)は単一文字\(バックスラッシュ)と同一です。"\"と書いても問題ない場面なのですが、Script kiddyは大人の事情でこういう書き方を避ける術を得ませんでした。なぜこの書き方が必要になったか、見事に言い当てた初めての人には、その洞察力を評して今フリーザーの中にある鶏肉を差し上げましょう。そのときにまだ食べ終わっていなければですが。

さて、いかがでしょうか。これであなたがユーザをフリーザーに入れなくても怒られることはなくなると思います。

それではScript kiddyはコンビニ弁当でも食べて寝ることにします。

※ サーバ名のシアトルとロサンゼルスのスペルがおかしいですが、これはサーバ名8文字ルールに従うために短くなっています。スルーしちゃってください。


※注 これは、Microsoftがやっている「Hey,scripting guy!」のパクリ企画です。 ご意見、ご要望はお問い合わせよりお願いします。