ADSI vs ターミナルサービス API

いつも Blog を見てくださっている皆様、誠にありがとうございます。
今回、ご案内させていただく "ぴろと" です。昨日、"イケメン缶" なるものを開封する際に、缶の切り口で中指の付け根をばっさりやってしまいました。本日出社したところ、ういこさんに傷がすごい勢いで治るという夢のような絆創膏をいただいたので、つけてみました。人工皮膚みたいな見た目なので、つけているだけで治ったように錯覚してしまうぐらいイケてるアイテムです。

今回は、Active Directory ユーザーとコンピュータにて、ユーザーのプロパティを見た際に、"ターミナル サービスのプロファイル" タグの項目に設定する方法について記事にさせていただきます。ターミナル サービスのプロファイルタグにある項目は、Active Directory 上のユーザー オブジェクトの属性値として設定されます。しかしながら、当該属性は、単純に編集できる内容ではありません。そのため、少しテクニックを使って実装するしかない状況となります。

ADSI を用いた場合、以下のメソッドを使用することで、今までご紹介させていただいた手法に非常に類似した形で実装できるかと思います。

IADsTSUserEx Property Methods
https://msdn.microsoft.com/en-us/library/aa380823(VS.85).aspx

(本メソッドを使う場合、Tsuserex.dll が必要です。本 dll は、Windows 2003 等のサーバー OS には標準ですが、クライアント OS には組み込まれていないため注意が必要です)
上記手法の場合、クライアント OS 上で使用するためには、Adminpak.msi をインストールされていなければならないといった、非常に大きな制約があるという問題点があります。

そこで、代替案があります。ターミナル サービス API を用いること です。このターミナル サービス API についてご紹介させていただきます。

WTSQueryUserConfig Function
https://msdn.microsoft.com/en-us/library/aa383839(VS.85).aspx

WTSSetUserConfig Function
https://msdn.microsoft.com/en-us/library/aa383844(VS.85).aspx

WTS_CONFIG_CLASS Enumeration
https://msdn.microsoft.com/en-us/library/aa383859(VS.85).aspx

早速、この API を用いた ターミナル サービスのユーザー プロファイル "プロファイルパス" を変更するサンプルコードを書いてみました。
(ひとまず、この API にて、設定できるかを確認するためのコードレベルとなってしまい恐縮ですが…)

=== Sample Codes ===

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

using System.Diagnostics;

namespace WTSAPI_TEST

{

    class Program

    {

        [DllImport("wtsapi32.dll")]

        extern static bool WTSSetUserConfig(StringBuilder pServerName,

            StringBuilder pUserName,

            UInt32 WTSConfigClass,

            StringBuilder pBuffer,

            UInt32 DataLength);

        [DllImport("wtsapi32.dll")]

        extern static bool WTSQueryUserConfig(StringBuilder pServerName,

            StringBuilder pUserName,

            UInt32 WTSConfigClass,

            ref StringBuilder pBuffer,

            ref UInt32 DataLength);

        private const UInt32 WTSUserConfigTerminalServerProfilePath = 15;

        static void Main(string[] args)

        {

            StringBuilder pServerName;

            StringBuilder pUserName;

            StringBuilder pBuffer;

            UInt32 DataLength;

            bool Flag;

            // 接続先DC -- 本来はDsGetDcName 関数で取得を行う(Null で終わる文字列)

            pServerName = new StringBuilder("DC-NetBIOSNAME\0");

            // 変更するユーザー(Null で終わる文字列)

            pUserName = new StringBuilder("User\0");

            pBuffer = new StringBuilder();

            DataLength = new UInt32();

            Flag = WTSQueryUserConfig(pServerName, pUserName,

                WTSUserConfigTerminalServerProfilePath,

                ref pBuffer, ref DataLength);

            if (Flag)

  {

                Debug.Print(pBuffer.ToString());

                // 変更する文字列(Null で終わる文字列)

                pBuffer = new StringBuilder("\\\\DC-NetBIOSNAME\\WTSUserProfile\\User\0");

                // 変更する文字列の長さを設定

                DataLength = (UInt32)pBuffer.Length;

                Flag = WTSSetUserConfig(pServerName, pUserName,

                    WTSUserConfigTerminalServerProfilePath,

                    pBuffer, DataLength);

                if(Flag)

                {

                    Debug.Print("反映終了");

                }

            }

        }

    }

}