Welcome to TechNet Blogs Sign in | Join | Help

管理者は見た!~AD と ILM 一家の秘密~

あらまあ Microsoft Japan の ADSI / ILM / WMI /PCNS
サポートチームのブログなんですってよ奥様!(本当)

★よりぬき ILM 一家さん★

Download 系 Link

おすすめ Blog!

免責事項

必見リンク (AD 系)

必見リンク (WMI)

私たちってこんな人たち

[ILM/MIIS] Anti-Virus ソフト検疫対象外とすべきファイルとフォルダについて

みなさんごきげんよう。ういこです。
日曜日、ちょっと足を伸ばして現小学生の息子の保育園時代の仲間たちとバーベキューとやらをしてまいりました。天気よくて風もなくて、これ以上望めないコンディションでした。
私、これまでの人生で恥ずかしながらそういうアウトドアなことほとんどしたことないんですよね。
考えてみたら、病院か、学校か、家か…。ああ、つまらない人生。大学時代勉強は本当に我ながらやったな!と充実はしましたけど、結局哲学科出ておいて今なんでこんなところにいるんでしょう?ちなみに、折角要卒単位に含まれないのに頑張ってとった社会の教員免許は全く役に立っておりません。
こういう外でみんなで何かするっていうのも悪くないなぁと早く気づいておけばよかったです。

そんな微妙な後悔先に立たずな私が贈る今日の御題はこちら!

【今日の御題】
ILM 2007 (MIIS) のサーバ環境上に Anti-Virus ソフトウエアを入れた場合、スキャン対象除外すべきファイルおよびフォルダは何か。

開発系サポートを長年やってきているからか、サーバ管理者のニーズがまだ把握仕切れていないなと反省しきりなことがあります。やっぱり、開発系のニーズと管理系のニーズは違うのです。
最近もお客様から尋ねられて「たしかに!」とはっとしたのが、この「アンチウイルスソフトを入れた場合、除外すべきファイルやフォルダはあるか」というご質問です。AD / Exchange などでは、そういうサポート技術情報があるらしいのですが、ILM は…と思うと、ズバリそれというものはありません。
ただ、よ~くみると、Notes MA に特化した話のように見せかけてわりと汎用的なドキュメントはありました。
わかりづらいな~。

[1] 除外することが望ましいディレクトリ (2 つ)
1. %userprofile%\Local Settings\Application Data\ApplicationHistory
2. %programfiles%\Microsoft Identity Integration Server\ExtensionsCache

%userprofile% フォルダは、MIIS サービスの実行ユーザー クレデンシャルを指定します。

[2] 除外することが望ましいファイル
1. Miiserver.exe
2. Mmsscrpt.exe
3. Miisclient.exe
4. %programfiles%\Microsoft Identity Integration Server\Data\MicrosoftIdentityIntegrationServer_log.LDF (※)
5. %programfiles%\Microsoft Identity Integration Server\Data\MicrosoftIdentityIntegrationServer.mdf (※)

(※) SQL Server も ILM と同じ環境に構成した場合
4. および 5. は SQL Server データベース本体とトランザクション ログ ファイルとなります。
これらのファイルは、SQL Server の規定で作成されるデータベース格納フォルダとは異なる場所に保存されるためちょっと注意が必要です。

[3] Anti-Virus ソフトウェアは MIIS 同期に影響するか
上記フォルダ、ファイルを Anti-Virus の検疫対象にしたことによってパスワード同期処理が遅くなるというケースはありましたが、そのほか米国、ヨーロッパなども含め弊社に寄せられた ILM のお問い合わせで Anti-Virus ソフトが同期動作に影響するといった事例はございません。

[4] 参考情報 : Notes MA と McAffee Anti-Virus ソフトの相性の話
Lotus Notes Management Agent may stop working with McAffee Anti-Virus
http://support.microsoft.com/default.aspx?scid=947552

このほか、SQL Server と ILM を同じ環境に構成した場合は上記に加え、 SQL Server に関する除外条件などを合わせればよろしいかと存じます。

Guidelines for choosing antivirus software to run on the computers that are running SQL Server
http://support.microsoft.com/kb/309422/EN-US/

それでは皆様、今週もがんばっていきましょう!

ういこう@隣の小学校は 12 クラス中  8 クラスが学級閉鎖だそうです…。

[WMI-NetAPI] Win32_NetworkAdapterConfigration の結果が重複する 2/(2)

みなさんごきげんよう。ういこです。

久しぶりに天空の城ラピュタを見ています。私ムスカ様が大好きで、某 SNS のファンコミュニティに勢いで入ってそれっきりなくらいラブです。ちなみにぴろとくんは飲み屋でビニール袋でないと触れない激辛チキン食べた際にリアル「目が、目が~」をやったそうです。グッジョブ!

さて、今回は以下のミッションのシリーズ第二回目です。

第一回目はこちら

[WMI-NetAPI] Win32_NetworkAdapterConfigration の結果が重複する 1/(2)http://blogs.technet.com/jpilmblg/archive/2009/11/20/wmi-netapi-win32-networkadapterconfigration-1.aspx

【今回のミッション】
環境上にあるネットワーク アダプタがある条件下ではレジストリにゴミ情報が残り、その結果 WMI の Win32_NetworkAdapterConfigration クラスの取得結果が重複してしまうことがある。
以前問い合わせをした際、その動作自体は OS の規定の動作ということで GetAdaptersInfo()、GetAdaptersAddresses() などを使ってアクティブなデバイスを取得し、そのデバイスから Win32_NetworkAdapterConfigration の情報をフィルタしたいと思っているが、フラグに使おうと思う変数が思うような値を返さず、フィルタ条件として有効にならない状況である。
Win32_NetworkAdapterConfigration のうち、適切なアクティブな状態のアダプタの情報だけフィルタして取得する方法とは何か!

*****************

前回は同じネットワーク アダプタなのに、重複して情報がレジストリに登録されてしまうという話をお伝えしました。
今回は、対処方法についてご案内します。

1) Win32_NetworkAdapter の Availability プロパティをみたらどうかな?
…残念ながらこの方法ではだめです。

最初私が試したのは、Win32_NetworkAdapterSetting の取得の前にWin32_NetworkAdapter をクエリし、各ネットワーク インターフェースの状態を見るということでした。
Availability プロパティは、デバイスの状態を指します。このとき、3 (0x3) が返されたデバイスは、"Running or Full Power" の状態ですので、それを使えばいいかなと思ったのです。
ちなみにこのとき、物理デバイス以外も 3 を返しますので、さらに PhysicalAdapter プロパティが True、すなわち物理デバイスであるかも条件に含めました。
重複してても、現時点で有効ではないデバイスは状態は 3 ではないと考えたのです。
しかし、結果はだめでした。やはり、重複分も検知されてかえってきてしまうのです。DDK のなおきお~さんに伺ったところ、そもそも OS からすれば、OS 停止中に抜かれたデバイスは復帰する可能性もあるので、Running or Full Power として認識したままになるのはおかしいことではないのではないかということでした。
デバイスのことはあまりよくわかりませんが、そういうものなのでしょうか。

ただ、現実的にうまくいかないことから、次の手を考えなくてはいけなくなってしまいました。

2) GetAdapterAddresses() あるいは GetAdapterInfo() の Index を使ってみたらどうかな
※ 注意 : 以下は今後の OS の設計あるいはサービス パックによって動作が変更される可能性があります ※

できなくはないのですが、手を入れる必要がかなりあります。
これらの API を使うと、GetAdapterInfo() API なら IP_ADAPTER_INFO 構造体の Index、GetAdapterAddresses() API なら IP_ADAPTER_ADDRESSES 構造体の ifIndex にネットワーク アダプタ インターフェースのインデックスとして振られる番号をとることができるのですが、このインデックスの振られ方にくせがあるため、ちょいと工夫が必要になります。

通常の流れはこうなると思います。

1. Win32_NetworkAdapterConfiguration にて、Description と、SettingID を取得
2. SettingID を使用し、レジストリから NTEContextList を取得
3. GetAdaptersAddresses() あるいは GetAdaptersInfo() で Index を取得
4. 上記 2. の NTEContextList と 3. で取得した値がマッチするかチェック

引っかかるのは、3. です。たとえば、Windows XP では、65539、Windows 2000 では、16777219 といった値が返ってきてしまうことがあります。

じつは、この "65539"、"16777219"、10 進数では意味のわからない値ですが、それぞれ 16 進数で見ると 65539 = 0x100003、16777219 = 0x1000003 となります。インデックス番号の順番は必ずしも 1, 2, ... n といったような順序ではなく、0x1000003 (Windows 2000)、0x100003 (Windows XP 以降) といった振られ方をされることがあるのです。

<< なぜインデックスが変な値になってるの? >>
Windows 2000 Service Pack 4 以降から OS の設計上の動作が変更され、ネットワーク アダプタ インターフェースのインデックスとして振られる番号は以下のような構成になりました。

PnP インスタンス + ネットワーク アダプタ インターフェースのインデックス

要は、これらの ifIndex やら Index で取れる値そのままを使っても、WMI の index として取得される下位のインターフェース インデックスとそのまま比較できないのです。
また、"PnP インスタンス + インターフェースのインデックス" のフォーマットは、OS ごとに異なります。

・Windows 2000 … 01 000003 = 0x1000003 = 16777219
(01 が PnP インスタンス、それ以降が NIC インデックスです)

・Windows XP / 2003 … 00 01 0003 = 0x10003 = 65539
(00 が常に 0 でデバイスを表します。01 が PnP インスタンス0003 が今回でいうところの NIC インデックスになります)

比較の前に、下位ネットワーク アダプタ インターフェースのインデックスのみ抽出してあげる必要があります。
以下は C++ の例です。

例) Windows 2000 の場合

 

PIP_ADAPTER_INFO pAdapterInfo, pAdapt;

//…(中略) …

if ((Err = GetAdaptersInfo(pAdapterInfo, &AdapterInfoSize)) != 0)

//…(中略) …

// シフトしてIndex 取得、以降 WMI の index と組み合わせる

test = (pAdapterInfo->Index << 16) >> 16;

例) Windows XP 以降の場合

 

PIP_ADAPTER_ADDRESSES pAddress;

//…(中略) …

if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAddress,&AdapterInfoSize)) != 0)

//…(中略) …

DWORD test;

//…(中略) …

// シフトしてIndex 取得、以降 WMI の index と組み合わせる

test = (pAddress->IfIndex << 8) >> 8;

シフトではなくて、マスクでもいいかもです。

3) SetupDi にてデバイスの状態確認を行う
上記の方法はシフト計算なので、C# などでもできなくはないですが (API 呼び出すのはちと骨が折れますが) 、なにぶん OS の将来的な設計変更なんかがあるとリンダ困っちゃいます。
重複情報があっても、デバイス マネージャでは常にデバイスはひとつしか出ません。
そこでこれを応用し、さらに敷居は高いのですが、デバイス マネージャの仕組みと同じく、デバイスの状態を見るという手もあります。

厳密に現在 Active なデバイスの状態を判断するために、Windows Driver Kit (WDK) のSetupDi を使い、WMI の Win32_NetworkAdapter で取得できる PNPDeviceID を与えることによって、判別するデバイスを指定しデバイスを列挙することが出来ればその NIC は有効、出来なければ除外するという処理を行うという手段です。

<< コード例 C++ >>
以下コード例です。IsPresentedNetClassDevice という関数を実装しています。使い方は簡単。Win32_NetworkAdapter クラスの PNPDeviceID を取得し、IsPresentedNetClassDevice() の引数に与えてやってください。現在有効なデバイスであれば True、無効(重複したいらない情報)であれば False を返します。

※ 注意 : SetupDi 系関数をご利用いただくには、Windows Driver Kit を開発環境にインストールしていただく必要があります。

WDK の入手方法 : http://www.microsoft.com/japan/whdc/DevTools/WDK/WDKpkg.mspx

// ←-- コード抜粋ここから

#pragma comment(lib, "setupapi.lib")

#include <setupapi.h>

#include <cfgmgr32.h>

#include <devguid.h>

 

BOOL IsPresentedNetClassDevice(LPCTSTR szTrgetDeviceId)

{

    BOOL bFound;

    DWORD index, result;

    HDEVINFO hDevInfo;

    SP_DEVINFO_DATA DevInfoData;

    TCHAR szDeviceID[MAX_PATH];

 

    bFound = FALSE;

    hDevInfo = NULL;

    if(szTrgetDeviceId == NULL)

    goto Done;

 

    hDevInfo = SetupDiGetClassDevsEx(&GUID_DEVCLASS_NET,

                    NULL,

                    NULL,

                    DIGCF_PRESENT,

                    NULL,

                    NULL,

                    NULL);

    if(hDevInfo == NULL)

    goto Done;

 

    index = 0;

    ZeroMemory(&DevInfoData, sizeof(DevInfoData));

    DevInfoData.cbSize = sizeof(DevInfoData);

    while(0 != SetupDiEnumDeviceInfo(hDevInfo, index++, &DevInfoData))

    {

        ZeroMemory(szDeviceID, sizeof(&szDeviceID));

        result = CM_Get_Device_ID(DevInfoData.DevInst, szDeviceID, sizeof(szDeviceID), 0);

        dbgprint(TEXT("%s\n"), szDeviceID);

        if((result != CR_SUCCESS) || (CSTR_EQUAL != CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, szTrgetDeviceId, -1, szDeviceID, -1)))

        continue;

        bFound = TRUE;

        break;

    }

 

    Done:

    if(hDevInfo)

    SetupDiDestroyDeviceInfoList(hDevInfo);

 

    return bFound;

// ←-- コード抜粋ここまで

ただ、これを VBScript やらでやるというと…↑の関数を DLL とかにして、参照するしかないのかなぁと悩んでます。
WMI や VBScript は、色々なテクノロジーで使えるようになっているので、各テクノロジーをそれぞれ勉強しないとわからないこともあり、「WMI」担当というくくりはちょっときっついなぁと思うこともありますが、日々勉強だなあと痛感しております。おいおい、VBScript でのやり方も考えていこうと思っていますが、ご参考まで。

協力 : WDK サポートチームなおきお~さん (Blog  : Japan WDK Support Team Blog)

ういこう@アパラチャノモゲータ!(フハッ)

[WMI-NetAPI] Win32_NetworkAdapterConfigration の結果が重複する 1/(2)

みなさんごきげんよう。ういこです。

最近というか、ずっと心身ともに調子悪くて困っています。目の前のことを一個一個片付けていったらいずれは終わるのでしょうか。いつ終わるのかわからない螺旋の中をぐるぐる回ってる気分です。
そういえば某恋愛ゲームの女の子も、告白直前の夢で螺旋がどうこうって言ってましたね。螺旋といえば、"覚悟のススメ" くらいしか思いつかなかったんですが。 …わたしはまだ、覚悟完了の境地までは至っておりません。

さて、今日はそんな終わることのない螺旋を思わせる for 文ばっかり想起させる WMI ねたをひとつ。

【今回の問題】
環境上にあるネットワーク アダプタがある条件下ではレジストリにゴミ情報が残り、その結果 WMI の Win32_NetworkAdapterConfigration クラスの取得結果が重複してしまうことがある。
以前問い合わせをした際、その動作自体は OS の規定の動作ということで GetAdaptersInfo()、GetAdaptersAddresses() などを使ってアクティブなデバイスを取得し、そのデバイスから Win32_NetworkAdapterConfigration の情報をフィルタしたいと思っているが、フラグに使おうと思う変数が思うような値を返さず、フィルタ条件として有効にならない状況である。
Win32_NetworkAdapterConfigration のうち、適切なアクティブな状態のアダプタの情報だけフィルタして取得する方法とは何か!
うなる鉄拳!
異音を立てるデバイス!
ただで機械の体をくれるといううまい話に明日はあるか。

*****************

…すみません後半はかなり電波でした…。
まず、どういう現象なのかを順に追ってみてみることにします。
今回は、同じデバイスなのになぜか違うデバイスとしておなじデバイスの情報が複数作られてしまう状況についてお話します。

1) 同じネットワーク アダプタなのに複数接続状態に見えることがある

取り外しできるようなネットワーク アダプタを挿して、そのあと抜いて、また挿すということはよくある操作です。
また、複数ネットワーク アダプタが挿してあるというのも、無線 Lan / 有線 Lan と使い分けることも多いこのご時勢、よくあることでございます。
通常こうした動作で何か超常現象が発生するようなことはありませんが、以下の条件などの場合に、同じデバイスの情報が重複してしまうことがあります。

1. ネットワーク アダプタを挿して、デバイス ドライバをインストール
2. PC の電源をシャットダウン
3. 電源の入ってない PC からアダプタを抜く
4. PC の電源をオン
5. また同じネットワーク アダプタを挿す

こうすると、同一のアダプタが複数接続状態となっている様に見える場合がありました。
これは、電源が落とされた状態でデバイスが抜かれ、無効となる事で OS がデバイスを取り外す際に行うべき処理をおこなう事ができず情報が残った結果となります。
また、確認されているほかの条件としては、複数存在するネットワーク アダプタのうち、インストール時に OS が先に認識したネットワーク アダプタを取り外す、などもあります。
あとから認識されたネットワーク アダプタを取り外してもこの現象は発生いたしません。 ちなみに、デバイス マネージャ上は重複している「はず」のデバイスは 1 個分しか表示されません

2) 何で複数接続状態に見えちゃうの?同じアダプタなのに!

レジストリには、ネットワーク アダプタを識別するために NTEContextList という値が保存されています。
この値は、ネットワーク アダプタが認識された順を示すのですが、OS にてネットワーク アダプタのアンインストール処理が行われないうちにネットワーク アダプタが取り外されてしまうと、次回アダプタを認識時に欠番が生じたことを判断できず、NTEContextList の値が重複してしまいます。
このため、ネットワーク アダプタ情報を重複して取得する結果が生じます。

NTEContextList は、レジストリ上のネットワークアダプタ情報が格納されている領域にて割り振られます。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces

上記レジストリ以下にネットワーク アダプタを示すユニークな文字によってレジストリキーが作成されているのです。
このキー配下に NTEContextList エントリがあります。
重複現象が発生した場合、複数のネットワーク アダプタ配下の NTEContextList 値に対して同一の値が格納されているネットワーク アダプタが存在することになります。
もし、これっぽいなと思ったらレジストリの上記エントリを見てみましょう。どこかに重複しているやつがいるはずです。
ちなみに、これら複数に見えるネットワーク アダプタの情報は、実際には取り外しが認識できずに旧情報が含まれた意味のない情報です。

次回は、これをどうやってお料理するかを見ていきましょう。

つづき ⇒ [WMI-NetAPI] Win32_NetworkAdapterConfigration の結果が重複する 2/(2)http://blogs.technet.com/jpilmblg/archive/2009/11/21/wmi-netapi-win32-networkadapterconfigration-2-2.aspx

ういこう@「流行りの服は嫌いかね?」…ムスカ様のお洋服の趣味ってどうかと思う。

[Win7] NB100 にインストール時に 0x80300001 (※ 自己責任でおねがいします!!※) Ver 2.0

みなさんこんにちは。ういこです。

いま私は自分の実家におります。昨日おばあちゃんのお見舞いに行きがてら、ホーム Lan を工事して引いた親父様が手ぐすね引いて待っていらして、無線 Lan の設定をなりゆきでお手伝いしていたのですが、それが終わらず今日にずれ込んでしまいました。
そしてその流れで、親父様が取材に行くときに使うというネットブック東芝 NB100 というもの(Windows XP 入り HDD モデル) を Windows 7 にしよう!ということで、旦那が無線 Lan の設定に四苦八苦している横で、優雅に Windows 7 をとっとと入れてやろうと思ったら…

ま だ 終 わ り ま せ ん

ホワーイ!?もう日曜の 11 時(午後)ですよ。月曜まで 1 時間切ってます!
というのも、いろいろトラブルが(汗

ちょいとハマったので、もしかして同じようにお困りのかたがいるかも~と思い、今日はごく私的な内容ですが、ご紹介させてください。

1. DVD からのブート
2. パパの HDD のリカバリ領域壊しちゃった
3. 0x80300001 ですってよ奥様、こまっちゃう

1. DVD からのブート
DVD ドライブがないと言われたので、徒歩 5 分の某電気店でバッファローの Windows 7 対応、OS を入れるさいのブート対応確認した DVD を購入。
電源供給 AC アダプタいるかなーと思いましたが、ケチって買いませんでした。
家に帰って PC につなげたら、青い電源ランプはつくけど、なぜかブートしない。
そこで、Windows 起動 → TOSHIBA 画面で、F2 押す → BIOS で、起動の優先順位を "DVD/CD" にする。とにかく HDD より DVD だか CD だかが先にくればよし。F7 / F8 を押すと起動順序が変わります。
でも、DVD からブートしない。
よーく DVD の付属品と紙をみたら、二股の USB がある。どうやら「ダブル給電対応USBケーブル」というらしい。電源が一本の USB 給電で弱い場合はこちらを使えとのこと。幸い、HB100 は右に二つくらい USB ポートがあるので、そこに二本ぶっ挿して、再起動。
これで DVD からブートできるようになりました!!

2. パパの HDD のリカバリ領域壊しちゃった
これに気を良くして、インストーラをどんどんすすめ、HDD のインストールパーティションのところで、もう全領域削除。100GB の領域のほかの 3 GB くらいの領域も削除しちゃいました。うっすら、これリカバリー領域じゃないかなぁと思ったんですが…
あとでこれが恐ろしい事態を招くとも思わず、横でだまらせるためにマスターガンダム(マスターグレード金メッキ仕様、私の作りかけ)を作っている息子は吠えるがセットアップは進む…(大映ドラマのナレーション風)

3.  0x80300001 ですってよ奥様、こまっちゃう
HDD をきりなおし、フォーマット。と…。なぜか [Next] がグレーアウト!どういうことですか?!
左下にエラーの詳細を見れと黄色いリンクが。

"Windows is unable to install to the selected location. Error: 0x80300001."
(↑英語版入れてた)

えーーーーーーーーーーーーーーーーーー!?
なんで!?

まず、既知事例を検索するも US で事例が一件。「解決した」とあるが、どうやって解決したか書いてないよ!?US の担当者!ちゃんと対応ログ書け!と思う。
そして、bing で NB100 で Windows 7 入れた人の意見とかないかなーと思って検索してみるも、なんかこんなトラブルの人だれもいないし。レアエラー!?

そこでいやな予感が。もしかして、なんかのドライバ必要とかって落ち!?しかし、いかんせん、なんのドライバが対応してないか情報が出ず、わからない…
いろいろ探して、これっぽいなぁと思うものをダウンロードしたが、 InstallShield で作られているようで、CAB が展開できず、USB に入れてセットアップのドライバ選択画面でリムーバブル ディスクを指定するも、inf ファイルがないのでドライバがないですと言われてしまう…。

もしかしてこれって
XP の状態でインストールしつつ展開して、ファイル抜いとかないといけなかった?!

いや~な汗が出てくるものの、いろいろ試行錯誤しつつ、結局一度 XP に戻すことを決意。
数字の 0 (ゼロ) キーを押して、電源を入れても…

何 も 出 ま せ ん

まっずーい…その、リカバリー DVD ってついてると思いこんでて…お客様に日ごろバックアップしてくださいねと言っておきながらこれ!お客様すみません!
つーかパパごめん!
いろいろ、FAQ や Bing ったりしたものの、こりゃサポートセンターの方にお世話にならないとダメかな…リカバリー領域戻すのはさすがにわからない(汗 と思っていたところでふと気付く。

もしかして SATA コントローラ…?

BIOS の設定を見たら、SATA Controller Mode が AHCI。規定の OS だと AHCI が設定してある必要があるらしいが(Dynabook のサイトより)Compatibility モードに変更したら、うまくいきました。
どうもその後いろいろみていたら、AHCI だと、PC → DVD は読み込めるけど、DVD → PC の方向だと、HDD が認識できないらしいです。正直よくわかりませんが…。
しかし東芝さんのサイトにあるように、もともとある環境で使いたいときは、 AHCI である必要があるということなので、あくまでも自己責任で。

http://dynabook.com/assistpc/faq/pcdata/006615.htm

そういえば、過日カーネルデバッグ目当てに、プレミアのお客様からまるごと VMware のイメージをいただいたうちのチームのエンジニアが、COM ポートがない!VMWare のプレーヤー上に設定項目もない!とあせったそうですが、正解は BIOS で COM ポートを有効化する、でした。
予想以上に BIOS は重要なんだなぁ…。
久しぶりにこういうセットアップなんかやると焦ります。

ちなみにそのあと、電源コードつないでると思ってたのがコンセント抜けてて、セットアップが途中で止まりやり直す羽目になってさらに 20 分くらい損しました。
電源コード抜けてたことの戦犯探しを激しくしましたが、旦那と父親になだめすかされて現在もセットアップ中。うまくいくといいんですが。もうこれで駄目なら本気で泣きたい(涙) ⇒ 追記 : うまくセットアップはできました。あせったけど。

【今日の教訓】
・リカバリーディスクはシステム存命中につくっとこうね
・インストール中は電源コードがつながっているかちゃんとチェックしよう
・なんか変なものがあったらとりあえず消さないでおく(リカバリー領域ちゃん…)
・BIOS の設定ってすごい大事

[Ver2.0 – 2009/11/24 追記] 結局このパパの大好きな NetBook のセットアップをうちの旦那様に下請けに出したのですが、BIOS のアップデートをしたところ、またもや SATA Controller Mode 設定が Compatibility から、AHCI に戻っており(どうも規定値に戻ったらしい)、その結果折角入れた Windows 7 のブートドライブを認識しなくなって「僕ブートできないよ!」と言われて一瞬あせったらしいです。また Compatibility に変更したらちゃんとご機嫌を直してブートしてくださったそうです。恐るべし BIOS。ご参考まで。

ういこう@それでも NT4 セットアップ中にデバドラ追加するよりは楽だな (※)
(※) MS 入社直後、NT4 セットアップを当時チームメイトだった今の旦那に指令され、その際にするときデバドラ追加しろと言われたんですが、どうやっても F6 (だったっけ) を押すタイミングがつかめず、できないと言ったら旦那に「心眼で見切れ!がんばれよ!」と言われ、とんでもない会社に来たなと思ったです。なんだよ心眼って。今はそんな無体な人いませんけど。旦那はいい人になりました。

[Windows 7] 前夜祭!秋葉原カフェソラーレであなたと握手!

皆さんごきげんよう、ういこです。
気づいたら、Windows 7 が明日ラウンチでございます。そんな緊迫した状況の中、本日 19 時から秋葉原カフェソラーレにおいてシステムビルダー主催の前夜祭が行われます。
ぜひ皆様お越しくださいませ!福引もあるようでございます。

詳細はこちら!
http://www.win7mania.com/launchevent/

ちなみに各ショップさんで、オリジナル前夜祭イベントも開催されるようです。
http://www.win7mania.com/launchevent/sboriginal/

私もいきたいのですが、今日は子供のお迎えなので行けません…。血涙を流したくなるほど残念でございます。 が、チームの誰かは行くみたいです。

Windows 7 は、Beta からいじったりしていますが、製品版、本当にいい感じです。
Windows 98 リリース直前の Windows 95 時代に購入して以来、なんと 11 年ぶりに私も自腹でノート PC (某社の Netbook) を購入し、Windows XP から Windows 7 製品版に入れなおして使っていますが、本当にストレス無く動いてます。ドライバのアンマッチも ACPI ドライバ以外特に無く、また電源関連で変な動作もしていないので満足しています。マウスユーティリティ for Windows XP も動くし。(※ 私のネットブックの場合です。デバイスや構成によって変わる可能性があるので、念のため、各ベンダー様に確認してくださいね。)

動きも軽いし、スペックバリバリじゃないけど軽めのネットブックとの相性の良さにいい意味で裏切られた気分です。社員としての使命感抜きで本当によいです。リモートデスクトップでサーバ管理できればいいや!という方や、Security からシン クライアント Love なあなたにも自信を持って薦められます。

皆さん、よろしくおねがいします!

ういこう@非公式キャラクターかわいい

[ILM/MIIS] Delta Import より Full Import のほうが早いときがある

みなさん御機嫌よう。ういこです。
今日 2009/10/08 はリンゴ台風以来の凄い台風が列島縦断しています。子供の学校はサックリ休みになっております。学童クラブからは、朝 8:30 から預かるが、空気を読んで自粛してほしいというメールを頂きましたが、断腸の思いでお弁当を持たせて行かせてしまいました…。(旦那がバイクで連れて行きました。)お弁当作るのって本当に大変です。奥様に作っていただいている世の旦那様、「いつもありがとう」の言葉と、せめて弁当箱くらいは洗ってあげてくださいね。でないと、微妙に不満や怨念が蓄積されていくかもしれませんよ。洗ってくれなくても言葉くらいはマジでほしいです。語らなくても通じるなんてうそです!!絶対に。ちなみに少なくとも私は蓄積されます。

と、まあ微妙に怨念が台風のように渦巻くのはさておき、今日のお題は、最近本業の ILM を忘れたような感じになってるので、ILM のことについて。

【今日のお題】
Active Directory / ADAM の MA を使ってます。Full Import は遅いので、Delta Import にしたいと思ってますがどうでしょう。

【回答】
結論からいうと、必ずしも Full Import より Delta Import のほうが早いとは限りません
場合によってはむしろ Full Import のほうが早い場合があります。

では、それはなぜか。まず、Active Directory / ADAM のマネージメントエージェント (MA) を例にとり、各 Import 処理はどんなことをしているか見てみましょう。

1. Import の処理ってどんなことをしているの?
・Full Import
ADAM および Active Directory の MA の Full Import では、LDAP API を使用し、接続先ディレクトリに存在するすべての対象オブジェクトに対してクエリーを実行します。たとえば、MA の "Select Object Types" プロパティ シートで指定されているオブジェクト クラスすべてを対象としてクエリーを実行する、というようなことが可能です。
Full Import で収集された情報には、特定オブジェクトに格納されているすべての属性値などがあります。
ILM も、最終更新時に関する情報を格納しているため、この情報は Delta Import でも使用することができます。

・Delta Import
Delta Import では、[Configure Partitions] ダイアログの [Containers] ボタンおよび [Deleted Objects] コンテナで設定されたコンテナのオブジェクトを対象としてクエリーを実行します。ADAM および Active Directory のマネージメント エージェントの Delta Import では、LDAP API と DirSync LDAP コントロールを併用します。DirSync LDAP コントロールを使用することにより、直近に成功した Full Import 以後、変更のあったディレクトリに対してのみ、クエリーを実行することが可能です。このような処理が可能なのは、Import した全オブジェクトのオブジェクト ステート情報を格納しているためです。

…これを見ていただいても、Delta Import は、クエリーを実行するのが、最後の Import 以後に変更の生じた箇所のみであるため、Full Import と比較し、Delta Import の実行時間がかなり短縮されるという以外に、何があるのだろう?といぶかしまれるかもしれません。

しかしながら、この、「最後の Import 以後に変更の生じた箇所」をチェックする、というところが実は誤解しやすいポイントなのです。ディレクトリのすべてオブジェクトあるいは大半が更新されるなど、大量の更新があった場合は Full Import の方が効率的な場合もあります。
実際、Delta Import でも Full Import の実行時間と変わらない場合や、逆に非常に遅くなることまであるのです。

2. Delta Import のコスト
Delta Import についてもう少し詳しく見てみましょう。
Active Directory は、 オブジェクトの属性に Update Sequence Number(USN) を持っています。
Delta Import では、コネクタ スペース (CS) 内のオブジェクトと Import 動作時に AD にアクセスし、USN 値を比較して差分を検出し、差分更新の生じているオブジェクトの Import を実施しています。
データ数が少ない状況ですと、Delta Operation は Full Operation と比較するとこれらの差分確認処理を含めても処理件数、プログラム コードの処理数的にも優位ですが、これが数万件単位になるとこの差分処理がオーバーヘッドとなります。
さらに、アクセスしにいくのは AD だけではありません。CD オブジェクトを参照し、比較する際に SQL Server にクエリを投げるのですが、これも処理コストとしては決して少なくない処理です。結果的に Full Operation よりも処理コストが高い処理になる、というからくりなのです。

まとめますと処理コストとなる要素として大きなものは下記となります。

・AD への USN の参照
・SQL Server に対する CS オブジェクトとの比較クエリ

件数が少ない場合、Delta Import のほうが早いというのは、差分が少なければディレクトリアクセスは抑制され、一連の処理で一番件数が増えて影響を受ける SQL クエリの処理の件数が少ないからです。

こうした事情により、更新オブジェクト数がディレクトリのほぼ全てに及ぶような場合、Delta Operetion の生じない Full Import の方が効率が良いことになります。つまり、若干の更新のみが検出されるような動作や運用初期においては Delta Import を通常操作としつつ、定期的に Full Import を施行する、というのが効率がよい運用ということになります。
なぜならば、定期的に Full Importをかけないと、差分が増加を続けるので、結果的に USN の処理も比例的に増加してしまうためです。

以下が公開されている情報でわりと詳しいものかと思います。

Understanding run profiles in MIIS 2003
http://support.microsoft.com/kb/827118/en-us

※ 補足
なお、AD 側でデータを直接登録、変更などを行った際は Full Import を定期的に行うほうが Delta Import の効率化を図れますが、たとえば AD 側で直接データ変更などを行わず、別のデータソースからのデータを Export のみで更新していくような運用であれば、定期的な Full Import は必ずしも有効ではありません。

・初回、AD 上の全オブジェクトが Export 操作により生成される前提条件であれば、Import 対象のオブジェクトはこの Export 操作により更新されていると判断されます。よって全オブジェクトが要更新対象(差分)とみなされますので、その後 Delta Import を行っても全てのオブジェクト属性が収集されます。

・Full Sync を以前行った日が半年以上前など、Active Directory における既定の TombStone 期間よりも前である場合、ドメインのオブジェクトの移動や削除に関する正しい情報が、データソースから得られないため、CS オブジェクトが無効となる恐れがあります。この場合、一旦 CS オブジェクトを削除し、Full Import と Delta Sync をやり直すことをお勧めします。

3. Delta Import と Full Import の所要時間逆転の閾値はシステムに依存する
残念ながら Delta Import と Full Import の所要時間が逆転する閾値に相当するかどうかの判断は、お客様の動作環境、ネットワーク構成および実際の動作状況から判断する必要があります。
また、ディレクトリ アクセスと SQL 負荷のどちらが、MIIServer サービスに影響を与えているかは、構成に依存するため、帯域、CPU 負荷、ハードディスクアクセスの状態など複数の要素によって状況が左右されるということがあり、ILM の製品的に一意の閾値は存在しません。
実際の運用の実績ベースの RunHistory からの更新件数、処理時間などから、判断する必要があります。

ではみなさんごきげんよう。

ういこう@うずまきといえば伊藤潤二先生だと思う

[~W2K8 / W2K8R2] Windows on Windows (WOW) の最大サポート CPU 基数はいくつ?

皆様御機嫌よう、ういこです。
今日は、せっかく今期から Windows SDK 一家の軒下を借りるようになったので、たまには Windows API についてのことでも書いてみようと思います。
Windows API というか、Windows の仕組みの話になっちゃいますが…。

Windows Server 2008 R2 から、64bit CPU に特化されましたことは、これまでのサーバー製品が 64bit 版にどんどんシフトしていっている流れ的にさもありなん、という感じはあったものの、ついにきたなという思いでした。ただ、64bit CPU が出てかなり時間が経つとはいえ、既存のアプリケーション資産は 32bit でビルドされたもの(32bit Windows 上で動作することを想定して作成されたものという意味)がまだまだ現役で動いている、という状況が大半ではないでしょうか。

Windows On Windows (WOW)
Windows OS では、64bit OS 上でも、32bit アプリケーションを動作させる仕組み "Windows On Windows" というサブ システムがあります。32bit アプリケーションは、このサブ システム上で動作します。あくまでもサブ システムなので、エミュレーションしているようなものです。そのため、厳密に 32bit Windows と同じ動作にはならないことがあることに注意しなくてはなりません。昔、Windows が出始めのころ、コマンド プロンプト上で DOS アプリケーションを動かした方で、挙動が微妙に違うと悩んだかたもいらっしゃるでしょう。それと同じことになることを頭に入れる必要があります。

CPU の最大サポート基数について
サーバー上で動作させるアプリケーションである場合、WOW 上で動作させるにしても、プロセッサを最大限使いたいというかたもいらっしゃると思います。そうした場合、WOW はいったい何基までの CPU をサポートするのでしょうか?
答えは、32 基までとなります。ドキュメントは、残念なことに本社の人にも聞いてみましたが、以下の MSDN のドキュメントくらいしか書いていないようです。

Processor Affinity (プロセッサの親和性)
http://msdn.microsoft.com/en-us/library/aa384228(VS.85).aspx

<--- 抜粋ここから ---->
32-bit Windows supports a maximum of 32 processors.
Therefore, functions such as GetProcessAffinityMask
simulate a computer with 32 processors when called under WOW64.
<--- 抜粋ここまで ---->

・Windows Server 2008 までの場合 (64bit アプリは 64 基、WOW は 32 基)
64 bit Windows OS の内部では、アプリケーションの動作の際に 64bit プラットフォーム上で動作することを前提としてビルドされているか、それ以外を対象としてビルドされたものかという判断を行っています。プロセッサ数は、MAXIMUM_PROCESSORS という定数で設定されており、以下のとおりとなります。

64bit アプリケーションの場合 64 基

それ以外の場合 32 基

・Windows Server 2008 R2 の場合 (64bit アプリは 256 基だが WOW は相変わらず 32 基)
Windows Server 2008 までの Windows の仕組みでは、ロック機構の実装にまだまだ改善の余地があり、64 基以上のプロセッサの場合動作が遅くなる可能性などがあり、上記のように 64 基までということになっていました。しかし、Windows Server 2008 R2 では、ある一人のすごい人がこのロックの実装ロジックを解決することができたそうです。(うわさではその人は勇者としてリアルにアワードをゲットしたとか…)

また、R2 では、CPU が複数あるマルチコア環境下で、Non-Uniform Memory Access (NUMA) の強化が行われています。
NUMA というのは耳慣れない言葉かと思いますが、実は結構前から概念はあったようです。これは、CPU をグループとして管理し、効率よく使おうとする見たいなことのようです。(プロセッサ グループはカーネルが決定) このグループ化の仕方がいい感じになり、1 スレッドを処理するコア = 1 論理プロセッサとして扱い、同一コア中の論理プロセッサ、同一の物理プロセッサ内のコア、物理に近い論理プロセッサなど、近隣の論理プロセッサ同士を同一のグループにすることで、バスのデータ転送の効率を上げようともくろんだようです。ちなみに NUMA グループは "ノード" という言葉で表現されるみたいです。

そして、256 基までサポートされるならば WOW もあわよくばサポート基数が増えたのでは…と思ったのですが、残念ながら WOW はあいかわらず 32 基でございます。
また、物理スロットは 64 基までです。なのに 256??

…実は、この 256 のからくりは、64 基 x 最大 4 ノード = 256 基、ということでして、なぜ WOW は 32 基なのかというと、32 基 x 1 ノード = 32 基ということだったりするのでした。

WOW 上での動作を見る際はお気をつけくださいませ。

ういこう@明日は小学校が臨時休校!?

[WMI] C++ で 2 つ以上の引数を与えてメソッドを実行するには? 2 / (2)

みなさん御機嫌よう、ういこです。
前回はお題が WMI C++ で 2 つ以上の引数をメソッドに与える方法についてなのに、VBScript やら C# やらで書いていてどうよ?って思われた方もいらっしゃるかと思います。すみません。

【お題 : C++ で WMI - メソッドに二つ以上引数を渡したいの】
前回はこちら。タイトル変えました。
[WMI] C++ で 2 つ以上の引数を与えてメソッドを実行するには? 1 / (2)
https://blogs.technet.com/jpilmblg/archive/2009/10/06/wmi-c-2-1-2.aspx

※ 前回のあらすじ ※
Windows を管理するには最高のパートナーの WMI。しかし、その実態は某大戦中の某国の大型戦車のように威力はすごいが足が遅かった!1 ターンでの移動力が 1 Hex 位しか進まないとまでは行かなくても。そんな WMI を改良すべく、スクリプトだと量がすごいすくないのはわかっていても、あえて C++ で動かそうと考えた熱い魂をもつ漢(おとこ)たち。しかし、MSDN には引数を一個しか指定しない感じのサンプルしかない。C# とかも微妙に参考にならない感じだ。
どうする!?

【はじめに】
早速、ExecQuery を…と思う前に、まあまあはやる心を抑えましょう。
C++ の場合は、自分で認証情報などをつけないといけないのです。C# や、VBScript などでよしなにしてくれた処理も、自分でやらなくてはならないのです。そこが大変な上に、コード量ももりもり増えます。

・IWbemService のプロキシが使用する認証情報を明示的に設定する必要がある。

(特に、リモートでアクセスする場合など)
WMI のプログラムのプロセス実行ユーザーがリモート コンピュータの管理者権限を持たない場合は、ConnectServer() で    管理者権限を持つユーザーの名前とパスワードを指定していても、ExecQuery() でアクセス拒否されてしまいます。
リモート コンピュータ上の情報を取得する際には、リモート コンピュータ上の WMI の実装が DCOM 経由で呼び出されます。この際、リモート コンピュータ上で実行されるスレッドのユーザーは適切な権限を持つユーザーである必要があるのです。この、リモートコンピュータ上で実行されるスレッドのユーザーを指定するには、CoSetProxyBlanket() を使用します。

ちなみに CoSetProxyBlanket() の第 7 引数がポイントです。NULL を指定した場合は「ローカル コンピュータ上で実行しているユーザー」として、リモート コンピュータ上でもスレッドを実行することを意味します。実行ユーザーとは別のリモート コンピュータ上で管理権限を持つユーザーとして、リモート コンピュータ上のスレッドを実行するには、CoSetProxyBlanket() の第 7 引数でユーザーを明示的に指定してあげてください。
それと、ふるーいバージョン Service Pack などがないの Windows XP では CoQueryProxyBlanket() の第 2 引数に DWORD のポインタを渡すように対応してください。Windows Server 2003 では修正されて出荷されているのですが、NULL を渡すと Access Violation が発生する不具合があります。XP のサービスパックなしバージョンなどで動作させようとすることもシステム要件に含む場合は注意してください。

1. ExecQuery() メソッドで、以下の WQL 文を発行します。

例 :
仮想マシン名「Windows Server 2003 (x86)」に対してシャットダウンを行う場合

    1 IEnumWbemClassObject* pEnumerator = NULL;

    2 hres = pSvc->ExecQuery(

    3 bstr_t("WQL"),

    4 bstr_t("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='Windows Server 2003 (x86)'"),

    5     WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,

    6     NULL,

    7     &pEnumerator);

2. IEnumWbemClassObject から仮想マシンの GUID (Name) を列挙し、Get() メソッドで VARIANT 型の変数に格納します。

   10 IWbemClassObject *pclsObj = NULL;

   11 ULONG uReturn = 0;

   12 

   13 VARIANT vtProp;

   14 

   15 while (pEnumerator)

   16 {

   17     HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

   18     if(0 == uReturn)

   19     {

   20         break;

   21     }

   22 

   23     // Get the value of the Name property

   24     hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);

   25     wcout << " VM's Name : " << vtProp.bstrVal << endl;

   26 

   27     pclsObj->Release();

   28     pclsObj = NULL;

   29 }

3. 上記ステップ 2. で取得した仮想マシン名を用いて、Msvm_ShutdownComponent クラスをクエリします。

   32 IEnumWbemClassObject* pVmshout = NULL;

   33 bstr_t WQL = _T("SELECT * FROM Msvm_ShutdownComponent WHERE SystemName='");

   34     WQL += vtProp.bstrVal;

   35     WQL += _T("'");

   36 

   37     VariantClear(&vtProp);

   38 

   39     hres = pSvc->ExecQuery(bstr_t("WQL"),

   40                         WQL,

   41                         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,

   42                         NULL,

   43                         &pVmshout);

4. IEnumWbemClassObject を列挙し、Msvm_ShutdownComponent クラスのパスを取得します。

   44     hr = pclsObj->Get(L"__Path", 0, &vtProp, 0, 0);

※ デバッガ上でみたクラスのフルパス = vtProp のデータ例 (実際には改行はありません) 検証端末名 : UIKOUTEST2008

   46     vtProp BSTR = "\\UIKOUTEST2008\root\virtualization:    Msvm_ShutdownComponent.CreationClassName="Msvm_ShutdownComponent",    DeviceID="Microsoft:9F8233AC-BE49-4C79-8EE3-E7E1985B2077",

5. ConnectServer() の呼び出しの際に指定した IWbemServices オブジェクトを用いて Msvm_ShutdownComponent クラスを取得します。

   50 bstr_t ClassName = _T("Msvm_ShutdownComponent");

   51 

   52 IWbemClassObject* pClass = NULL;

   53 hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);

 

6. ステップ 5. で取得した Msvm_ShutdownComponent クラスの InitiateShutdown() メソッドを取得します。

 

   56 bstr_t MethodName = _T("InitiateShutdown");

   57 

   58 IWbemClassObject* pInParamsDefinition = NULL;

   59 hres = pClass->GetMethod(MethodName, 0,

   60 &pInParamsDefinition, NULL);

 

7. SpawnInstance() を使用してインスタンスを取得します。

 

   63 IWbemClassObject* pClassInstance = NULL;

   64 hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance);

8. InitiateShutdown() メソッドの引数をPut() メソッドを使用して指定します。
以下の例では、InitiateShutdown() メソッドの引数 Force に true を、第二引数 Reason に文字列を指定します。なんと、わかれば単純!この形式でどんどん Put していけばよいのですね。

   67 // Create the values for the in parameters

   68 VARIANT varCommand;

   69 varCommand.vt = VT_BOOL;

   70 varCommand.boolVal = true;

   71 hres = pClassInstance->Put(L"Force", 0,&varCommand, 0);

   72 VariantClear(&varCommand);

   73 

   74 varCommand.vt = VT_BSTR;

   75 varCommand.bstrVal = L"Because I want to do it.";

   76 hres = pClassInstance->Put(L"Reason", 0,&varCommand, 0);

   77 VariantClear(&varCommand);

 

9. ステップ 4. で取得した Msvm_ShutdownComponent クラスのパスを ExecMethod() に指定し、InitiateShutdown() メソッド (第二引数 MethodName) を実行します。

   80 IWbemClassObject* pOutParams = NULL;

   81 hres = pSvc->ExecMethod(vtProp.bstrVal, MethodName, 0,

   82 NULL, pClassInstance, &pOutParams, NULL);

【注意点】
・ドメイン非参加の PC からリモート PC 上の管理者権限ユーザを指定してもアクセス拒否されることがある

ちなみにドメインに参加していない PC (Windows XP など) の既定の設定では、ネットワーク経由でのアクセスの際に認証されたユーザーはリモートコンピュータ上で Guest の権限のみを持ちます。このため、WMI を使ってリモート コンピュータ上の情報を取得する際に、リモート コンピュータ上での管理者権限を持つユーザーを指定してアクセスした場合でも、アクセスを拒否されることがあります。
この設定はローカル セキュリティ ポリシー管理ツールの以下の項目で変更可能です。

[セキュリティの設定]
- [ローカルポリシー]
- [セキュリティ オプション]
- [ネットワーク アクセス:ローカル アカウントの共有とセキュリティ モデル]

この項目を、「クラシック - ローカルユーザーがローカルユーザーとして認証する」に変更することで、ネットワーク アクセスの際に認証されたユーザがリモートコンピュータ上で、認証されたユーザーとしての権限を持つように変更できます。
なお、ドメインに参加している Windows XP 上ではネットワーク アクセスの際に認証されたユーザーは、リモートコンピュータ上でそのユーザーとしての権限を持ちます。ちなみに、Windows Server 2003 のデフォルトの設定では、この設定は「クラシック」に設定されています。

参考 :
エラー メッセージ : Access Denied; Specified User Is Not a Member of TelnetClients Group
http://support.microsoft.com/default.aspx?scid=kb;ja;298060

image 

image

【おまけ : 一連の処理をもっとわかりやすくしてみたです & 行番号がないコピペ対応版】

BSTR methodName = SysAllocString(L"InitiateShutdown");

BSTR className = SysAllocString(L"Msvm_ShutdownComponent");

 

IWbemClassObject *pClass = NULL;

hres = pSvc->GetObject(className, 0, NULL, &pClass, NULL);

 

IWbemClassObject *pInParamsDefinition = NULL;

hres = pClass->GetMethod(methodName, 0, &pInParamsDefinition, NULL);

 

IWbemClassObject *pClassInstance = NULL;

hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance);

 

VARIANT varCommand;

varCommand.vt = VT_BOOL;

varCommand.boolVal = true;

VARIANT varCommand2;

varCommand2.vt = VT_BSTR;

varCommand2.bstrVal = L"Because I want to do it.";

 

pClassInstance->Put(L"Force",0,&varCommand,0);

pClassInstance->Put(L"Reason",0,&varCommand2,0);

 

hres = pclsObj->Get(L"__PATH", 0, &vtProp, 0, 0);

 

IWbemClassObject* pOutParams = NULL;

hr = pSvc->ExecMethod(vtProp.bstrVal, methodName,0,NULL,pClassInstance,&pOutParams,NULL);

if (FAILED(hr))

{

wcout << " Could not shutdown" << hex << hr << endl;

}

 

_bstr_t bstrret("ReturnValue");

BSTR ret;

hr = pOutParams->GetObjectText(0, &ret);

cout << "Return Value: " << ret << endl;

 

VariantClear(&varCommand);

VariantClear(&varCommand2);

pclsObj->Release();

pclsObj = NULL;

以上です。

それにしても、なんだかブログへの風当たりが強い今日この頃。わかりやすくて、使えるブログを目指しておりますので、皆さんこれからも応援していただければ幸いです。

ういこう@I Love メカニカルキーボード

[WMI] C++ で 2 つ以上の引数を与えてメソッドを実行するには? 1 / (2)

みなさん、大変ご無沙汰しておりました。ういこです。
しばらく心身ともに調子が悪く、ブログもやめようかな…と悩んでおりました。
しかし、会計年度も変わり、そろそろ年末も見えてきたあたりで復活しようかなと思いつつあります。またひとつよろしくお願いいたします。

なぜか前会計年度では Windows Media テクノロジーのサポートチームと同じチームでしたが (※ US も同じ構成ですが、いまだになぜ一緒なのか謎) 今期から Windows SDK のチームとさらにくっつき、最近は普通に API 案件などもやっていたりします。なぜ Windows Media と ILM / ADSI、Windows SDK が一緒なのか、それはきっと足が飾りだと思う必要がないレベルのえらい人にしかわからない何か事情があるんでしょう。というわけで、今後は SDK 案件も書いていくことになると思いますがよろしくお願いします。

…相変わらず前置き長くてすみません。本題に入らせていただきますです。
さて復活第一弾は、ILM ねたでいこうかなと思いましたが、現在稼働中の案件もいくつかあるので、あえて WMI を。…今回も文章、長いですよ…。というか、一回にしようと思いましたが、コード長すぎなんですみません。

続きはこちら。タイトル変えました。
[WMI] C++ で 2 つ以上の引数を与えてメソッドを実行するには? 2 / (2)
http://blogs.technet.com/jpilmblg/archive/2009/10/06/wmi-c-2-2-2.aspx

【お題 : C++ で WMI - メソッドに二つ以上引数を渡したいの】
WMI。それはシステム管理者様にとって、一見いいことずくめな感じなもの。スクリプトを気合で組めば、何だって自動化できちゃうぞ!人のマシンだってシャットダウンできちゃうぞ(※注 : それ相応のシステムの管理権限必要)!と、野望や夢も膨らむってもんですが、問題はえっらい遅いこと。
そんな「WMI 遅い」問題に果敢に挑み C++ で実装いただいている漢(おとこ)たちもいらっしゃいます。(あるいはこれまでの既存 C 資産に WMI を組み込む必要がある方々など…。)しかし、いかんせんコード量が多い。多いのです。スクリプトや、.NET Framework アプリとして C# や VB.net などで組んだ場合と比較してコード量が半端じゃありません。

何気に WMI はドキュメントが多いほうです。C++ も例外ではありません。英語ばっかりではあるものの拳でわかりあうように、コードをとりあえずコピペして動きに思いを馳せるってやりかたができるので割と敷居は低いほうのプロダクトです。
ただ、C++ の場合、メソッドを実行したいと思っても、複数個引数を与えるメソッド実行、どうやったらいいかって思ったことありませんか?今回は、C++ で WMI、複数引数でメソッド実行について、Msvm_shutdownComponent の InitiateShutdown() メソッドを例にとり、二回に分けてお話させていただきます。

例を挙げましょう。Windows Server 2008 の Hyper-V 上の OS をシャットダウンするというものです。 それぞれ、wmic コマンドを使った場合、VBScript の場合、C# の場合から見ていきます。C++ は次回のお楽しみです。

[1] WMIC コマンドの場合
WMIC コマンドを使った例です。まず、仮想マシンの名前が "Windows 7" のものをシャットダウンします。

1. GUID をゲットする
仮想マシン名から、仮想マシンの GUID をとってきます。このとき、Msvm_ComputerSystem を使います。

※注意 : 必ずコマンドプロンプトは権限を昇格させ、管理者で実行してください。

wmic /namespace:"\\root\virtualization" path Msvm_ComputerSystem where ElementName='Windows 7' get name

image

2. Msvm_shutdownComponent を使って、上記 1. を使いシャットダウンさせます。

メソッドは InitiateShutdown です。一つ目の引数 true は強制終了の意味、二つめはあのよくサーバを落とす際にかかされる「終了の理由」です。下記の引数に与えているオレンジ色の GUID は、上記 1. でとってきた GUID をコマンド プロンプトからコピペしてきたものです。

wmic /namespace:\\root\virtualization path Msvm_shutdownComponent where systemname='5EDE3587-0CF3-4C0A-913F-9BEAB8E84C83' call InitiateShutdown true,"てすと"

image

↑ただしく実行されると、ReturnValue = 0 で返されてきます。

↓シャットダウンされます

image

[2] VBScript の場合
wmic だと二行ですが、ちょいと増えます。ただ、systemname にあたるところも変数を使えるので、いちいち人間が name を取得してコピペしないですむので、作成の工数はかかりつつ、その後は格段に楽です。

' <==== ここから
Option Explicit
Dim vmshut
Dim VMName
Dim WMIObject
Dim VM
Dim VMList
Dim vmReturn

VMName = "Windows 7"

Set WMIObject = GetObject("winmgmts:\\.\root\virtualization")
Set VMList = WMIObject.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & VMName & "'")
VM = VMList.ItemIndex(0).Name
Set vmshut = WMIObject.ExecQuery("SELECT * FROM Msvm_ShutdownComponent WHERE SystemName='" & VM & "'")
vmReturn = vmshut.ItemIndex(0).InitiateShutdown(True,"てすと")
' <====
ここまで

[3] C# の場合
うわ、ながっ!って思うかも知れません。自分でも今見て、ながっ!と思いましたが、まだまだこれからです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Management;

namespace ShutDownVM
{
   public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
           // root\virtualization クラスにスコープをあわせる
            ConnectionOptions options = new ConnectionOptions();
            ManagementScope scope = new ManagementScope(@"\\localhost\root\virtualization");
            scope.Connect();

           // Msvm_computersystem クラスを用いて、name を取得
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope,
            new ObjectQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = 'Windows 7'"));
            IEnumerator enumr = searcher.Get().GetEnumerator();
            enumr.MoveNext();
            ManagementObject msvm_computersystem = (ManagementObject)(enumr.Current);
            ManagementObjectCollection collection = msvm_computersystem.GetRelated("Msvm_ShutdownComponent");
            ManagementObjectCollection.ManagementObjectEnumerator enumerator =
            collection.GetEnumerator();
            enumerator.MoveNext();
            ManagementObject msvm_shutdowncomponent = (ManagementObject)enumerator.Current;

            // InitiateShutdown() メソッドの引数を指定
            ManagementBaseObject inParams =
            msvm_shutdowncomponent.GetMethodParameters("InitiateShutdown");           
            inParams["Force"] = true;
            inParams["Reason"] = "てすと";

            // InitiateShutdown() メソッドの実行
            ManagementBaseObject outParams =
            msvm_shutdowncomponent.InvokeMethod("InitiateShutdown", inParams, null);
            uint returnValue = (uint)outParams["ReturnValue"];

           // 処理失敗した場合は 0 以外が返ります
           if (returnValue != 0)
                        Console.WriteLine("失敗したよ");

            }
        }
    }

これを見ると、メソッドをただ実行するのではなく、以下の段階を踏んでいることがわかるかと思います。

1. メソッドの引数 (上記例だと、inParams) を指定する
2. メソッドを実行する

次回は、これを C++ でやるとどんな風かというのを、C++ 固有の処理も含めてご紹介させていただきます。

さて、このブログを初めてごらんいただく皆様もいらっしゃるかと思います。また、気がついたらブログ開設から一年とっくに過ぎておりました。
当初、ILM / MIIS という率直に言って決して今のところ、裾野が広いとは言い切れない分野に情報が提供できれば、またサポート契約でどうしても対応できない範囲やわかっていればお問い合わせいただく手間も必要ないような FAQ な事例などをご紹介しようと思い始めたブログですが、気がついたら WMI やら PowerShell やら担当製品が微妙に増加してしまい、今となっては何でもありというかそもそも、technet である必要があるのかもさっぱりわからないカオスな状態になっています。文章もカオスで、マイクロソフトのサポートチームなのか胡散臭いかもしれませんが、お役立ち度数は文章の胡散臭さの絶対値以上のものを目指しております。
今後ともよろしくお願いいたします!

ういこう@某国民的 GF な恋愛ゲームを誕生日プレゼントにだんなからもらいました

[PowerShell] PowerShell のコマンドって?

こんにちは、ILM一家のパパ(お父さん)です。

昨日、連休が明け、久しぶりに ILM一家のメンバーと顔を合わせました。
普段、リアル家族より長い時間を過ごす仲間で、なんか安心します。

リアル家族といえば、先月、娘のペットのハムスターがお亡くなりになり、新しい子をお迎えすることとなりました 。
行き着けのペットショップに行くと、そこには星となったハムスター(没名”ココア”ですが)と瓜二つのの子が...
結局、その子が新たな家族の一員となり、名前を "マロン" としたのですが、あまりにも前の子とそっくりなので、娘もつい前世の ”ココア” と呼んでしまいます。職業病でしょうか、私はその子を "ココア R2" と呼称していますが、お母さん(ういこさん) に言わせると "ココア MarkⅡ" が格好いいらしいです。やっぱ、ガン○ム 思考なんでしょうか... (※ 2009/10/06 ういこうより : 同じ「日の出系」ですが、むしろ思考はエ○ガイムか吉田拓郎です。)
ちなみに、ハムスターの名前の由来は色で、栗毛(ダウというらしい)長毛サテンで綺麗な毛艶だからだそうです。
見た目で、初代ハムを "ちゅうちゅう”、2代目を ”もこもこ” と命名する娘の思考は、今も変わりません...

さて、今回も PowerShell をいろいろ見ていきたいと思います。
前回、”get-help *” で使用できる、Alias、Cmdlet、HelpFile を列挙できる事を書きましたが、コマンドについて少し参照情報を絞り込んで見ましょう。

ここまでで使用した "get-help""get-help *" で列挙された Cmdlet を見て、お気づきなられたでしょうか。
PowerShell では操作を明示する、[動詞-名詞] のペアでコマンド名が定義されています。
何かを取得したい場合、"get-xxxxx" となりますし、逆に設定であれば "set-xxxxxxx”  といった名称の Cmdlet となります。

そのため、取得系の提供コマンドに絞って情報参照したい場合、"get-help get-*" (* はワイルドカード)とすれば、取得系コマンドのみを列挙することが可能です。

PowerShell01

その他にコマンド操作を明示する動詞には ”add”"clear"”copy”"enable"”disable” その他、多数が用いられます。どのような動詞があるかは、Cmdlet を列挙してみるのが良いかと思います。

ここでは  "get-command" を使用してみましょう。"get-command" では引数 -CommandType でコマンドタイプを限定することが可能です。"get-command -CommandType Cmdlet" と入力すると、Cmdlet(コマンドレット)のみが列挙されます。

PowerShell02

いかがでしょうか、PowerShell のコマンドで何かしたい場合、したい操作(動詞部分)を指定し "get-help" 試される事をお勧めします。標準のコマンドレットについては、このようにコンソール上で使用機能を検索、機能参照する事が可能です。(使用される機能によっては、"import-module" によるパッケージ参照動作が必要となりますが、コマンドを参照列挙したい場合の基本操作は同じです。)よろしければ、お試し下さい。

もっと、PowerShell 、Windows 7 をいじり倒したい
~ お父さん より ~

[PowerShell] PowerShell ってどんな感じ?

こんにちは、ILM一家のパパ(お父さん)です。
ご無沙汰しており恐縮です。

このところ、忙しくしていた我々 ILM一家ですが、この 5連休は追加の夏休みをいただいた感じです。
追加といっても、会社からいただいた夏休みが 2日残っていて如何しようか悩んでいる状況ですが...

この休みは、娘と ディズニーシーに行ってきました。
もう、半端な混み方ではなかったですね、200分待ちのアトラクションなど尋常ではありません。
ポップコーンも種類によっては買うのに 30分待ちとは、日本人はホント忍耐強い民族です。
私も、娘も、我慢が無いので、乗りたいものはファストパスで乗って、30分待ちぐらいのアトラクションしか並びませんでしたけど... それなりに乗り物乗って、ポップコーン二種類を含め一通り飲み食いできたので満足です。
それにしても歩きますね、車で行って徒歩はディズニーシーの中だけですが 26677歩記録されてます。1歩 60cm換算でも 16Km超えてて、さすがに疲れましたが、最近少し脱メタボをサボってたので丁度よい運動になりました。

さて今回は、この休みに少し PowerShell を Windows 7 で触ってみたので、感触をご紹介しましょう。
みなさん、PowerShell はお試しいただいていますでしょうか?
Windows Server 2008 から OS の追加機能となった PowerShell ですが、Windows 7 でも標準搭載されています。
(Windows Server 2003、Windows XP、Vista ではダウンロード入手いただくことで使用可能です)

Windows 上の 従来のコマンドラインプロンプト(CMD.EXE)では、コマンド機能が DOS 由来のもので、OS 管理機能の多くを、他の実行ファイル(exe)や、スクリプティング(スクリプティングからの COM 呼び出し)などに依存していました。
PowerShell では コマンドラインシェル(CUI)から、今まで、 他の実行ファイル(exe)や、スクリプティング(スクリプティングからの COM 呼び出し)などに依存していた部分を、コマンドレット(Cmdlet) で提供しています。
 
まず PowerShell を 今までの CMD.EXE に替え、コマンドラインシェルとして使用してみましょう。
Windows 7(手元では Ultimateを使用しています) のスタートメニューからは、管理ツール内の "Windows PowerShell Modules" で起動します。

PowerShell_01

起動すると、上記のようにコンソールが開き表示されますが、慌てる必要はありません。
指示通りに "get-help about_signing” と入力してみましょう。以下のようにヘルプ表示されます。

PowerShell_02

Windows 7 環境の既定では、スクリプトの実行権限が与えられていないので警告が出ていた状況ですが、ヘルプメッセージの通り、”set-executionpolicy remotesigned” で権限設定すれば、次回以降の PowerShell コンソールの起動で警告が表示されなくなります。
ここで、覚えておいて欲しいのは、判らなくいことは ”get-help" で確認すればよいということです。
”get-help” は引数に、使用したい不明な cmdlet、Alias、HelpFile (about_xxxxx)などを指定して、情報を引き出すことが可能です。

次に、ファイル参照してみましょう。従来の CMD.EXE のように "dir" も使用可能です。

PowerShell_03

PowerShell の "dir" はどのように機能提供されているのか、”get-help” してみましょう。

PowerShell_04 

"Get-ChildItem""dir" という エイリアスがマッピングされている事が判ります。
実際に "Get-ChildItem" でも同様の結果が取得されます。

PowerShell_05 

PowerShell では 、"Get-ChildItem" で、指定したリソースの下位オブジェクトが参照可能です。さきほどの "dir" も実際には従来の “dir” ではありませんので、以下のようにレジストリ参照などもできてしまいます。

PowerShell_04b

ここでは、従来との違いを見て頂きたいために "dir" エイリアスを使いましたが、このような動きを考えると、PowerShell を使っていく上では、"Get-ChildItem" を使用されたほうが構文上自然です。
参照したいレジストリパスが予め判っている場合、コマンドラインで操作できるのは便利ですね。

おまけですが、"ls" エイリアスも用意されており、同様に "Get-ChildItem" にマップされています。
こちらの方が、違和感がない方もいるでしょうし、便利は便利です。

PowerShell_06

コマンドラインシェルとして、従来のコマンドプロンプト風に動かしてみましたが、いかがでしょうか。
ここまでで、興味がありましたら PowerShell コンソール上で "get-help *" を実行してみてください。既定で使用できる Alias、Cmdlet、HelpFile が列挙されます。さらに、詳細を知りたい場合、”get-help” の引数に、確認したい Alias、Cmdlet、HelpFile を指定して再実行すれば詳細が表示されます。    

PowerShell は今まで、コマンドラインやスクリプティングでできなかったことが実現可能です。
ILM 一家では、従来のスクリプトでの困りごとや、運用事例との対比で PowerShell の優位な部分について、ご紹介できればと考えています。

これから夏休みを取りたい
~ お父さんより ~

[WinRM] Windows Remoe Management を使って、らくらく管理!- その1

こんにちは。今週末に バリウム を飲みにいくのでぷるぷる震えている ぴろと です。

先日、お父さんと Windows Remote Management ( 以下、WinRM) について話あっていたのですが、どうやら US では、WinRM と WMI のサポートチームは一緒だということが判明しました。そのため、私たちの Blog でも WinRM を取り上げなくては!ということで、第一弾として、さっぱり簡単レシピをご紹介させていただきます。(最近、仕事と ETロボコンに追われて Blog を書けてませんでした。ぴろとファンの皆様申し訳ございません)

- そもそも WinRM ってなんですか?

WinRM は、WS-Management プロトコルのマイクロソフト実装です。WS-Management プロトコルは、さまざまなベンダが提供するハードウェアやオペレーティング システムの相互運用を可能にする標準的なファイアウォールに対応した SOAP ベースのプロトコルです。というのは大袈裟な言い方ですが、WinRM により、HTTP や HTTPS などの標準的なインターネット プロトコルを使用してコンピュータをリモート管理できるようになります。

ここで、標準的なファイアウォールに対応というところがいいですね! 最近の流行は、何でも HTTPS (Windows Server 2008 R2 の Hosted Mode で使用されるのも HTTPS) ですし、WMI を用いたリモート管理の場合、Port 135 (Remote Procidure Call) のポートが開いてなくてはいけませんものね!

構成を行うのも、割と簡単です。以下のサポート技術情報を参考ください。

How to enable Windows Remote Shell
http://support.microsoft.com/kb/555966/en-us

これで、あなたの端末も WinRM で管理できちゃいます。

また、WMI と同じくスクリプトでの管理も容易です。”Hey,Scripting Guy!” にて公開されているスクリプトがあったので、あわせてご紹介させていただきます。

Hey, Scripting Guy! あの世からのデスクトップ管理
http://technet.microsoft.com/ja-jp/magazine/2007.11.heyscriptingguy.aspx

Hey, Scripting Guy! 帰ってきた WinRM
http://technet.microsoft.com/ja-jp/magazine/2007.12.heyscriptingguy.aspx

すごいネーミングセンスですね!”帰ってきた”と聞くと、”帰マン” とか “新マン”とかを連想する人が多いチームメンバーたちに囲まれて、軽いジェネレーションギャップを感じざるを得ないのはここだけの話です。

VB や C# を使って開発されている場合は、WMI みたいに System.Management 名前空間を用いて開発されているかと存じます。WinRM は、WinRM Scripting API と WinRM C++ API が用意されています。オートメーション インタフェースが公開されているので、WinRM Scripting API を使って実装できます。次回は、サンプルを含めて実装を行っていく予定です!

今後は、WMI だけではなく ”WinRM” も Blog で盛り上げて行きたいと思いますので、どうぞよろしくお願いいたします!

~ すぐにコースアウトするミニ四駆しか作れない ぴろと より~

[MSDN/Technet] ついに Windows7 提供開始!ダウンロード可能になりました。(Ver1.01)

みなさんごきげんよう。ういこです。無事、アメリカから帰国しました。帰国後は素敵な時差ぼけや、お弁当作りでギブアップしたりいろいろでした。

さて、今日は Windows 7 がついに MSDN サブスクライバー ダウンロードに Up されたことをご報告申し上げます。どうやら昨日 up された様子です。(Technet もです!)

MSDN サブスクライバ ダウンロード ログイン
http://msdn.microsoft.com/ja-jp/subscriptions/dd179326.aspx

(8/7 11 AM update1)
日本時間の深夜 2 AM に Up されたようです。 ちなみに、Windows Server 2008 R2 はまだのようです。(8/7)

Professional
Home Premium
Home Basic (※ x86 のみ)
Ultimate
Enterprise
Starter (※ x86 のみ)
デバッグ シンボル(x86, x64)

Windows 自動インストール キット (WAIK) 言語パックの日本語版も Up されています。

Ultimate、Enterprise のみ、FileTransferManager からのダウンロードに制限があるようです。
[ダウンロード] ボタンがクリックできません。
Top Download サイトからは、後述の Akamai のダウンロード マネージャを使ってダウンロードするようになっています。

しかし、早速ログインしてはやる気持ちがあるのはわかるのですが、まあいまはひとまず落ち着きましょう。いきなり罠があります。日本人であると、わりと「言語 : Japanese」が最初から選ばれている状態が多いと思うのですが、ここを「言語 : English」にしないと、左ペインの “Windows 7” を選んでも、ダウンロード候補出てきません。まだ英語版しかないからなんですね。

image

↑ここを、こうします↓

image

これで、Windows 7 を左ペインで選べば、出てきますよ。ただ、よく見ると、「ダウンロード」リンクがグレーアウトしてるので、一瞬あせりますが、”詳細情報” をクリックすればよいです。

image

詳細情報をクリックしたところです。

image

詳細情報をクリックすると、したが展開され、まあ要は青字の Top Downloads をクリックしろってことですね。クリックすると、以下のリンクに行きます。ここで注意が。

https://msdn.microsoft.com/ja-jp/subscriptions/downloads/bb608344.aspx

"下記の一覧で項目をクリックすると Top Subscriber Downloads (ダウンロード サブスクライバ ランキング) の一部にアクセスできます。この新しい機能にアクセスするには、Akamai Technologies Download Manager Browser アドオンをインストールしてこれらのファイルにアクセスする必要があります。"

・・・つまり、ダウンロードは、今までの File Transfer Manager ではない、Akamai なんとかって言うのが使われるように変更されたのです。つまり、すでに他の OS やらなにやらを MSDN サブスクライバーダウンロードから落としたことがある環境でも、Ultimate / Enterprise 落とすためには、新しい ActiveX を入れなくてはいけないのです。(8/7 現在) これに、20 秒くらいかかることがあります。気長に待ちましょう。

image

上記より、iso イメージのリンクをクリックすると、こんな風にでます。

image

そして、ActiveX のダウンロードが開始されます。インストールしないと、スーパーマリオの 8-4 みたいに、上記ページの無限ループになるので必ず入れてください。

image

インストールする、を選んでください。

image

ダウンロードが開始されます。

image

ここまでいけばあとはこっちのもんです。ダウンロードしまくってください。

それでは、取り急ぎですが皆様 Windows 7 をかわいがってあげてください!よろしくお願いします。

~ ういこう

[ADSI プログラミング] お役立ちツールのご紹介

こんにちは、 ILM 一家のパパ ( お父さん ) です。
今週は、一家のお母さん(ういこさん)がいない、非常に寂しい日々を送っています。 ピロトと二人で留守を守り、指折り数えて帰りを待ってます。また、今月は余暇も非常にバタバタしていまして、ブログ書き込みもお休みがちでした、読者の方すみません。

さて、寂しさのあまりテンションも低い状況ですが、気を取り直してお役立ち情報をご紹介することにしましょう。
過去に製品の管理ツール、サポートツール、リソースキット等のユーティリティをご紹介しましたが、我々サポートエンジニアが、その他、トラブルシュートや動作の診断に使用しているツールは他にも多数あります。

まず、サイトを見ていただきましょう。

Windows Sysinternals
 http://technet.microsoft.com/ja-jp/sysinternals/default.aspx

ここで紹介しているツール類は 10年以上前から使っていたものですが、以前は 他社(Sysinternals 社)のツールとしてご紹介に難がある状況がありました。2006年に マイクロソフトが買収したことにより Technet のサイトに内包されることとなっています。
このサイトには、我が Blog で扱っている ADSI、WMI、ILM のみでなく、一般的な Windows トラブル、プログラミングトラブルの診断に使用できるツールが数多く登録されています。

ADSI , WMI プログラミングで有効と考えられるツールとしては、以下のようなものがあります。

AD Explorer (英語)
Active Directory Explorer は、Active Directory (AD) の高度なビューアーおよびエディターです。

AD Insight (英語)
AD Insight は、Active Directory クライアント アプリケーションのトラブルシューティングを目的とした LDAP (ライトウェイト ディレクトリ アクセス プロトコル) リアルタイム監視ツールです。

AdRestore (英語)
削除した Server 2003 の Active Directory オブジェクトを復元します。

TCPView (英語)
アクティブなソケットを表示するコマンドライン ビューアーです。

AccessChk (英語)
このツールでは、ファイル、レジストリ キー、Windows サービスに対して、指定したユーザーやグループが持つアクセス権を確認できます。

AccessEnum (英語)
シンプルかつ強力なセキュリティ ツールです。システム上のディレクトリ、ファイル、およびレジストリ キーについて、どのユーザーがどのアクセス権を持っているかどうかを確認できます。このツールを使用すると、アクセス許可のセキュリティ ホールを見つけることができます。

Process Explorer (英語)
プロセスが開いたファイル、レジストリ キーなどのオブジェクト、読み込んだ DLL などを調べます。この非常に強力なユーティリティでは、各プロセスの所有者も表示できます。

PsTools
PsTools スイートには、ローカル コンピューターまたはリモート コンピューターで実行されているプロセスの一覧の取得、リモートでのプロセスの実行、コンピューターの再起動、イベント ログのダンプなど、さまざまな操作を行うためのコマンド ライン ユーティリティが含まれています。

なお、以下のようなスクリーンセーバもあるようですが、どうしたものでしょう.... サポート担当者としては微妙な気持ちです。

BlueScreen (英語)
このスクリーン セーバーは、ブルー スクリーンを正確に模した画面を表示するだけでなく、CHKDSK を含む再起動を模した画面も表示します。このユーティリティは、Windows NT 4、Windows 2000、Windows XP、Server 2003、および Windows 9x で使用できます。

いかがですか?
使えそうなツールはありますでしょうか。
またの機会に、この中の幾つかを具体的に紹介したいと思います。

今週は ろんりーはーと な
~ お父さんより ~

[AD/ADAM] 10000件以上のデータが登録された環境でサーバソートすると 0x8007202C (3)/4 – DirectorySearcher.VirtualListView

みなさんごきげんよう、ういこです。
これまでは、大量データ保持の AD / ADAM に対してソートを行う際の問題についてお伝えしてまいりました。今回は、回避策として、Virtual List View が使えるか?という内容です。

【問題】
10000 件以上、大量に ADAM および AD にオブジェクトが登録されている環境に対し、ソートを実行すると

"サーバーは要求された重大な拡張子をサポートしていません。(0x8007202C)"

というエラーが返され、ソートができない。しかし、Name など一部の属性では問題なく動作する。 ただし、降順ソートの場合、すべての属性に対してソートができず、上記エラーが発生する。

【解説】Active Directory の大容量データに対するサーバソートについて
(1) 昇順ソート ~ インデックスつき属性と、インデックスなし属性での挙動の違い

(2) 降順ソート ~ 既知の問題
(3) Virtual List View は対処方法となりえるか?← このコンテンツです!
(4) まとめ (4 回目予定)

- これまでの経緯
サーバ ソート(データをサーバ側で「整える(取得したデータの並べ替えを行う))の昇順ソートの場合は、インデックス化されていない属性をソートキーに指定した場合は、データの並べ替えのためサーバ側で一時的にデータを格納するテーブルが作成され、このテーブル内で指定されたキーによる整列を行います。この一時的なソートに用いられるテーブルのサイズは、"MaxTempTableSize" という LDAP ポリシーで決められており、既定は 10000 です。
ソートする対象のレコード数が MaxTempTableSize を超えた場合、ソート処理は行われません。
一方、インデックス化された属性のソートの場合にはこの一時データ格納テーブルを使わないためこの制限に抵触しません。このため、インデックス化された属性の場合はうまくいき、インデックス化されてない属性をソートキーに指定して昇順ソートを行った場合は上記問題が発生してしまうことになるのでした。
そして、降順ソート時は MaxTempTableSize のサイズ制限抵触以外の問題が存在するため、インデックス化属性であっても降順ソート時大量件数が存在する場合、非インデックス属性の昇順ソート時の動作と同様のエラーが発生する問題があります。この問題は製品の障害となります。そのため、降順ソートを実装する必要があるシステムの場合は、属性のインデックス化は回避手段とはなりません。

- VLV は回避策にならない
MSDN を見ると、VLV は大きなサイズの ResultSet に向いてます、みたいなことが書いてあるのですが、実際は、VLV も Temp tableを使って中間結果を保持することで動作する設計です。しかし、この Temp Table はすなわち MaxTempTableSize が制限値になるため、VLV の計算に必要な中間結果がこの値を超えた場合、昇順ソートのインデックスなし属性がソートキーに指定された場合と同様処理が中断することになります。よって、回避策として有効な手段には残念ながらならないという結論になります。なお、問題発生時のエラーは、非インデックス属性の大量データの昇順ソート実行時と同じく「"サーバーは要求された重大な拡張子をサポートしていません。(0x8007202C)」となります。なお、MaxTempTableSize のサイズをオブジェクト数をカバーする値に変更しますと、正常に Resultset が返されるようになります。

- VLV サンプル コード

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.DirectoryServices;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SearchResultCollection results;
            using (DirectorySearcher searcher = new DirectorySearcher())
            {           
                DirectoryEntry de = new DirectoryEntry("LDAP://CN=Users,DC=corp,DC=contoso,DC=com");
                searcher.SearchRoot = de;
                searcher.Filter = "(objectclass=*)";
                searcher.PropertiesToLoad.Add("samaccountname");
                searcher.PropertiesToLoad.Add("name");
                searcher.PropertiesToLoad.Add("displayName");
                searcher.PropertiesToLoad.Add("mail");
                searcher.SearchScope = SearchScope.Subtree;
                DirectoryVirtualListView virtualList = new DirectoryVirtualListView(0, 50, 10);
                string searchAttributeName = null;
                searchAttributeName = "name";
                SortOption sort = new SortOption(searchAttributeName, SortDirection.Descending);
                searcher.Sort = sort;
                searcher.VirtualListView = virtualList;
                results = searcher.FindAll();
                if (results.Count >= 0)
                {
                    Console.WriteLine(searcher.VirtualListView.ApproximateTotal);
                    MessageBox.Show(searcher.VirtualListView.ApproximateTotal.ToString());
                }
            }
        }
    }
}

~ ういこう ~

More Posts Next page »
Page view tracker