Maintenance automatique

Plateformes

Clients – Windows 8
Serveurs – Windows Server 2012

Description

Windows dépend de l’exécution de l’activité de maintenance de boîte de réception et de maintenance tierce pour une grande partie de son ajout de valeur, y compris Windows Update, et la défragmentation automatique du disque, ainsi que les mises à jour et analyses antivirus. En outre, les entreprises utilisent fréquemment l’activité de maintenance telle que l’analyse NAP (Network Access Protection) pour aider à appliquer les normes de sécurité sur toutes les stations de travail d’entreprise.

L’activité de maintenance dans Windows est conçue pour s’exécuter en arrière-plan avec une interaction utilisateur limitée et un impact minimal sur les performances et l’efficacité énergétique. Toutefois, dans Windows 7 et versions antérieures, les performances et l’efficacité énergétique sont toujours affectées en raison du calendrier non déterministe et largement varié des activités de maintenance dans Windows. La réactivité des utilisateurs est réduite lorsque l’activité de maintenance s’exécute pendant que les utilisateurs utilisent activement l’ordinateur. Les applications demandent également fréquemment à l’utilisateur de mettre à jour son logiciel et d’exécuter une maintenance en arrière-plan et de diriger les utilisateurs vers plusieurs expériences, notamment le Centre d’action, Panneau de configuration, Windows Update, le composant logiciel enfichable MMC Task Scheduler et les contrôles tiers.

L’objectif de Maintenance automatique est de combiner toutes les activités de maintenance en arrière-plan dans Windows et aider les développeurs tiers à ajouter leur activité de maintenance à Windows sans impact négatif sur les performances et l’efficacité énergétique. En outre, Maintenance automatique permet aux utilisateurs ainsi qu’aux entreprises de contrôler la planification et la configuration des activités de maintenance.

Problèmes clés

Maintenance automatique est conçu pour résoudre ces problèmes liés à l’activité de maintenance dans Windows :

  • Planification des échéances
  • Conflits d’utilisation des ressources
  • Efficacité énergétique
  • Transparence de l’utilisateur

Fonctionnalités

Maintenance automatique facilite l’efficacité inactive et permet à toutes les activités de s’exécuter en temps opportun et de manière hiérarchisée. Elle permet également d’activer la visibilité unifiée et le contrôle de l’activité de maintenance, et permet aux développeurs tiers d’ajouter leur activité de maintenance à Windows sans impact négatif sur les performances et l’efficacité énergétique. Pour ce faire, il fournit un mode entièrement automatique, un mode initié par l’utilisateur, un arrêt automatique, des délais et des notifications et un contrôle d’entreprise. Chacune d’elles est décrite ci-dessous.

Mode entièrement automatique

Ce mode par défaut active la planification intelligente pendant le temps d’inactivité du PC et à des moments planifiés , l’exécution et la suspension automatique de l’activité de maintenance sans aucune intervention de l’utilisateur. L’utilisateur peut définir une planification hebdomadaire ou quotidienne. Toutes les activités de maintenance ne sont pas interactives et s’exécutent en mode silencieux.

L’ordinateur reprend automatiquement du sommeil lorsque le système n’est pas susceptible d’être utilisé, en respectant la stratégie de gestion de l’alimentation, qui, dans le cas des ordinateurs portables, autorise par défaut l’éveil uniquement s’il se trouve sur l’alimentation ac. Les ressources système complètes à puissance élevée sont utilisées pour terminer l’activité de maintenance aussi rapidement que possible. Si le système a été repris du sommeil pour Maintenance automatique, il est demandé de revenir au sommeil.

Toutes les interactions utilisateur requises liées aux activités telles que la configuration sont effectuées en dehors de Maintenance automatique exécution.

Mode initié par l’utilisateur

Si les utilisateurs doivent se préparer au voyage, attendez-vous à être sur batterie pendant une durée prolongée ou souhaitez optimiser les performances et la réactivité, ils ont la possibilité de lancer Maintenance automatique à la demande. Les utilisateurs peuvent configurer Maintenance automatique attributs, y compris la planification d’exécution automatique. Ils peuvent afficher l’état actuel de l’exécution de Maintenance automatique, et ils peuvent arrêter Maintenance automatique si nécessaire.

Arrêt automatique

Maintenance automatique arrête automatiquement les activités de maintenance en cours d’exécution si l’utilisateur commence à interagir avec l’ordinateur. L’activité de maintenance reprend lorsque le système retourne à l’état inactif.

Notes

Toutes les activités de Maintenance automatique doivent prendre en charge l’arrêt en 2 secondes ou moins. L’utilisateur doit être averti que l’activité a été arrêtée.

 

Délais et notification

L’activité de maintenance critique doit s’exécuter dans une fenêtre de temps prédéfinie. Si les tâches critiques n’ont pas pu s’exécuter dans leur temps désigné, Maintenance automatique démarre automatiquement l’exécution au prochain moment d’inactivité du système disponible. Toutefois, si l’état de la tâche reste derrière l’échéance, Maintenance automatique avertira l’utilisateur de l’activité et fournira une option pour une exécution manuelle de Maintenance automatique. Toutes les tâches planifiées pour la maintenance s’exécutent, bien que les tâches les plus affamées soient prioritaires. Cette activité peut avoir un impact sur la réactivité et les performances du système ; par conséquent, Maintenance automatique avertira l’utilisateur que l’activité de maintenance critique s’exécute.

contrôle Enterprise

Enterprise professionnels de l’informatique doivent être en mesure de déterminer quand Maintenance automatique s’exécute sur leurs systèmes Windows, appliquer cette planification via des interfaces de gestion standardisées et récupérer des données d’événement sur l’état des tentatives d’exécution de Maintenance automatique. En outre, les professionnels de l’informatique doivent pouvoir appeler une activité de Maintenance automatique spécifique à distance via des interfaces de gestion standard. Chaque fois que Maintenance automatique s’exécute, la création de rapports d’état, y compris les notifications lorsque Maintenance automatique n’a pas pu être exécutée, car l’utilisateur a suspendu manuellement l’activité, s’exécute. Les professionnels de l’informatique doivent envisager de déplacer des scripts d’ouverture de session vers Maintenance automatique pour aider à accélérer l’expérience d’ouverture de session de l’utilisateur.

Création d’une tâche Maintenance automatique

Cette section explique comment les développeurs peuvent créer une tâche à l’aide d’une définition de tâche dans le langage XML ou C. N’oubliez pas que l’activité de maintenance ne doit pas lancer une interface utilisateur qui nécessite une interaction utilisateur, car Maintenance automatique est complètement silencieux et s’exécute lorsque l’utilisateur n’est pas présent. En effet, si l’utilisateur interagit avec l’ordinateur pendant Maintenance automatique, toutes les tâches en cours de processus seront terminées jusqu’à la prochaine période d’inactivité.

Utilisation de XML

Le planificateur de tâches inclut un outil en ligne de commande intégré, schtasks.exe, qui peut importer une définition de tâche au format XML. Le schéma de définition de tâche est documenté à l’adresse https://msdn.microsoft.com/library/aa383609(v=VS.85).aspx. Voici un exemple de tâche Maintenance automatique définie dans XML.

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2011-07-01T11:34:31</Date>
    <Author>IT Deptartment</Author>
  </RegistrationInfo>
  <Principals>
    <Principal id="Author">
      <RunLevel>LeastPrivilege</RunLevel>
      <GroupId>NT AUTHORITY\SYSTEM</GroupId>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <MaintenanceSettings>
      <Period>P2D</Period>
      <Deadline>P14D</Deadline>
    </MaintenanceSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
    <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>cmd</Command>
      <Arguments>/c timeout -t 60</Arguments>
    </Exec>
  </Actions>
</Task> 

Pour enregistrer la tâche sur un ordinateur Windows, enregistrez le code XML ci-dessus en tant que fichier texte et utilisez cette ligne de commande :

Schtasks.exe /create /tn <task name> /xml <text file name>

Utilisation de C

Une tâche Maintenance automatique peut également être créée à l’aide du code C. Voici un exemple de code qui peut être utilisé pour configurer les paramètres Maintenance automatique d’une tâche :

/********************************************************************
This sample creates a maintenance task to start cmd window during maintenance opportunities with periodicity of 2 days and deadline 0f 14 days.
********************************************************************/

#define _WIN32_DCOM

#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <comdef.h>
#include <wincred.h>
//  Include the task header file.
#include <taskschd.h>
//#pragma comment(lib, "taskschd.lib")
//#pragma comment(lib, "comsupp.lib")

int __cdecl 
MainteanceTask( )
{
    //  ------------------------------------------------------
    //  Initialize COM.
    HRESULT hr;

    //  ------------------------------------------------------
    //  Create a name for the task.
    LPCWSTR wszTaskName = L"MaintenanceTask";

    ITaskService *pService = NULL;
    ITaskFolder *pRootFolder = NULL;
    ITaskDefinition *pTask = NULL;
    ITaskSettings *pSettings = NULL;
    IRegistrationInfo *pRegInfo= NULL;
    IPrincipal *pPrincipal = NULL;
    ITaskSettings3 *pSettings3 = NULL;
    IMaintenanceSettings* pMaintenanceSettings = NULL;
    IActionCollection *pActionCollection = NULL;
    IAction *pAction = NULL;
    IExecAction *pExecAction = NULL;
    IRegisteredTask *pRegisteredTask = NULL;

    wprintf(L"\nCreate Maintenance Task %ws", wszTaskName );

    hr = CoInitializeEx( NULL, COINIT_MULTITHREADED);
    if( FAILED(hr) )
    {
        wprintf(L"\nCoInitializeEx failed: %x", hr );
        return 1;
    }

    //  Set general COM security levels.
    hr = CoInitializeSecurity( NULL,
        -1,
        NULL,
        NULL,
        RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        0,
        NULL);

    if( FAILED(hr) )
    {
        wprintf(L"\nCoInitializeSecurity failed: %x", hr );
        goto CleanUp;
    }

    //  ------------------------------------------------------
    //  Create an instance of the Task Service. 
    hr = CoCreateInstance( CLSID_TaskScheduler,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ITaskService,
                           (void**)&pService );  
    if (FAILED(hr))
    {
        wprintf(L"\nFailed to create an instance of ITaskService: %x", hr);
        goto CleanUp;
    }
        
    //  Connect to the task service.
    hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
    if( FAILED(hr) )
    {
        wprintf(L"\nITaskService::Connect failed: %x", hr );
        goto CleanUp;
    }

    //  ------------------------------------------------------
    //  Get the pointer to the root task folder.  This folder will hold the
    //  new task that is registered.
    hr = pService->GetFolder( _bstr_t( L"\\") , &pRootFolder );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot get Root folder pointer: %x", hr );
        goto CleanUp;
    }
    
    //  If the same task exists, remove it.
    ( void ) pRootFolder->DeleteTask( _bstr_t(wszTaskName), 0  );
    
    //  Create the task definition object to create the task.
    hr = pService->NewTask( 0, &pTask );
    if (FAILED(hr))
    {
        wprintf(L"\nFailed to CoCreate an instance of the TaskService class: %x", hr);
        goto CleanUp;
    }
        
    //  ------------------------------------------------------
    //  Get the registration info for setting the identification.
    hr = pTask->get_RegistrationInfo( &pRegInfo );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot get identification pointer: %x", hr );
        goto CleanUp;
    }
    
    hr = pRegInfo->put_Author( _bstr_t(L"Author Name") );    
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot put identification info: %x", hr );
        goto CleanUp;
    }

    // The task needs to grant explicit FRFX to LOCAL SERVICE (A;;FRFX;;;LS)
    hr = pRegInfo->put_SecurityDescriptor( _variant_t(L"D:P(A;;FA;;;BA)(A;;FA;;;SY)(A;;FRFX;;;LS)") );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot put security descriptor: %x", hr );
        goto CleanUp;
    }

    //  ------------------------------------------------------
    //  Create the principal for the task - these credentials
    //  are overwritten with the credentials passed to RegisterTaskDefinition
    hr = pTask->get_Principal( &pPrincipal );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot get principal pointer: %x", hr );
        goto CleanUp;
    }
    
    //  Set up principal logon type to interactive logon
    hr = pPrincipal->put_LogonType( TASK_LOGON_INTERACTIVE_TOKEN );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot put principal info: %x", hr );
        goto CleanUp;
    }  

    //  ------------------------------------------------------
    //  Create the settings for the task
    hr = pTask->get_Settings( &pSettings );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot get settings pointer: %x", hr );
        goto CleanUp;
    }

    hr = pSettings->QueryInterface( __uuidof(ITaskSettings3), (void**) &pSettings3 );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot query ITaskSettings3 interface: %x", hr );
        goto CleanUp;
    }

    hr = pSettings3->put_UseUnifiedSchedulingEngine( VARIANT_TRUE );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot put_UseUnifiedSchedulingEngine: %x", hr );
        goto CleanUp;
    }

    hr = pSettings3->CreateMaintenanceSettings( &pMaintenanceSettings );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot CreateMaintenanceSettings: %x", hr );
        goto CleanUp;
    }

    hr = pMaintenanceSettings->put_Period ( _bstr_t(L"P2D") );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot put_Period: %x", hr );
        goto CleanUp;
    }

    hr = pMaintenanceSettings->put_Deadline ( _bstr_t(L"P14D") );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot put_Period: %x", hr );
        goto CleanUp;
    }

    //  ------------------------------------------------------
    //  Add an action to the task. This task will execute cmd.exe.     
    //  Get the task action collection pointer.
    hr = pTask->get_Actions( &pActionCollection );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot get Task collection pointer: %x", hr );
        goto CleanUp;
    }
    
    //  Create the action, specifying that it is an executable action.
    hr = pActionCollection->Create( TASK_ACTION_EXEC, &pAction );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot create the action: %x", hr );
        goto CleanUp;
    }

    //  QI for the executable task pointer.
    hr = pAction->QueryInterface( IID_IExecAction, (void**) &pExecAction );
    if( FAILED(hr) )
    {
        wprintf(L"\nQueryInterface call failed for IExecAction: %x", hr );
        goto CleanUp;
    }

    //  Set the path of the executable to cmd.exe.
    hr = pExecAction->put_Path( _bstr_t(L"cmd") );
    if( FAILED(hr) )
    {
        wprintf(L"\nCannot put action path: %x", hr );
        goto CleanUp;
    }  
    
    //  ------------------------------------------------------
    //  Save the task in the root folder.
    hr = pRootFolder->RegisterTaskDefinition(
            _bstr_t(wszTaskName),
            pTask,
            TASK_CREATE_OR_UPDATE, 
            _variant_t(), 
            _variant_t(), 
            TASK_LOGON_INTERACTIVE_TOKEN,
            _variant_t(L""),
            &pRegisteredTask);
    if( FAILED(hr) )
    {
        wprintf(L"\nError saving the Task : %x", hr );
        goto CleanUp;
    }
    
    wprintf(L"\nSuccess!\n----------------------------------" );

CleanUp:

    if ( pService != NULL ) pService->Release();
    if ( pRootFolder != NULL ) pRootFolder->Release();
    if ( pTask != NULL ) pTask->Release();
    if ( pSettings != NULL ) pSettings->Release();
    if ( pRegInfo != NULL ) pRegInfo->Release();
    if ( pPrincipal != NULL ) pPrincipal->Release();
    if ( pSettings3 != NULL ) pSettings3->Release();
    if ( pMaintenanceSettings != NULL ) pMaintenanceSettings->Release();
    if ( pActionCollection != NULL ) pActionCollection->Release();
    if ( pAction != NULL ) pAction->Release();
    if ( pExecAction != NULL ) pExecAction->Release();
    if ( pRegisteredTask != NULL ) pRegisteredTask->Release();

    CoUninitialize();
    return SUCCEEDED ( hr ) ? 0 : 1;
}

Validation des tâches

Vérifiez que la tâche a été créée avec succès et s’exécute dans le cadre de la maintenance.

Validation de la création de tâches

Utilisez cette ligne de commande pour exporter la définition de tâche vers un fichier et vérifier que la définition de tâche est comme prévu :

Schtasks.exe /Query /tn<task name> /xml <text file name>

Validation de l’exécution de tâches

Exécutez cette ligne de commande pour lancer la tâche et valider que l’interface utilisateur du planificateur de tâches (taskschd.msc) affiche l’exécution de la tâche :

Schtasks.exe /Run /tn<task name>

Ressources