Share via


Managing Site Control Configuration

The site control file maintains the current configuration of the site. You use the following SMS_SiteControlFile methods to manage changes to the site control file.

Method Description
CommitSCF Applies your changes to the Microsoft® Systems Management Server (SMS) database. This method replaces the Commit method.
RefreshSCF Refreshes your in-memory copy of the site control file with any recent changes from the SMS database. This method replaces the Refresh method.
GetSessionHandle Gets you an in-memory copy of the site control file and a session handle. You place the session handle in an IWbemContext object that is passed to all IWbemServices methods.
ReleaseSessionHandle Releases your in-memory copy of the site control file and any resources associated with your session handle.

Caution  You should be experienced in managing a site's configuration before using the SMS Provider classes to modify the site configuration. You can cause great harm to a site by changing some configurable items. You should use extreme caution or avoid using the SMS_SCI_FileDefinition and SMS_SCI_SiteDefinition classes altogether. These classes manage the site control file itself. If you are not careful, you can render the site useless.

For more information about how to modify a site's configuration using the console before you use the provider to do the same, see the SMS Administrator's Guide.

The following example shows you how to use the site control methods to change the Number of Retries property of the SMS_DISTRIBUTION_MANAGER component.

  [Visual Basic]
    On Error Resume Next

    Dim Services As SWbemServices
    Dim SMSContext As New SWbemNamedValueSet      'Create the context qualifer object
    Dim SCF As SWbemObject                        'SMS_SiteControlFile class
    Dim SCIComponent As SWbemObject               'Instance of SMS_SCI_Component
    Dim SCIComponentSet As SWbemObjectSet         'Query results
    Dim SCICompPath As SWbemObjectPath            'Path to the updated component
    Dim InParams As SWbemObject
    Dim SessionHandle As String
    Dim Query As String
    Dim Retries As Long
    Dim vProperty As Variant

    'Add the standard SMS context qualifiers to the context object
    SMSContext.Add "LocaleID", "MS\1033"
    SMSContext.Add "MachineName", "MyMachine"
    SMSContext.Add "ApplicationName", "MyApp"

    Set Services = GetObject("winmgmts:root/sms/site_<sitecode>")

    Set SCF = Services.Get("SMS_SiteControlFile")
    SCF.GetSessionHandle SessionHandle
    SMSContext.Add "SessionHandle", SessionHandle

    Query = "SELECT * FROM SMS_SCI_Component " & _
            "WHERE ComponentName = 'SMS_DISTRIBUTION_MANAGER' " & _
            "AND SiteCode = '<sitecode>' "

    Set SCIComponentSet = Services.ExecQuery(Query, , _
                          wbemFlagForwardOnly Or wbemFlagReturnImmediately, SMSContext)

    'Only one instance is returned from the query.
    For Each SCIComponent In SCIComponentSet

        'Loop through the array of embedded SMS_EmbeddedProperty instances for the
        'Number of Retries PropertyName. Get its value so the value can be restored
        'after it is modified.
        For Each vProperty In SCIComponent.Props
            If vProperty.PropertyName = "Number of Retries" Then
                Retries = vProperty.Value
                MsgBox "Retry value before change is " & Retries

                'Modify the value and exit.
                vProperty.Value = 500
                Exit For
            End If
        Next

        'Update the component in your copy of the site control file. Get the path
        'to the updated object, which is used later to retrieve the instance.
        Set SCICompPath = SCIComponent.Put_(wbemChangeFlagUpdateOnly, SMSContext)
    Next

    'Commit the change to the actual site control file.
    Set InParams = Services.Get("SMS_SiteControlFile").Methods_("CommitSCF").InParameters.SpawnInstance_
    InParams.SiteCode = "<sitecode>"
    Services.ExecMethod "SMS_SiteControlFile", "CommitSCF", InParams, , SMSContext

    'Open the console and review the changes to the software distribution properties
    'under the component configuration site settings.

    'Refresh the in-memory copy of the site control file.
    Set InParams = Services.Get("SMS_SiteControlFile").Methods_("RefreshSCF").InParameters.SpawnInstance_
    InParams.SiteCode = "<sitecode>"
    Services.ExecMethod "SMS_SiteControlFile", "RefreshSCF", InParams, , SMSContext

    'Get the component instance that you updated earlier.
    Set SCIComponent = Services.Get(SCICompPath.RelPath, , SMSContext)

    'Loop through the array of embedded SMS_EmbeddedProperty instances for the
    'Number of Retries PropertyName. Get its value and display it.
    For Each vProperty In SCIComponent.Props
        If vProperty.PropertyName = "Number of Retries" Then
            MsgBox "Retry value after change is " & vProperty.Value

            'Reset the retry number to the original value and exit.
            vProperty.Value = Retries
            Exit For
        End If
    Next

    'Update your copy of the site control file.
    Set SCICompPath = SCIComponent.Put_(wbemChangeFlagUpdateOnly, SMSContext)

    'Commit your changes to the actual site control file.
    Set InParams = Services.Get("SMS_SiteControlFile").Methods_("CommitSCF").InParameters.SpawnInstance_
    InParams.SiteCode = "<sitecode>"
    Services.ExecMethod "SMS_SiteControlFile", "CommitSCF", InParams, , SMSContext

    'Release your copy of the site control file.
    SCF.ReleaseSessionHandle SessionHandle


[C/C++]
    IWbemClassObject      *pclsSCF = NULL;            //SMS_SiteControlFile class
    IWbemClassObject      *pdefInParams = NULL;       //Definition of in parameters
    IWbemClassObject      *pinstInParams = NULL;      //Instance of in parameters
    IWbemClassObject      *pinstOutParams = NULL;     //Instance of out parameters
    IEnumWbemClassObject  *penumSCICompSet = NULL;    //SMS_SCI_Component enumeration
    IWbemClassObject      *pinstSCIComp = NULL;       //Instance of SMS_SCI_Component
    IWbemCallResult       *pSCICompPath = NULL;       //Object path to the component
    IWbemClassObject      *pinstProperty = NULL;      //Embedded property instance
    _bstr_t                bstrQuery;
    _bstr_t                SessionHandle;             //Identifies copy of the SCF
    _variant_t             vPropertySet;              //SMS_SCI_Component.Props
    _variant_t             vTemp;
    long                   LBound, UBound, i;         //SafeArray items
    long                   Retries;                   //Value for Number of retries
    unsigned long          ulReturned;


    //First step is to get a copy of the site control file using GetSessionHandle.
    hr = pServices->GetObject(_bstr_t(L"SMS_SiteControlFile"), 0, NULL, &pclsSCF, NULL);
    hr = pServices->ExecMethod(_bstr_t(L"SMS_SiteControlFile"),
                               _bstr_t(L"GetSessionHandle"),
                               0, NULL, NULL, &pinstOutParams, NULL);

    //Add the session handle to the context object. The context object must be passed
    //to all calls, object and services, that reference the SCF. If you don't pass the
    //context object, the in-memory copy of the SCF will not be changed.
    pinstOutParams->Get(_bstr_t(L"SessionHandle"), 0, &vTemp, 0, 0);
    hr = pSMSContext->SetValue(_bstr_t(L"SessionHandle"), 0, &vTemp);
    pinstOutParams->Release();
    pinstOutParams = NULL;

    bstrQuery = L"SELECT * FROM SMS_SCI_Component "
                L"WHERE ComponentName = \"SMS_DISTRIBUTION_MANAGER\" "
                L"AND   SiteCode = \"<sitecode>\" ";

    hr = pServices->ExecQuery(_bstr_t(L"WQL"), bstrQuery,
                              WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
                              pSMSContext, &penumSCICompSet);

    //Only one instance is returned in the enumeration.
    hr = penumSCICompSet->Next(WBEM_INFINITE, 1, &pinstSCIComp, &ulReturned);

    hr = pinstSCIComp->Get(_bstr_t(L"Props"), 0, &vPropertySet, 0, 0);
    SafeArrayGetLBound(V_ARRAY(&vPropertySet), 1, &LBound);
    SafeArrayGetUBound(V_ARRAY(&vPropertySet), 1, &UBound);

    //Loop through the Props array for the Number of Retries property. Save its value
    //so it can be reset later, modify the value, and save the instance back to the
    //array.
    for (i = LBound; i <= UBound; i++)
    {
        SafeArrayGetElement(V_ARRAY(&vPropertySet), &i, &pinstProperty);
        hr = pinstProperty->Get(_bstr_t(L"PropertyName"), 0, &vTemp, 0, 0);

        if ( _bstr_t(vTemp) == _bstr_t(L"Number of Retries") )
        {
            char  sz[50];

            hr = pinstProperty->Get(_bstr_t(L"Value"), 0, &vTemp, 0, 0);
            Retries = (long)vTemp;

            sprintf(sz, "Retry value before change is %d", Retries);
            MessageBox(HWND_DESKTOP, sz, "SCI Test", MB_OK);

            vTemp = (long)600;
            hr = pinstProperty->Put(_bstr_t(L"Value"), 0, &vTemp, NULL);

            hr = SafeArrayPutElement(V_ARRAY(&vPropertySet), &i, pinstProperty);
            pinstProperty->Release();
            pinstProperty = NULL;

            break;
        }
        pinstProperty->Release();
        pinstProperty = NULL;
    }

    //Update the component instance with the new retries value
    vTemp = vPropertySet;
    hr = pinstSCIComp->Put(L"Props", 0, &vTemp, NULL);
    hr = pServices->PutInstance(pinstSCIComp, WBEM_FLAG_UPDATE_ONLY,
                                pSMSContext, &pSCICompPath);

    penumSCICompSet->Release();
    pinstSCIComp->Release();
    pinstSCIComp = NULL;


    //Commit the change to the actual site control file.
    hr = pclsSCF->GetMethod(_bstr_t(L"CommitSCF"), 0, &pdefInParams, NULL);
    hr = pdefInParams->SpawnInstance(0, &pinstInParams);
    pdefInParams->Release();
    pdefInParams = NULL;

    vTemp = _bstr_t(L"<sitecode>");
    pinstInParams->Put(_bstr_t(L"SiteCode"), 0, &vTemp, NULL);
    hr = pServices->ExecMethod(_bstr_t(L"SMS_SiteControlFile"), _bstr_t(L"CommitSCF"),
                               0, pSMSContext, pinstInParams, NULL, NULL);
    pinstInParams->Release();
    pinstInParams = NULL;


    //Refresh the in-memory copy of the SCF.
    hr = pclsSCF->GetMethod(_bstr_t(L"RefreshSCF"), 0, &pdefInParams, NULL);
    hr = pdefInParams->SpawnInstance(0, &pinstInParams);
    pdefInParams->Release();
    pdefInParams = NULL;

    vTemp = _bstr_t(L"<sitecode>");
    pinstInParams->Put(_bstr_t(L"SiteCode"), 0, &vTemp, NULL);
    hr = pServices->ExecMethod(_bstr_t(L"SMS_SiteControlFile"),
                               _bstr_t(L"RefreshSCF"),
                               0, pSMSContext, pinstInParams, NULL, NULL);
    pinstInParams->Release();
    pinstInParams = NULL;


    //Get the SCI component using the object path from the earlier update.
    BSTR  bstrPath = NULL;
    hr = pSCICompPath->GetResultString(0, &bstrPath);
    hr = pServices->GetObject(bstrPath, 0, pSMSContext, &pinstSCIComp, NULL);
    SysFreeString(bstrPath);

    //Go through the process again of finding the Number of Retries property.
    //Ensure the value has changed and then reset it to its original value.
    //You can also check the value using the SMS console.
    hr = pinstSCIComp->Get(_bstr_t(L"Props"), 0, &vPropertySet, 0, 0);
    SafeArrayGetLBound(V_ARRAY(&vPropertySet), 1, &LBound);
    SafeArrayGetUBound(V_ARRAY(&vPropertySet), 1, &UBound);

    for (i = LBound; i <= UBound; i++)
    {
        SafeArrayGetElement(V_ARRAY(&vPropertySet), &i, &pinstProperty);
        hr = pinstProperty->Get(_bstr_t(L"PropertyName"), 0, &vTemp, 0, 0);

        if (_bstr_t(vTemp) == _bstr_t(L"Number of Retries"))
        {
            char  sz[50];

            hr = pinstProperty->Get(_bstr_t(L"Value"), 0, &vTemp, 0, 0);
            sprintf(sz, "Retry value after change is %d", (long)vTemp);
            MessageBox(HWND_DESKTOP, sz, "SCI Test", MB_OK);

            vTemp = (long)Retries;
            hr = pinstProperty->Put(_bstr_t(L"Value"), 0, &vTemp, NULL);
            hr = SafeArrayPutElement(V_ARRAY(&vPropertySet), &i, pinstProperty);
            pinstProperty->Release();
            pinstProperty = NULL;

            break;
        }
        pinstProperty->Release();
        pinstProperty = NULL;
    }

    vTemp = vPropertySet;
    hr = pinstSCIComp->Put(L"Props", 0, &vTemp, NULL);
    hr = pServices->PutInstance(pinstSCIComp, WBEM_FLAG_UPDATE_ONLY,
                                pSMSContext, NULL);
    pinstSCIComp->Release();
    pinstSCIComp = NULL;

    hr = pclsSCF->GetMethod(_bstr_t(L"CommitSCF"), 0, &pdefInParams, NULL);
    hr = pdefInParams->SpawnInstance(0, &pinstInParams);
    pdefInParams->Release();
    pdefInParams = NULL;

    vTemp = _bstr_t(L"<sitecode>");
    pinstInParams->Put(_bstr_t(L"SiteCode"), 0, &vTemp, NULL);
    hr = pServices->ExecMethod(_bstr_t(L"SMS_SiteControlFile"), _bstr_t(L"CommitSCF"),
                               0, pSMSContext, pinstInParams, NULL, NULL);
    pinstInParams->Release();
    pinstInParams = NULL;


    //Release our copy of the site control file.
    hr = pclsSCF->GetMethod(_bstr_t(L"ReleaseSessionHandle"), 0, &pdefInParams, NULL);
    hr = pdefInParams->SpawnInstance(0, &pinstInParams);
    pdefInParams->Release();
    pdefInParams = NULL;

    hr = pSMSContext->GetValue(L"SessionHandle", 0, &vTemp);
    pinstInParams->Put(_bstr_t(L"SessionHandle"), 0, &vTemp, NULL);
    hr = pServices->ExecMethod(_bstr_t(L"SMS_SiteControlFile"),
                               _bstr_t(L"ReleaseSessionHandle"),
                               0, pSMSContext, pinstInParams, NULL, NULL);
    pinstInParams->Release();
    pinstInParams = NULL;

    pclsSCF->Release();
    pSMSContext->Release();