Mai 2016

Volume 31,numéro 5

Cet article a fait l'objet d'une traduction automatique.

Windows PowerShell : écrire des services Windows dans PowerShell

Par Jean-François Larvoire | Mai 2016 | Obtenir le Code de

Les Services Windows sont normalement compilés programmes écrits en C, C++, c# ou autres langages Microsoft .NET Framework, et ces services de débogage peut être assez difficile. Quelques mois plus tôt, inspirés par d'autres systèmes d'exploitation qui permettent la création de services en tant que scripts de shell simple, j'ai commencé à me demande s'il peut être plus facilement les créer dans Windows, ainsi.

Cet article présente le résultat final de cet effort : Un moyen simple et nouvel pour créer des Services Windows, en les écrivant dans le langage de script Windows PowerShell. Pas plus de compilation, juste un cycle de modifier/test rapide qui peut être effectuée sur n'importe quel système, pas seulement le développeur.

Fournir un modèle de script de service générique appelé PSService.ps1, qui vous permet de créer et tester les nouveaux Services Windows en quelques minutes, avec seulement un éditeur de texte tel que le bloc-notes. Cette technique peut enregistrer beaucoup d'efforts de développement et de temps pour toute personne souhaitant faire des essais avec les Services Windows, ou même de fournir des services réels pour Windows lors de la performance n'est pas un facteur critique. PSService.ps1 peut être téléchargé à partir de bit.ly/1Y0XRQB.

Qu'est un Service Windows ?

Les Services Windows sont des programmes qui s'exécutent en arrière-plan, sans aucune interaction utilisateur. Par exemple, un serveur Web, ce qui est en mode silencieux répond aux demandes HTTP pour les pages Web à partir du réseau, est un service, est une application de surveillance qui enregistre les mesures de performances ou enregistre les événements de capteur matériel en mode silencieux.

Services peuvent de démarrer automatiquement au démarrage du système. Ou ils peuvent démarrer à la demande, comme requis par les applications qui s'appuient sur ces derniers. Services s'exécutent dans leur propre session Windows, distincte de la session de l'interface utilisateur. Leur exécution dans un nombre de processus système, avec des droits soigneusement sélectionnées pour limiter les risques de sécurité.

Le Gestionnaire de contrôle de Service Windows

Ces services sont gérés par le Gestionnaire de contrôle des services Windows (SCM). Le SCM est responsable de la configuration des services, Démarrer, arrêter et ainsi de suite.

Le panneau de configuration SCM est accessible via le panneau de configuration | Système et sécurité | Outils d'administration | Services. En tant que Figure 1 montre, il affiche une liste de tous les services configurés avec leur nom, la description, état, nom d'utilisateur et le type de démarrage.

L'interface utilisateur graphique du Gestionnaire de contrôle des services Windows dans Windows 10
Figure 1 l'interface utilisateur graphique du Gestionnaire de contrôle des services Windows dans Windows 10

Il existe également des interfaces de ligne de commande au SCM :

  • Les dates à partir de l'ancien outil net.exe, avec ses bien connu « net start » et les commandes « net stop », jusqu'à MS-DOS ! Malgré son nom, il peut être utilisé pour démarrer et arrêter un service, et pas seulement les services réseau. Tapez « net help » pour plus d'informations.
  • Un outil plus puissant appelé sc.exe, introduit dans Windows NT, donne un contrôle précis sur tous les aspects de la gestion des services. Type « sc /? » pour plus d'informations.

Ces outils de ligne de commande, bien que toujours présentes dans Windows 10, sont désormais déconseillées au profit des fonctions de gestion de service Windows PowerShell, décrites plus loin.

Piège n : Net.exe et sc.exe utilisent le nom de service d'un mot « court », qui, malheureusement, n'est pas le même que le nom plus descriptif affiché par le panneau de configuration SCM. Pour obtenir la correspondance entre les deux noms, utilisez la commande get-service Windows PowerShell.

États du service

Les services peuvent être dans différents états. Certains États sont requis, d'autres sont facultatifs. Les deux États de base que tous les services doivent prendre en charge sont arrêtés et démarrés. Ces s'affichent respectivement (vide) ou en cours d'exécution la colonne état Figure 1.

Un troisième état facultatif est suspendu. Et un autre état implicit que chaque service prend en charge même si elle n'est pas mentionnée est désinstallé.

Un service peut rendre les transitions entre ces États, comme indiqué dans Figure 2.

États du service
Figure 2 États

Enfin, il existe également plusieurs états transitoires gérant des services peuvent éventuellement : StartPending, StopPending, PausePending, ContinuePending. Ils sont utiles uniquement si les transitions d'état prennent beaucoup de temps.

Fonctions de gestion du Service Windows PowerShell

Windows PowerShell a été le shell de gestion système recommandée depuis Windows Vista. Il inclut un puissant langage de script et une grande bibliothèque de fonctions pour gérer tous les aspects du système d'exploitation. Certains des points forts de Windows PowerShell sont :

  • Noms de fonction cohérente
  • Entièrement orienté objet
  • Faciliter la gestion d'un objet .NET

Windows PowerShell fournit de nombreuses fonctions de gestion de service, qui sont appelées des applets de commande. Figure 3 présente quelques exemples.

Fonctions de gestion de la figure 3 Windows PowerShell Service

Nom de la fonction Description
Start-Service Démarre un ou plusieurs services arrêtés
Stop-Service Arrête un ou plusieurs services en cours d'exécution
Nouveau Service Installe un nouveau service
Get-Service Obtient les services sur un ordinateur local ou distant, avec leurs propriétés
Set-Service Démarre, arrête et interrompt un service modifie ses propriétés.

 

Pour obtenir une liste complète de toutes les commandes avec la chaîne « service » dans leurs noms, exécutez :

Get-Command *service*

Pour obtenir la liste de simplement les fonctions de gestion de service, exécutez :

Get-Command -module Microsoft.PowerShell.Management *service*

Étonnamment, il n'existe aucune fonction de Windows PowerShell pour supprimer (qui désinstalle) un service. C'est une des rares cas lorsqu'il est toujours nécessaire d'utiliser l'outil sc.exe ancien :

sc.exe delete $serviceName

La classe ServiceBase .NET

Tous les services doivent créer un objet .NET dérivant de la classe ServiceBase. Documentation Microsoft décrit toutes les propriétés et méthodes de cette classe. Figure 4 répertorie quelques-unes de ces éléments, présente un intérêt particulier pour ce projet.

Figure 4 certaines propriétés et méthodes de la classe ServiceBase

Membre Description
ServiceName Nom abrégé utilisé pour identifier le service sur le système
CanStop Si le service peut être arrêté une fois qu'il a démarré.
OnStart() Actions à entreprendre lorsque le service démarre
OnStop() Actions à entreprendre lorsque le service s'arrête
Run() Inscrit l'exécutable du service pour le GCL

 

Par l'implémentation de ces méthodes, une application de service peut être gérable par le SCM pour démarrer automatiquement au démarrage ou à la demande ; et il s'agit de gérable par le panneau SCM, par l'ancien net.exe et commandes sc.exe ou par les nouvelles fonctions Windows PowerShell service management, pour démarrer ou arrêter manuellement.

Création d'un fichier exécutable à partir de la Source c# incorporé dans un Script Windows PowerShell

PowerShell rend les objets .NET facile à utiliser dans un script. Par défaut, elle a une prise en charge intégrée pour de nombreux types d'objet .NET, suffisantes pour la plupart des cas. Mieux encore, il est extensible et permet l'incorporation de courts extraits de code c# dans un script Windows PowerShell pour ajouter la prise en charge de toute autre fonctionnalité de .NET. Cette fonctionnalité est fournie par la commande Add-Type, qui, en dépit de son nom, peut faire beaucoup plus que d'ajouter simplement la prise en charge de nouveaux types d'objets .NET à Windows PowerShell. Il peut même compiler et lier une application c# complète dans un nouveau fichier exécutable. Par exemple, cette hello.ps1 script Windows PowerShell :

$source = @"
  using System;
  class Hello {
    static void Main() {
      Console.WriteLine("Hello World!");
    }
  }
"@
Add-Type -TypeDefinition $source -Language CSharp -OutputAssembly "hello.exe"
  -OutputType ConsoleApplication

Crée une application hello.exe, qui imprime « Hello world! » :

PS C:\Temp> .\hello.ps1
PS C:\Temp> .\hello.exe
Hello World!
PS C:\Temp>

En résumé

PSService.ps1 fonctionnalités basées sur toutes les que j'ai abordés jusqu'à présent, je peux désormais créer ce service Windows PowerShell que j'ai rêvez, un script PSService.ps1 :

  • Installer et désinstaller (à l'aide de fonctions de gestion de service de Windows PowerShell).
  • Démarrer et arrêter proprement dit (en utilisant le même ensemble de fonctions).
  • Contient un court extrait de code c#, qui crée la PSService.exe SCM attend (à l'aide de la commande Add-Type).
  • Vérifiez le stub PSService.exe rappeler dans le script PSService.ps1 pour l'opération de service (en réponse à OnStart, OnStop et autres événements).
  • Être géré par le panneau de configuration SCM et de tous les outils de ligne de commande (grâce au stub PSService.exe).
  • Être résilient et traiter correctement n'importe quelle commande dans n'importe quel état. (Par exemple, il peut automatiquement arrêter le service avant de le désinstaller, ou ne faites rien lorsque vous êtes invité à démarrer un service déjà démarré.)
  • Prise en charge de Windows 7 et toutes les versions ultérieures de Windows (en utilisant uniquement les fonctionnalités Windows PowerShell v2).

Notez que je vais aborder uniquement les parties critiques du PSService.ps1 conception et implémentation de cet article. L'exemple de script contient également le code de débogage et une prise en charge des fonctionnalités de service facultatif, mais leur description serait compliquer inutilement les explications fournies ici.

Architecture PSService.ps1 le script est organisé en une série de sections :

  • Un commentaire d'en-tête décrivant le fichier.
  • Un bloc de commentaire aide.
  • Le bloc Param définissant les commutateurs de ligne de commande.
  • Variables globales.
  • Routines d'assistance : Maintenant et journal.
  • C# bloc source du stub PSService.exe.
  • La routine principale, chaque commutateur de ligne de commande de traitement.

Paramètres globaux

Immédiatement sous le bloc Param, PSService.ps1 contient des variables globales, les paramètres globaux, qui peuvent être modifiés en fonction des besoins. Les valeurs par défaut sont affichés dans Figure 5.

Figure 5 Global par défaut, Variable

Variable Description Par défaut
$serviceName Un nom d'un mot utilisé pour les commandes net start, etc. Le nom de base du script
$serviceDisplayName Un nom plus descriptif pour le service Un exemple de Service de PowerShell
$installDir Où installer les fichiers du service ${Env:windir})} \System32
$logFile Nom du fichier dans lequel consigner les messages de service ${ENV:windir}\Logs\$serviceName.log
$logName Nom du journal des événements dans lequel enregistrer les événements de service Application

 

En utilisant le nom du fichier de base comme le nom du service (par exemple, PSService pour PSService.ps1) vous permet de créer plusieurs services à partir du même script, simplement en copiant le script, renommer la copie, puis l'installation de la copie.

Arguments de ligne de commande

Pour le rendre facile à utiliser, le script prend en charge les arguments de ligne de commande qui correspondent à toutes les transitions d'état, comme indiqué dans Figure 6.

Figure 6 les Arguments de ligne de commande pour les Transitions d'état

Commutateur Description
-Démarrer Démarrer le service
-Arrêter Arrêter le service
-Le programme d'installation. Installer lui-même en tant que service
-Supprimer Désinstallez le service

 

(Prise en charge de l'état de pause n'est pas implémenté mais serait simple d'ajouter, avec les options de transition d'état correspondant).

Figure 7 montre quelques plusieurs arguments de gestion prenant en charge le script.

Figure 7 prise en charge des Arguments de gestion

Commutateur Description
-Redémarrage Arrêter le service, puis redémarrez-le
-État Afficher l'état actuel du service
-Service Exécution de l'instance de service (à utiliser uniquement par le stub service.exe)
-Version Afficher la version du service
Paramètres courants -? ,-Verbose, - Debug, etc.

 

Chaque commutateur de transition d'état comporte deux modes d'opération :

  • Lorsqu'elle est appelée par l'utilisateur final : Utilisez les fonctions de gestion de service de Windows PowerShell pour déclencher une transition d'état.
  • Lorsqu'elle est appelée par le SCM (et indirectement via le stub service.exe) : Gérer l'instance de service service.ps1 en conséquence.

Les deux cas peuvent être distingués au moment de l'exécution en vérifiant le nom d'utilisateur : Dans le premier cas, il est un utilisateur normal (l'administrateur système) ; dans le deuxième cas, il est l'utilisateur réel du système Windows. L'utilisateur du système peut être identifiée comme suit :

$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$userName = $identity.Name   # Ex: "NT AUTHORITY\SYSTEM" or "Domain\Administrator"
$isSystem = ($userName -eq "NT AUTHORITY\SYSTEM")

Installation

L'objectif de l'installation d'un service consiste à stocker une copie des fichiers du service dans un répertoire local, puis faire la déclaration auprès du GCL, afin qu'il sache quel programme exécuter pour démarrer le service.

Voici la séquence des opérations effectuée par le programme d'installation commutateur - traitement :

  1. Désinstaller une instance précédente, le cas échéant.
  2. Créer le répertoire d'installation si nécessaire. (Cela n'est pas nécessaire pour la valeur par défaut : C:\Windows\System32.)
  3. Copiez le script dans le répertoire d'installation.
  4. Créer un stub service.exe dans ce même répertoire d'installation à partir de l'extrait de code c# dans le script.
  5. Inscrire le service.

Notez que depuis un script Windows PowerShell source (PSService.ps1), je me retrouve avec trois fichiers installés dans C:\Windows\System32 : PSService.ps1, PSService.pdb et PSService.exe. Ces trois fichiers doivent être supprimés pendant la désinstallation. L'installation est implémentée en incluant deux éléments de code dans le script :

  • La définition du commutateur - le programme d'installation dans le bloc Param au début du script :
[Parameter(ParameterSetName='Setup', Mandatory=$true)]
[Switch]$Setup,    # Install the service
  • Un bloc if, comme dans Figure 8, pour le traitement-commutateur d'installation dans la routine principale à la fin du script.

Gestionnaire de Code figure 8 le programme d'installation

if ($Setup) {
  # Install the service
  # Check if it's necessary (if not installed,
  # or if this script is newer than the installed copy).
  [...] # If necessary and already installed, uninstall the old copy.
  # Copy the service script into the installation directory.
  if ($ScriptFullName -ne $scriptCopy) {
    Copy-Item $ScriptFullName $scriptCopy
  }
  # Generate the service .EXE from the C# source embedded in this script.
  try {
    Add-Type -TypeDefinition $source -Language CSharp -OutputAssembly $exeFullName
      -OutputType ConsoleApplication -ReferencedAssemblies "System.ServiceProcess"
  } catch {
    $msg = $_.Exception.Message
    Write-error "Failed to create the $exeFullName service stub. $msg"
    exit 1
  }
  # Register the service
  $pss = New-Service $serviceName $exeFullName -DisplayName $serviceDisplayName
    -StartupType Automatic
  return
}

Démarrage

L'autorité responsable de la gestion des services est le SCM. Chaque opération de démarrage doit passer par le SCM afin qu'il peut effectuer le suivi des États de service. Par conséquent, même si l'utilisateur souhaite lancer manuellement un démarrage en utilisant le script, que le démarrage doit être effectué via une demande au SCM. Dans ce cas, la séquence des opérations est :

  1. L'utilisateur (administrateur) exécute une première instance : PSService.ps1-Démarrer.
  2. Cette première instance indique au SCM pour démarrer le service : Start-Service $serviceName.
  3. Le SCM exécute PSService.exe. La routine principale crée un objet de service, puis appelle sa méthode Run.
  4. Le SCM appelle la méthode OnStart d'objet de service.
  5. La méthode OnStart c# exécute une deuxième instance de script : PSService.ps1-Démarrer.
  6. Cette seconde instance maintenant en cours d'exécution en arrière-plan en tant que l'utilisateur du système, démarre une troisième instance, qui reste en mémoire que le service réel : PSService.ps1-Service. Il est de ce dernier - instance de Service qui effectue la tâche de service, les tâches que vous souhaitez personnaliser.

Au final, il y aura deux tâches en cours d'exécution : PSService.exe et une instance PowerShell.exe PSService.ps1-Service.

Tout cela est implémentée en utilisant trois éléments de code dans le script :

  • La définition du commutateur - Start dans le bloc Param au début du script :
[Parameter(ParameterSetName='Start', Mandatory=$true)]
[Switch]$Start, # Start the service
  • Dans la routine principale, à la fin du script, un bloc if traitement-commutateur de démarrage :
if ($Start) {# Start the service
  if ($isSystem) { # If running as SYSTEM, ie. invoked as a service
    Start-Process PowerShell.exe -ArgumentList (
      "-c & '$scriptFullName' -Service")
  } else { # Invoked manually by the administrator
  Start-Service $serviceName # Ask Service Control Manager to start it
  }
  return
}
  • Dans le langage c# source extrait de code, une routine principale et un gestionnaire pour la méthode OnStart qui exécute PSService.ps1-Démarrer, comme illustré dans Figure 9.

Gestionnaire de Code de début de la figure 9

public static void Main() {
  System.ServiceProcess.ServiceBase.Run(new $serviceName());
}
protected override void OnStart(string [] args) {
  // Start a child process with another copy of this script.
  try {
    Process p = new Process();
    // Redirect the output stream of the child process.
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.FileName = "PowerShell.exe";
    p.StartInfo.Arguments = "-c & '$scriptCopyCname' -Start";
    p.Start();
    // Read the output stream first and then wait. (Supposed to avoid deadlocks.)
    string output = p.StandardOutput.ReadToEnd();
    // Wait for the completion of the script startup code,     // which launches the -Service instance.
    p.WaitForExit();
  } catch (Exception e) {
    // Log the failure.
  }
}

Obtention de l'état du Service

-État Gestionnaire simplement le SCM demande l'état du service et l'envoie dans le canal de sortie :

try {
  $pss = Get-Service $serviceName -ea stop # Will error-out if not installed.
} catch {
  "Not Installed"
  return
}
$pss.Status

Mais pendant la phase de débogage, vous pouvez rencontrer des erreurs de script, dû, par exemple, aux erreurs de syntaxe dans le script et autres. Dans ce cas, l'état SCM peuvent se terminer est incorrect. J'ai réellement exécuté à plusieurs reprises lors de la préparation de cet article. Pour aider à diagnostiquer ce genre de chose, il est prudent de vérifier et de recherche - instances de Service :

$spid = $null
$processes = @(gwmi Win32_Process -filter "Name = 'powershell.exe'" | where {
  $_.CommandLine -match ".*$scriptCopyCname.*-Service"
})
foreach ($process in $processes) { # Normally there is only one.
  $spid = $process.ProcessId
  Write-Verbose "$serviceName Process ID = $spid"
}
if (($pss.Status -eq "Running") -and (!$spid)) {
# This happened during the debugging phase.
  Write-Error "The Service Control Manager thinks $serviceName is started,
    but $serviceName.ps1 -Service is not running."
  exit 1
}

Arrêt et la désinstallation

Les opérations d'arrêt et suppression annuler en gros ce que font le programme d'installation et de démarrage :

  • -Stop (s'il est appelé par l'utilisateur) indique au SCM pour arrêter le service.
  • Si elle est appelée par le système, il supprime simplement le PSService.ps1-instance de Service.
  • -Remove arrête le service, à l'aide de sc.exe delete $serviceName annule l'inscription, puis supprime les fichiers dans le répertoire d'installation.

L'implémentation est également très similaire à celle de l'installation et le démarrage :

  1. La définition de chacun d'eux dans le bloc Param au début du script.
  2. Une instruction if bloquer le commutateur dans la routine principale, à la fin du script de traitement.
  3. Pour l'opération d'arrêt, dans l'extrait de code source c#, un gestionnaire pour la méthode OnStop qui exécute PSService.ps1-arrêter. L'opération d'arrêt fait les choses différemment selon que l'utilisateur est un utilisateur réel ou le système.

Journalisation des événements

Services s'exécutent en arrière-plan, sans interface utilisateur. Cela les rend difficiles à déboguer : Comment pouvez-vous diagnostiquer la cause du problème, lors de par sa conception, rien n'est visible ? La méthode habituelle est de conserver un enregistrement de tous les messages d'erreur et l'horodatage et consigner les événements importants qui a fonctionné, tels que les transitions d'état.

L'exemple de script PSService.ps1 implémente deux méthodes de journalisation distinct et utilise à la fois aux points stratégiques (y compris dans les parties des extraits de code précédents, supprimés ici pour clarifier le fonctionnement de base) :

  • Il écrit des objets d'événements dans le journal des applications, avec le nom du service comme nom de source, comme indiqué dans Figure 10. Ces objets événement sont visibles dans l'Observateur d'événements et peuvent être filtrés et recherchée à l'aide de toutes les fonctionnalités de cet outil. Vous pouvez également obtenir ces entrées avec l'applet de commande Get-Eventlog :

Observateur d'événements avec des événements de PSService
Figure 10 l'Observateur d'événements avec des événements de PSService

Get-Eventlog -LogName Application -Source PSService | select -First 10
  • Il écrit des lignes de message dans un fichier texte dans le répertoire des journaux Windows, ${ENV:windir}\Logs\$serviceName.log, comme indiqué dans Figure 11. Ce fichier journal peut être lu dans le bloc-notes et peut être recherché à l'aide de findstr.exe, ou les ports de Win32 de grep, Queue et ainsi de suite.

Figure 11 exemple de fichier journal

PS C:\Temp> type C:\Windows\Logs\PSService.log
2016-01-02 15:29:47 JFLZB\Larvoire C:\SRC\PowerShell\SRC\PSService.ps1 -Status
2016-01-02 15:30:38 JFLZB\Larvoire C:\SRC\PowerShell\SRC\PSService.ps1 -Setup
2016-01-02 15:30:42 JFLZB\Larvoire PSService.ps1 -Status
2016-01-02 15:31:13 JFLZB\Larvoire PSService.ps1 -Start
2016-01-02 15:31:15 NT AUTHORITY\SYSTEM & 'C:\WINDOWS\System32\PSService.ps1' -Start
2016-01-02 15:31:15 NT AUTHORITY\SYSTEM PSService.ps1 -Start: Starting script 'C:\WINDOWS\System32\PSService.ps1' -Service
2016-01-02 15:31:15 NT AUTHORITY\SYSTEM & 'C:\WINDOWS\System32\PSService.ps1' -Service
2016-01-02 15:31:15 NT AUTHORITY\SYSTEM PSService.ps1 -Service # Beginning background job
2016-01-02 15:31:25 NT AUTHORITY\SYSTEM PSService -Service # Awaken after 10s
2016-01-02 15:31:36 NT AUTHORITY\SYSTEM PSService -Service # Awaken after 10s
2016-01-02 15:31:46 NT AUTHORITY\SYSTEM PSService -Service # Awaken after 10s
2016-01-02 15:31:54 JFLZB\Larvoire PSService.ps1 -Stop
2016-01-02 15:31:55 NT AUTHORITY\SYSTEM & 'C:\WINDOWS\System32\PSService.ps1' -Stop
2016-01-02 15:31:55 NT AUTHORITY\SYSTEM PSService.ps1 -Stop: Stopping script PSService.ps1 -Service
2016-01-02 15:31:55 NT AUTHORITY\SYSTEM Stopping PID 34164
2016-01-02 15:32:01 JFLZB\Larvoire PSService.ps1 -Remove
PS C:\Temp>

Une fonction de journalisation permet de facilement écrire ces messages automatiquement préfixant l'horodatage ISO 8601 et un nom d'utilisateur actuel :

Function Log ([String]$string) {
  if (!(Test-Path $logDir)) {
    mkdir $logDir
  }
  "$(Now) $userName $string" |
    out-file -Encoding ASCII -append "$logDir\$serviceName.log"
}

Exemple de Session de Test

Voici comment les journaux précédents ont été générés :

PS C:\Temp> C:\SRC\PowerShell\SRC\PSService.ps1 -Status
Not Installed
PS C:\Temp> PSService.ps1 -Status
PSService.ps1 : The term 'PSService.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program.
[...]
PS C:\Temp> C:\SRC\PowerShell\SRC\PSService.ps1 -Setup
PS C:\Temp> PSService.ps1 -Status
Stopped
PS C:\Temp> PSService.ps1 -Start
PS C:\Temp>

Cet exemple montre comment utiliser le service en général. N'oubliez pas qu'il doit être exécuté par un utilisateur disposant de droits d'administrateur local, dans une session Windows PowerShell en tant qu'administrateur. Notez comment le script PSService.ps1 n'était pas sur le chemin d'accès dans un premier temps, puis après-opération d'installation, qu'il est. (Le premier - appel sans chemin d'accès spécifié de l'état échoue ; la deuxième - réussit appel de l'état.)

Calling PSService.ps1 -Status at this stage would produce this output: Running. And this, after waiting 30 seconds:
PS C:\Temp> PSService.ps1 -Stop
PS C:\Temp> PSService.ps1 -Remove
PS C:\Temp>

Personnalisation du Service

Pour créer votre propre service, procédez simplement comme suit :

  • Copiez l'exemple de service dans un nouveau fichier avec un nouveau nom de base, telles que C:\Temp\MyService.ps1.
  • Modifier le nom du service de temps dans la section des variables globales.
  • Modifier la ne bloquent-Gestionnaire de Service à la fin du script. Actuellement, le temps ($true) bloc contient uniquement du code factice qui sort de veille chaque 10 secondes et journaux d'un message dans le fichier journal :
######### TO DO: Implement your own service code here. ##########
###### Example that wakes up and logs a line every 10 sec: ######
Start-Sleep 10
Log "$script -Service # Awaken after 10s"
  • Installer et démarrer le test :
C:\Temp\MyService.ps1 -Setup
MyService.ps1 -Start
type C:\Windows\Logs\MyService.log

Vous n'avez pas à modifier quoi que ce soit dans le reste du script, sauf à ajouter de nouvelles fonctionnalités SCM telles que l'état suspendu.

Limitations et problèmes

Le script doit être exécuté dans un environnement en cours d'exécution avec des droits d'administrateur ou vous obtiendrez diverses erreurs d'accès refusé.

L'exemple de script fonctionne dans les versions de Windows XP à 10 et les versions de serveur correspondant. Dans Windows XP, vous devez installer Windows PowerShell v2, qui n'est pas disponible par défaut. Téléchargez et installez Windows Management Framework v2 pour XP (bit.ly/1MpOdpV), qui inclut Windows PowerShell v2. Notez que j'ai fait très peu de tests dans ce système d'exploitation, comme il n'est pas plus possible.

Sur de nombreux systèmes, l'exécution du script Windows PowerShell est désactivée par défaut. Si vous obtenez une erreur comme, « l'exécution de scripts est désactivée sur ce système, » lorsque vous tentez d'exécuter PSService.ps1, puis utilisez :

Set-ExecutionPolicy RemoteSigned

Pour plus d'informations, consultez « Références ».

Évidemment, type de script de service ne peut pas être comme performantes comme programme compilé. Un script de service écrit dans Windows PowerShell est appropriée pour le prototypage un concept et de tâches dont le coût des performances faibles comme système de surveillance, le service de clustering et ainsi de suite. Mais, pour n'importe quelle tâche hautes performances, une réécriture en C++ ou c# est recommandée.

L'encombrement mémoire n'est également pas aussi bonne que celle d'un programme compilé, car il requiert le chargement d'un interpréteur de Windows PowerShell à part entière dans la session du système. Dans le monde, avec des systèmes comportant plusieurs gigaoctets de RAM, cela n'est pas compliqué.

Ce script est totalement indépendant de PsService.exe Mark Russinovich. J'ai choisi le nom PSService.ps1 avant que je connaissais l'homonymy. Je vais conservez-le pour cet exemple de script que je pense que le nom permet d'effacer son objectif. Bien sûr, si vous envisagez de faire des essais avec votre propre service de Windows PowerShell, vous devez le renommer, pour obtenir un nom de service unique à partir d'un nom de base de script unique !

Références


Jean-François Larvoiretravaille pour entreprise Hewlett-Packard de Grenoble, France. Il développe des logiciels pour 30 ans pour BIOS du PC, pilotes de Windows, la gestion du système Windows et Linux. Il peut être contacté à jf.larvoire@hpe.com.

Merci aux experts techniques suivants d'avoir relu cet article : Jeffery Hicks (JDH Solutions informatiques)