Win32 API 日本語リファレンス
ホームNetworking.ActiveDirectory › IADsContainer

IADsContainer

COMIDispatch (デュアル)
IDispatch を実装(デュアルインターフェース)。HSP では comobj 経由でメソッド名による遅延バインド呼び出しができます(vtableインデックス不要)。
IID001677d0-fd16-11ce-abc4-02608c9e7553継承元IDispatch呼び出し名前(IDispatch) または vtbl自前メソッド開始 vtbl7

公式ドキュメント

IADsContainer インターフェイスは、ADSI コンテナー オブジェクトが、格納された ADSI オブジェクトを作成、削除、および管理できるようにします。コンテナー オブジェクトは、ファイル システムのような階層的なディレクトリ ツリーを表し、ディレクトリ階層を編成します。

解説(Remarks)

オブジェクトがコンテナーであるかどうかを判断するには、そのオブジェクトの IADsClass.Container プロパティを使用します。

GUID(または SID)を使用してコンテナー オブジェクトにバインドした場合、そのコンテナー オブジェクトに対しては特定の操作しか実行できません。これらの操作には、オブジェクトの属性の調査と、オブジェクトの直下の子の列挙が含まれます。これらの操作を次のコード例に示します。

Dim con As IADsContainer
Dim obj As IADs
Set con = GetObject("LDAP://svr01/<GUID=xxxx>")
con.Filter = Array("user")
For Each item In con
    debug.print item.Name " &  " of " & item.Class
Next

その他のすべての操作、つまり GetObjectCreateDeleteCopyHereMoveHere は、コンテナーの GUID 表現ではサポートされません。たとえば、次のコード例の最後の行はエラーになります。

Dim con As IADsContainer
Dim obj As IADs
Set con = GetObject("LDAP://svr01/<GUID=xxxx>")
Set obj = con.GetObject("user", "CN=Jeff Smith")

GUID(または SID)を使用したバインドは、オーバーヘッドが小さく、そのため高速なバインドを目的としており、多くの場合オブジェクトのイントロスペクションに使用されます。

GUID(または SID)でバインドされたコンテナーのこれらのメソッドを呼び出すには、識別名(DN)を使用してオブジェクトに再バインドしてください。

Dim conGUID, conDN As IADsContainer
Dim obj As IADs
Set conGUID = GetObject("LDAP://svr/<GUID=xxxx>")
Set conDN=GetObject("LDAP://svr/" & conGUID.Get("distinguishedName"))
Set obj = conDN.GetObject("user", "CN=Jeff Smith")

オブジェクトの GUID 表現の詳細については、IADs.GUID を参照してください。

次のコード例は、ADSI オブジェクトがコンテナーであるかどうかを判断します。

Dim obj As IADs
Dim cls As IADsClass
On Error GoTo Cleanup

Set obj = GetObject("WinNT://myComputer,computer")
Set cls = GetObject(obj.Schema)
If (cls.Container = TRUE) Then
    MsgBox "The object is a container."
Else
    MsgBox "The object is a leaf."
End If

Cleanup:
    If (Err.Number<>0) Then
        MsgBox("An error has occurred. " & Err.Number)
    End If
    Set obj = Nothing
    Set cls = Nothing

次のコード例は、ADSI オブジェクトがコンテナーであるかどうかを判断します。

IADs *pADs = NULL;
IADsClass *pCls = NULL;
HRESULT hr = S_OK;
BSTR bstr;

hr = ADsGetObject(L"WinNT://myComputer,computer", IID_IADs, (void**)&pADs);
if(FAILED(hr)){return;}

pADs->get_Schema(&bstr);
hr = ADsGetObject(bstr, IID_IADsClass, (void**)&pCls);
pADs->Release();
SysFreeString(bstr);

if(FAILED(hr)){return;}

VARIANT_BOOL isContainer;
pCls->get_Container(&isContainer);

if(isContainer) 
    printf("Object is a container.\n");
else
    printf("Object is not a container.\n");

pCls->Release();

メソッド 11

vtbl = vtable インデックス(0始まり)。IDispatch 実装のため HSP ではメソッド名でも呼べます(上記)。低レベルの index 呼び出し用に vtbl も掲載。0〜2 は IUnknown。

vtbl 7 HRESULT get_Count(INT* retval)
retvalINT*outコンテナに含まれる子オブジェクトの数を受け取る出力ポインタ。
vtbl 8 HRESULT get__NewEnum(IUnknown** retval)

コンテナーの列挙子オブジェクトを取得します。

retvalIUnknown**out列挙子オブジェクトを受け取る IUnknown ポインターへのポインター。呼び出し側は、このインターフェイスが不要になったら解放する必要があります。

戻り値

このメソッドは、操作が成功した場合の S_OK を含む標準的な戻り値をサポートします。エラー コードの詳細については、ADSI Error Codes を参照してください。

解説(Remarks)

関数名には、"get" と "NewEnum" の間に 2 つのアンダースコア文字("__")があります。

Visual Basic では、ForEach… ステートメントを使用して IADsContainer::get__NewEnum メソッドを暗黙的に呼び出します。

C/C++ では、ADsBuildEnumeratorADsEnumerateNextAdsFreeEnumerator ヘルパー関数を使用します。

次のコード例は、コンテナー内の子オブジェクトを列挙する方法を示します。

Dim cont As IADsContainer
On Error GoTo Cleanup

Set cont = GetObject("LDAP://OU=Sales,DC=Fabrikam,DC=com")
For Each obj In cont
  Debug.Print obj.Name
Next

Cleanup:
    If(Err.Number<>0) Then
        MsgBox("An error has occurred. " & Err.Number)
    End If
    Set cont = Nothing

次のコード例は、コンテナーに格納されたオブジェクトを列挙する方法を示します。

IEnumVARIANT *pEnum = NULL;
IADsContainer *pCont = NULL;
LPUNKNOWN pUnk = NULL;
VARIANT var;
IDispatch *pDisp = NULL;
ulong lFetch;
IADs *pADs = NULL;
 
// In this sample, skip error checking.
ADsGetObject(L"LDAP://OU=Sales,DC=Fabrikam,DC=COM", 
                        IID_IADsContainer, (void**) &pCont);
pCont->get__NewEnum(&pUnk);
pCont->Release();
 
pUnk->QueryInterface(IID_IEnumVARIANT, (void**) &pEnum);
pUnk->Release();
 
// Enumerate. 
HRESULT hr = pEnum->Next(1, &var, &lFetch);
while(SUCCEEDED(hr) && lFetch > 0)
{
    if (lFetch == 1)
    {
        BSTR bstr;

        pDisp = V_DISPATCH(&var);
        pDisp->QueryInterface(IID_IADs, (void**)&pADs); 
        pDisp->Release();
        hr = pADs->get_Name(&bstr);
        if(SUCCEEDED(hr))
        {
            SysFreeString(bstr);
        }

        pADs->Release();
    }

    VariantClear(&var);
    hr = pEnum->Next(1, &var, &lFetch);
};

 
pEnum->Release();
vtbl 9 HRESULT get_Filter(VARIANT* pVar)
pVarVARIANT*out現在の列挙フィルタ(クラス名配列)を保持するVARIANTを受け取る出力ポインタ。
vtbl 10 HRESULT put_Filter(VARIANT Var)
VarVARIANTin列挙対象を限定するクラス名配列を保持するVARIANT。
vtbl 11 HRESULT get_Hints(VARIANT* pvFilter)
pvFilterVARIANT*outプリフェッチ対象の属性名を示すヒント配列のVARIANTを受け取る出力ポインタ。
vtbl 12 HRESULT put_Hints(VARIANT vHints)
vHintsVARIANTinプリフェッチ対象の属性名を示すヒント配列を保持するVARIANT。
vtbl 13 HRESULT GetObject(LPWSTR ClassName, LPWSTR RelativeName, IDispatch** ppObject)

コンテナー内のディレクトリ オブジェクトのインターフェイスを取得します。

ClassNameLPWSTRin取得するオブジェクトのオブジェクト クラスの名前を指定する BSTR。このパラメーターが NULL の場合、プロバイダーはコンテナー内で最初に見つかった項目を返します。
RelativeNameLPWSTRin取得するオブジェクトの相対識別名(相対DN)を指定する BSTR
ppObjectIDispatch**out指定されたオブジェクト上の IDispatch インターフェイスへのポインターへのポインター。

戻り値

このメソッドは、操作が成功した場合の S_OK を含む標準的な戻り値をサポートします。エラー コードの詳細については、ADSI Error Codes を参照してください。

解説(Remarks)

LDAP プロバイダーの場合、bstrRelativeName パラメーターには "CN=Jeff Smith" のような名前プレフィックスを含める必要があります。bstrRelativeName パラメーターには、"CN=Jeff Smith,OU=Sales" のように複数レベルの名前を含めることもできます。

C++ では、GetObject が成功した場合、呼び出し側は QueryInterface メソッドを使用して、IDispatch インターフェイスに目的のインターフェイスを問い合わせる必要があります。

bstrClassName パラメーターには、有効なクラス名または NULL のいずれかを指定できます。クラス名が有効でない場合(空白が含まれている場合を含む)、このメソッドは E_ADS_UNKNOWN_OBJECT エラーをスローします。

次のコード例は、コンテナー オブジェクトからユーザー オブジェクトを取得します。

Dim cont As IADsContainer
Dim usr As IADsUser
Set cont = GetObject("LDAP://OU=Sales,DC=Fabrikam,DC=com")
Set usr = cont.GetObject("user", "CN=jeffsmith")

これは次と同等です。

Dim usr As IADsUser
Set usr=GetObject("LDAP://CN=jeffsmith,OU=Sales,DC=Fabrikam,DC=com")

次のコード例は、コンテナー オブジェクトからユーザー オブジェクトを取得します。

HRESULT hr = S_OK;
CoInitialize(NULL);
 
IADsContainer *pCont = NULL;
 
hr = ADsGetObject(L"LDAP://DC=windows2000,DC=mytest,DC=fabrikam,DC=com",
            IID_IADsContainer, 
            (void**) &pCont );

if(FAILED(hr))
{
    goto Cleanup;
}
 
///////////////////////////////////////////////////////////////////////
// Retrieve the child from the container.
// Be aware that in the LDAP provider you can navigate multiple levels.
///////////////////////////////////////////////////////////////////////
IDispatch *pDisp = NULL;
IADs *pADs = NULL;
hr = pCont->GetObject(CComBSTR("user"), CComBSTR("CN=Jeff Smith,OU=DSys"), &pDisp);
pCont->Release();
if(FAILED(hr))
{
    goto Cleanup;
}
 
hr = pDisp->QueryInterface(IID_IADs, (void**)&pADs);
pDisp->Release(); 
if(FAILED(hr))
{
    goto Cleanup;
}
 
// Perform an operation with pADs.
pADs->Release();
 
Cleanup:
if(pCont)
    pCont->Release();

if(pDisp)
    pDisp->Release();

if(pADs)
    pADs->Release();

CoUninitialize();
vtbl 14 HRESULT Create(LPWSTR ClassName, LPWSTR RelativeName, IDispatch** ppObject)

指定したスキーマ クラスと指定した名前を持つディレクトリ オブジェクトをコンテナー内に作成する要求を設定します。

ClassNameLPWSTRin作成するスキーマ クラス オブジェクトの名前。この名前は IADs::get_Schema プロパティ メソッドから返されるものです。
RelativeNameLPWSTRin基になるディレクトリで認識されるオブジェクトの相対名で、IADs::get_Name プロパティ メソッドで取得されるものと同一です。
ppObjectIDispatch**out新しく作成されたオブジェクト上の IDispatch インターフェイスへの間接ポインター。

戻り値

このメソッドは、操作が成功した場合の S_OK を含む標準的な戻り値をサポートします。エラー コードの詳細については、ADSI Error Codes を参照してください。

vtbl 15 HRESULT Delete(LPWSTR bstrClassName, LPWSTR bstrRelativeName)

指定したディレクトリ オブジェクトをこのコンテナーから削除します。

bstrClassNameLPWSTRin削除するスキーマ クラス オブジェクト。この名前は IADs::get_Class メソッドから返されるものです。また、このパラメーターには NULL も有効な選択肢です。このパラメーターに NULL を指定することは、廃止された(defunct)スキーマ クラスを扱う唯一の方法です。クラスが廃止される前にインスタンスが作成されていた場合、廃止されたクラスのインスタンスを削除する唯一の方法は、IADsContainer::Delete を呼び出して、このパラメーターに NULL を指定することです。
bstrRelativeNameLPWSTRin基になるディレクトリで認識されるオブジェクトの名前で、IADs::get_Name メソッドで取得される名前と同一です。

戻り値

このメソッドは、操作が成功した場合の S_OK を含む標準的な戻り値をサポートします。エラー コードの詳細については、ADSI Error Codes を参照してください。

解説(Remarks)

削除するオブジェクトは、リーフ オブジェクトまたは子を持たないサブコンテナーである必要があります。コンテナーとその子(つまりサブツリー)を削除するには、IADsDeleteOps::DeleteObject を使用します。

指定したオブジェクトは IADsContainer::Delete の呼び出し後ただちに削除されるため、コンテナー オブジェクトに対して IADs::SetInfo を呼び出す必要はありません。

C/C++ アプリケーションで IADsContainer::Delete メソッドを使用してオブジェクトを削除する場合は、そのオブジェクトへのインターフェイス ポインターも解放してください。これは、このメソッドが基になるディレクトリからオブジェクトをただちに削除する一方で、削除されたオブジェクトについてアプリケーションがメモリ内に保持しているインターフェイス ポインターはそのまま残るためです。解放しない場合、削除されたオブジェクトに対して IADs::GetIADs::Put をエラーなしで呼び出せる一方、IADs::SetInfoIADs::GetInfo を呼び出すとエラーが返される、という混乱が生じることがあります。

次のコード例は、Active Directory 内のコンテナーからユーザー オブジェクトを削除します。

Dim cont as IADsContainer
On Error GoTo Cleanup

Set cont = GetObject("LDAP://OU=Sales,DC=Fabrikam,DC=com")
cont.Delete "user", "CN=JeffSmith"

Cleanup:
    If (Err.Number<>0) Then
        MsgBox("An error has occurred. " & Err.Number)
    End If
    Set cont = Nothing

次のコード例は、WinNT プロバイダー下のコンテナーからユーザー オブジェクトを削除します。

Dim cont as IADsContainer
On Error GoTo Cleanup

Set cont = GetObject("WinNT://Fabrikam")
cont.Delete "user", "jeffsmith"

Cleanup:
    If (Err.Number<>0) Then
        MsgBox("An error has occurred. " & Err.Number)
    End If
    Set cont = Nothing

次のコード例は、IADsContainer::Delete を使用してユーザーを削除します。

HRESULT hr = S_OK;
IADsContainer *pCont=NULL;
 
CoInitialize(NULL);
 
hr = ADsGetObject(L"WinNT://myMachine", 
                  IID_IADsContainer, 
                  (void**) &pCont);
if ( !SUCCEEDED(hr) )
{
     return hr;
}
 
hr = pCont->Delete(CComBSTR("user"), CComBSTR("JeffSmith"));
pCont->Release();
vtbl 16 HRESULT CopyHere(LPWSTR SourceName, LPWSTR NewName, IDispatch** ppObject)

IADsContainer::CopyHere メソッドは、指定したディレクトリ オブジェクトのコピーをこのコンテナー内に作成します。

SourceNameLPWSTRinコピーするオブジェクトの ADsPath。
NewNameLPWSTRinコンテナー内の新しいオブジェクトの名前(省略可能)。オブジェクトに新しい名前を指定しない場合は NULL を設定します。その場合、新しいオブジェクトはソース オブジェクトと同じ名前になります。
ppObjectIDispatch**outコピーされたオブジェクト上の IADs インターフェイスへの間接ポインター。

戻り値

このメソッドは、操作が成功した場合の S_OK を含む標準的な戻り値をサポートします。詳細およびエラー コードについては、ADSI Error Codes を参照してください。

解説(Remarks)

コピー先のコンテナーは、コピー元のコンテナーと同じディレクトリ サービス内にある必要があります。オブジェクトを、ディレクトリ サービスの実装をまたいでコピーすることはできません。

ADSI に付属するプロバイダーは、E_NOTIMPL エラー メッセージを返します。

vtbl 17 HRESULT MoveHere(LPWSTR SourceName, LPWSTR NewName, IDispatch** ppObject)

指定したオブジェクトを、このインターフェイスを実装するコンテナーに移動します。

SourceNameLPWSTRin移動するオブジェクトの ADsPath を指定する null 終端 Unicode 文字列。
NewNameLPWSTRinコンテナー内の新しいオブジェクトの相対名を指定する null 終端 Unicode 文字列。これは NULL にすることができ、その場合オブジェクトは移動されます。NULL でない場合は、その過程でオブジェクトが指定に従って名前変更されます。
ppObjectIDispatch**out移動されたオブジェクト上の IDispatch インターフェイスへのポインターへのポインター。

戻り値

このメソッドは、操作が成功した場合の S_OK を含む標準的な戻り値をサポートします。エラー コードの詳細については、ADSI Error Codes を参照してください。

解説(Remarks)

Active Directory では、同じドメイン内でオブジェクトを移動したり、同じディレクトリ フォレスト内の異なるドメイン間で移動したりできます。ドメイン間の移動の場合、次の制限が適用されます。

メモ  異なるドメイン間でサブツリーを移動するには、Movetree.exe ユーティリティを使用します。Movetree コマンドライン ツールを使用して移動元ドメインから移動先ドメインへオブジェクトを移動するには、移動元ドメインの RID マスター ロールを保持するドメイン コントローラーに接続する必要があります。RID マスターが使用できない場合、オブジェクトを他のドメインに移動することはできません。Movetree.exe ツールを使用してあるドメインから別のドメインへオブジェクトを移動しようとする際に、RID マスターではない移動元ドメイン コントローラーを指定した場合、具体的でない "Movetree failed" というエラー メッセージが表示されます。
 
メモ  ADsOpenObject 関数を使用して ADSI オブジェクトにバインドする場合、IADsContainer::MoveHere でドメイン間の移動を行うには、この関数の dwReserved パラメーターに ADS_AUTHENTICATION_ENUMADS_USE_DELEGATION フラグを使用する必要があります。 ADsOpenObject 関数は IADsOpenDSObject::OpenDsObject メソッドと同等です。 同様に、OpenDsObject メソッドを使用して ADSI オブジェクトにバインドする場合、IADsContainer::MoveHere でドメイン間の移動を行うには、このメソッドの InReserved パラメーターに ADS_AUTHENTICATION_ENUMADS_USE_DELEGATION フラグを含める必要があります。
 
次のコード例は、ユーザー "jeffsmith" を "South.Fabrikam.Com" ドメインから "North.Fabrikam.Com" ドメインに移動します。まず、移動先コンテナーへの IADsContainer ポインターを取得し、次に MoveHere の呼び出しで移動するオブジェクトのパスを指定します。
Set ou = GetObject("LDAP://server1/OU=Support,DC=North,DC=Fabrikam,DC=COM")
ou.MoveHere("LDAP://server2/CN=jeffsmith,OU=Sales,DC=South,DC=Fabrikam,DC=Com", vbNullString)

サーバーレスの ADsPath は、移動元、移動先、またはその両方に使用できます。

IADsContainer::MoveHere メソッドは、同じコンテナー内でオブジェクトの名前を変更するためにも、異なるコンテナー間でオブジェクトを移動するためにも使用できます。オブジェクトを移動すると、そのオブジェクトの RDN は保持されますが、オブジェクトの名前を変更すると RDN が変更されます。

たとえば、次のコード例は名前変更の操作を実行します。

set cont = GetObject("LDAP://dc=dom,dc=com")
set newobj = cont.MoveHere("LDAP://cn=Jeff Smith,dc=dom,dc=com", "cn=Denise Smith")

次のコード例は移動を実行します。

set cont = GetObject("LDAP://dc=dom,dc=com")
set newobj = cont.MoveHere("LDAP://cn=jeffsmith,ou=sales,dc=dom,dc=com", "cn=jeffsmith")

Visual Basic アプリケーションでは、あるコンテナーから別のコンテナーへオブジェクトを移動するときに、2 番目のパラメーターとして vbNullString を渡すことができます。

Set newobj =  cont.MoveHere("LDAP://cn=jeffsmith,ou=sale,dc=dom,dc=com", vbNullString)

ただし、VBScript では同じことはできません。これは、VBScript が Visual Basic とは異なり、vbNullString を null 文字列ではなく空文字列にマップするためです。前の例に示したように、RDN を明示的に使用する必要があります。

メモ  WinNT プロバイダーは IADsContainer::MoveHere をサポートしますが、ドメイン内のユーザーおよびグループの名前変更に限られます。
 

次のコード例は、このメソッドを使用してオブジェクトの名前を変更する方法を示します。

Dim cont As IADsContainer
Dim usr As IADsUser

On Error GoTo Cleanup
' Rename an object.
Set cont = GetObject("LDAP://OU=Sales, DC=Fabrikam,DC=com")
Set usr = cont.MoveHere("LDAP://CN=jeffsmith,OU=Sales, DC=Fabrikam,DC=com", "CN=jayhenningsen")
 
' Move an object.
cont.MoveHere("LDAP://CN=denisesmith,OU=Engineer,DC=Fabrikam,DC=com", vbNullString)

Cleanup:
    If (Err.Number<>0) Then
        MsgBox("An error has occurred. " & Err.Number)
    End If
    Set cont = Nothing
    Set usr = Nothing

次のコード例は、IADsContainer::MoveHere メソッドを使用してユーザー オブジェクトを移動します。

/////////////////////////////////////////////
// First, bind to the destination container.
////////////////////////////////////////////
HRESULT hr;
IADsContainer *pCont=NULL;
CoInitialize(NULL);
hr = ADsGetObject(
        L"LDAP://OU=MCS,DC=windows2000,DC=mytest,DC=fabrikam,DC=com",
        IID_IADsContainer,
        (void**) &pCont );
 
if ( !SUCCEEDED(hr) )
{
    goto Cleanup;
}
 
//////////////////////////////////////////////////
// Second, move the object to the bound container.
//////////////////////////////////////////////////
IDispatch *pDisp=NULL;
 
hr = pCont->MoveHere(CComBSTR("LDAP://CN=Jeff Smith,OU=DSys,DC=windows2000,DC=mytest,DC=fabrikam,DC=com"), NULL, &pDisp );
pCont->Release();
 
if (SUCCEEDED(hr) )
{ 
// You can perform another operation here, such as updating attributes.
pDisp->Release();
}

Cleanup:
    if(pCont)
        pCont->Release(); 

    if(pDisp)
        pDisp->Release();

    CoUninitialize();
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

HSP用 COM定義

#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"

出力引数:
#define global IID_IADsContainer "{001677D0-FD16-11CE-ABC4-02608C9E7553}"
#usecom global IADsContainer IID_IADsContainer "{}"
#comfunc global IADsContainer_get_Count     7 var
#comfunc global IADsContainer_get__NewEnum  8 sptr
#comfunc global IADsContainer_get_Filter    9 var
#comfunc global IADsContainer_put_Filter    10 int
#comfunc global IADsContainer_get_Hints     11 var
#comfunc global IADsContainer_put_Hints     12 int
#comfunc global IADsContainer_GetObject     13 wstr,wstr,sptr
#comfunc global IADsContainer_Create        14 wstr,wstr,sptr
#comfunc global IADsContainer_Delete        15 wstr,wstr
#comfunc global IADsContainer_CopyHere      16 wstr,wstr,sptr
#comfunc global IADsContainer_MoveHere      17 wstr,wstr,sptr
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。
; ※IDispatch 実装。HSP では comobj 経由でメソッド名による呼び出しも可能(vtbl 不要)。