Huomautus
Tämän sivun käyttö edellyttää valtuutusta. Voit yrittää kirjautua sisään tai vaihtaa hakemistoa.
Tämän sivun käyttö edellyttää valtuutusta. Voit yrittää vaihtaa hakemistoa.
In my previous post we discussed how to modify a registry based GPO programmatically. In this post we will focus on using the GPMC ( Group Policy Management Console ) object model to find a GPO that contains a specific string in the display name.
The steps for using the GPMC to locate GPOs from C++ are straight forward:
1. Create an IGPM interface to initialize the GPMC dlls. (msdn.microsoft.com/en-us/library/aa814148(VS.85).aspx )
2. Use IGPM::GetDomain to initialize a SOM (Scope of Management) object to manage GPOs from a specific domain. (msdn.microsoft.com/en-us/library/aa814309(VS.85).aspx). This returns an IGPMDomain object (msdn.microsoft.com/en-us/library/aa814189(VS.85).aspx ).
3. Initialize a variant with the portion of the string you wish to match in the Display Name attribute of the GroupPolicyContainer object in the Active Directory.
4. Retrieve a GPMC Constants object from the IGPM interface by calling IGPM::GetConstants(). This method returns an IGPMConstants object (msdn.microsoft.com/en-us/library/aa814177(VS.85).aspx ) Using the GPMC constants object to retrieve GPMC constants will make the code much easier to read.
5. Create a Search Criteria object using the IGPMC::CreateSearchCriteria() method. This method returns an IGPMSearchCriteria object (msdn.microsoft.com/en-us/library/aa814259(VS.85).aspx ).
6. Using the IGPMConstants::get_SearchPropertyGPODisplayName() object, create a GPMSearchProperty object. This object will contain information that identifies the attribute you are searching for.
7. Using the IGPMConstants::get_SearchOpContains () method to retrieve a GPMSearchOperation object initialized to a wild card contains search.
8. Add the search property object ( GPMSearchProperty created in step 6) along with the search operation object ( GPMSearchOperation created in step 7) to the search criteria object ( created in step 5 ) with the variant ( initialized in step 3 ) using the IGPMSearchCriteria::Add method (msdn.microsoft.com/en-us/library/aa814260(VS.85).aspx )
9. Execute the search using the SOM domain object created in step 2 by calling the IGPMDomain::SearchForGPOs( ) method passing in the IGPMSearchCriteria object initialized in step 8. You will be given a IGPMGPOCollection object (msdn.microsoft.com/en-us/library/aa814200(VS.85).aspx ) containing the results of the search. The collection object will contain a set of IGPMGPO objects returned as variants containing IDispatch interfaces.
Let’s take a look at each step in a C++ code block.
//
// Locate a GPO with contains match and modify it
//
{
//
IGPM *pGPM = NULL; // Initial GPMC interface.
// Used to retrieve other GPO objects.
IGPMDomain *pDom = NULL; // Returned by pGPM, limits items
// to a specific domain.
IGPMGPO *pGPO = NULL; // The GPMC interface that
// represents a single GPO
IGPMConstants *pGPMConstants = NULL; // Used to help retrieve
// GPMC constants easily
IGPMSearchCriteria *pIGPMSearch = NULL; // Defines a search
// criteria to locate
// GPOs.
IGPMGPOCollection *pGPOCollection = NULL; // used to search for
// a GPO, this will
// contain the results
// of the search.
//
// To use _bstr_t classes must use the comutil library and
// and header files
//
_bstr_t bErrorStr("");
//
// Retrieve FQDN
//
wchar_t strFQDN[255], strDispName[255];
fflush( stdin );
printf("Enter the FQDN of the domain to create the GPO in: ");
_getws( strFQDN );
fflush(stdin);
//
// Retrieve Display Name
//
printf("Enter Display name for GPO to Match: ");
_getws( strDispName );
fflush(stdin);
//
// Step 1: Create and initialize the GPMC objects.
// Use the GPMC to create SOM and locate GPO
// To use this interface the GPMC components must be present
// on the client.
//
_bstr_t bstrFQDN(strFQDN);
hr = CoCreateInstance(CLSID_GPM, NULL,
CLSCTX_INPROC_SERVER,
IID_IGPM , (LPVOID*)&pGPM);
//
// Step 2: Retreive the SOM ( Scope of Management object )
// Retrieve a SOM object associated with the target domain
//
hr = pGPM->GetDomain( (BSTR)bstrFQDN, NULL, 0, &pDom);
//
// Step 3: initialize the search string into a variant.
//
_variant_t vData( strDispName );
//
// Step 4:
// Retreive the GPMC constants object.
//
hr = pGPM->GetConstants( &pGPMConstants );
if( FAILED(hr) )
{
bErrorStr = L"Failed to retrieve IGPMConstants";
goto CLEANUP_CONTAINS2;
}
//
// Step 5:
// Retrieve the search criteria object.
//
hr = pGPM->CreateSearchCriteria( &pIGPMSearch);
if( FAILED(hr) )
{
bErrorStr = L"Failed to create IGPMSearchCirteria";
goto CLEANUP_CONTAINS2;
}
//
// Step 6 & 7: Setup the search property and the
// search operation constants.
//
GPMSearchProperty sp;
GPMSearchOperation so;
//
// Contains Match for display name.
//
pGPMConstants->get_SearchPropertyGPODisplayName( &sp);
pGPMConstants->get_SearchOpContains( &so);
//
// Step 8:
// Add the search operation and property
// to the search criteria object.
//
pIGPMSearch->Add( sp, so, vData );
long lCount = 0;
//
// Step 9:
// Perform the search and retrieve the GOP collection.
//
hr = pDom->SearchGPOs( pIGPMSearch, &pGPOCollection);
if( FAILED(hr) )
{
bErrorStr = L"IGPMDomain::SearchGPOs failed";
vData.Clear();
goto CLEANUP_CONTAINS2;
}
//
// the following is an example of how to work
// with the GPO collection returned from the search.
// If we matched at least one item, lets use a helper
// function to retrieve the index of the GPO object
// from the collection.
//
pGPOCollection->get_Count( &lCount);
printf("Found %d GPOs that matched the display name criteria \"%S\"\n",
lCount, strDispName);
if( lCount > 0 )
{
long lIndex = 0;
//
// Get a selected GPO to delete
// if the count is 1, then we have only 1 item,
// if the count is > 1, then we need to
// ask the user to select one to modify.
//
if( lCount == 1 ) lIndex = 1;
else lIndex = RequestGPOIndex( pGPOCollection );
if( lIndex > 0 )
{
//
// Retrieve the mode and settings
//
int iMode = RequestMode();
DWORD lData = RequestSetting();
//
// Clear the variant to request an IDispatch
// pointer to the IGPMGPO interface that
// represents the GPO.
//
vData.Clear();
hr = pGPOCollection->get_Item( lIndex, &vData);
if( FAILED(hr) )
{
bErrorStr = L"Failed to retrieve IGPMGPO interface form collection";
goto CLEANUP_CONTAINS2;
}
//
// QI for the GPO interface
//
hr = vData.pdispVal->QueryInterface( IID_IGPMGPO,
(void **)&pGPO);
if( FAILED(hr) )
{
bErrorStr = L"Failed to retreive GPO pointer from vData.pdispVal->QueryInterface";
vData.Clear();
goto CLEANUP_CONTAINS2;
}
//
// Get the path to the GPO and then call the
// modify function.
//
BSTR bPath;
pGPO->get_Path( &bPath);
_bstr_t bADsPath("LDAP://");
bADsPath = bADsPath + strFQDN;
bADsPath = bADsPath + "/";
bADsPath = bADsPath + bPath;
SysFreeString( bPath );
hr = ModifyUserPolicyForPreventAccessToCmdPrompt(
bADsPath, iMode, lData);
if( SUCCEEDED(hr) ) bErrorStr = L"Successfully modified GPO";
else bErrorStr = L"Unable to modify GPO";
}
CLEANUP_CONTAINS2:
vData.Clear();
if( pGPO ) pGPO->Release();
if( pGPOCollection) pGPOCollection->Release();
if ( pIGPMSearch ) pIGPMSearch->Release();
if( pGPMConstants ) pGPMConstants->Release();
if( pGPM ) pGPM->Release();
if( pDom ) pDom->Release();
LPTSTR pstr = bErrorStr;
printf("%S\nLast HRESULT: %0X\n", pstr, hr);
CoUninitialize();
return hr;
}
}
break;
Below are 3 helper functions:
RequestGPOIndex – example of working with the GPO collection returned from the search.
RequestMode – retrieves the mode setting for the GPO.
RequestSetting – Retreives the data to be written to the registry.
int RequestMode ( )
{
int retval = -1;
BOOL bContinue = TRUE;
fflush(stdin);
while( (retval < 0 ) || ( retval > 2 ) )
{
printf("\nEnter GPO Mode Value:\n 0 - Not Configured\n 1 - Enabled\n 2 - Disabled\nEnter Selection: ");
fscanf_s(stdin, "%d", &retval);
if( (retval < 0 ) || ( retval > 2 )) printf("Invalid Mode Values, must be 0, 1, 2\n");
fflush(stdin);
}
return retval;
}
DWORD RequestSetting( )
{
int retval = -1;
BOOL bContinue = TRUE;
fflush(stdin);
while( (retval < 1 ) || ( retval > 2 ) )
{
printf("\nDisable the command prompt script processing also?\n 1 - Yes\n 2 - No\nEnter Selection: ");
fscanf_s(stdin, "%d", &retval);
if( (retval < 1 ) || ( retval > 2 )) printf("Invalid Mode Values, must be 1, 2\n");
fflush(stdin);
}
return retval;
}
long RequestGPOIndex( IGPMGPOCollection *pGPOs)
{
long lSelection = -1;
long lCount = 0;
if( pGPOs )
{
pGPOs->get_Count( &lCount );
_variant_t vData;
IGPMGPO *pGPO;
while ( (lSelection < 0) || (lSelection > lCount ) )
{
long lLoop = 1;
printf("GPOs in Collection:\n");
BSTR bID;
VARIANT_BOOL bUser;
VARIANT_BOOL bMachine;
HRESULT hr;
for( lLoop =1 ;lLoop <= lCount; lLoop++ )
{
hr = pGPOs->get_Item( lLoop, &vData );
hr = vData.pdispVal->QueryInterface(IID_IGPMGPO, (void **)&pGPO);
pGPO->get_ID( &bID);
pGPO->IsComputerEnabled( &bMachine );
pGPO->IsUserEnabled( &bUser);
printf(" %d -> ID: \"%S\"\n", lLoop, bID );
printf("\tUser Enabled: ");
if( bUser == VARIANT_TRUE ) printf(" Yes ");
else printf(" No ");
printf(" Machine Enabled: ");
if( bMachine ) printf(" Yes \n");
else printf(" No\n");
SysFreeString( bID );
pGPO->get_DisplayName( &bID );
printf("\tDisplay Name: \"%S\"\n", bID);
SysFreeString( bID );
pGPO->Release();
vData.Clear();
}
printf(" 0 -> No Selection\n\nEnter a number from 0 to %d: " , lCount);
fflush(stdin);
fscanf_s(stdin,"%d",&lSelection);
if( (lSelection < 0) || (lSelection > lCount) ) printf("\n\007Invalid Entry\n");
}
if( lSelection == 0 ) lSelection = -1;
}
return lSelection;
}
Comments
Anonymous
September 27, 2010
What caused this error? error LNK2001: unresolved external symbol _IID_IGPMAnonymous
April 27, 2011
Try after including 'gpmuuid.lib' libraryAnonymous
May 02, 2013
hi code is running well on windows server but when i run it on my xp machine then in following step i got error Class not Register hr = CoCreateInstance(CLSID_GPM, NULL, CLSCTX_INPROC_SERVER, IID_IGPM , (LPVOID*)&pGPM); even i register dll gpmgmt.dll on this machine please tell me how can i run this from aremote xp machine