Partager via


Utilisation de PowerShell dans votre extension

Examinons plus en détail le kit SDK Windows Admin Center. Nous allons évoquer l’ajout de commandes PowerShell à votre extension.

PowerShell dans TypeScript

Le processus de génération gulp comporte une étape de génération qui accepte les {!ScriptName}.ps1 placés dans le dossier \src\resources\scripts, et les génère dans la classe powershell-scripts sous le dossier \src\generated.

Notes

Ne mettez pas à jour manuellement les fichiers powershell-scripts.ts ni les fichiers strings.ts. Tout changement que vous apportez est remplacé à la prochaine génération.

Exécution d’un script PowerShell

Tous les scripts à exécuter sur un nœud peuvent être placés dans \src\resources\scripts\{!ScriptName}.ps1.

Important

Les changements apportés à un fichier {!ScriptName}.ps1 ne sont pas répercutés dans votre projet tant que gulp generate n’a pas été exécuté.

L’API fonctionne en créant d’abord une session PowerShell sur les nœuds que vous ciblez, en créant le script PowerShell avec tous les paramètres à passer, puis en exécutant le script sur les sessions créées.

Par exemple, nous avons ce script \src\resources\scripts\Get-NodeName.ps1 :

Param
 (
    [String] $stringFormat
 )
 $nodeName = [string]::Format($stringFormat,$env:COMPUTERNAME)
 Write-Output $nodeName

Nous allons créer une session PowerShell pour notre nœud cible :

const session = this.appContextService.powerShell.createSession('{!TargetNode}');

Nous allons ensuite créer le script PowerShell avec un paramètre d’entrée :

const command = PowerShell.createCommand(PowerShellScripts.Get_NodeName, {stringFormat: 'The name of the node is {0}!'});

Pour finir, nous devons exécuter ce script dans la session que nous avons créée :

  public ngOnInit(): void {
    this.session = this.appContextService.powerShell.createAutomaticSession('{!TargetNode}');
  }

  public getNodeName(): Observable<any> {
    const command = PowerShell.createCommand(PowerShellScripts.Get_NodeName, { stringFormat: 'The name of the node is {0}!'});
    return this.appContextService.powerShell.run(this.session, command)
    .pipe(
        map(
        response => {
            if (response && response.results) {
                return response.results;
            }
            return 'no response';
        }
      )
    );
  }

  public ngOnDestroy(): void {
    this.session.dispose()
  }

Nous devons à présent nous abonner à la fonction observable que nous venons de créer. Placez ce qui suit à l’emplacement où vous devez appeler la fonction pour exécuter le script PowerShell :

this.getNodeName().subscribe(
     response => {
	console.log(response)
     }
);

En fournissant le nom du nœud à la méthode createSession, une nouvelle session PowerShell est créée, utilisée, puis immédiatement détruite à l’issue de l’appel PowerShell.

Options des clés

Quelques options sont disponibles au moment de l’appel de l’API PowerShell. Chaque fois qu’une session est créée, elle peut l’être avec ou sans clé.

Key : une session avec clé est créée. Elle peut être recherchée et réutilisée, même entre les composants (ce qui signifie que Composant 1 peut créer une session avec la clé « SME-ROCKS », et que Composant 2 peut utiliser cette même session). Si une clé est fournie, la session créée doit être supprimée via l’appel de dispose(), comme cela a été effectué dans l’exemple ci-dessus. Une session ne doit pas être conservée plus de 5 minutes sans être supprimée.

  const session = this.appContextService.powerShell.createSession('{!TargetNode}', '{!Key}');

Keyless : Une clé est automatiquement créée pour la session. Cette session est supprimée automatiquement au bout de 3 minutes. L’utilisation de keyless permet à votre extension de recycler l’utilisation de n’importe quelle instance d’exécution déjà disponible au moment de la création d’une session. Si aucune instance d’exécution n’est disponible, une autre instance est créée. Cette fonctionnalité convient bien pour les appels ponctuels, mais son utilisation répétée peut affecter les performances. La création d’une session dure environ 1 seconde. Le recyclage continu des sessions peut donc entraîner des ralentissements.

  const session = this.appContextService.powerShell.createSession('{!TargetNodeName}');

ou

const session = this.appContextService.powerShell.createAutomaticSession('{!TargetNodeName}');

Dans la plupart des situations, créez une session à clé dans la méthode ngOnInit(), puis supprimez-la dans ngOnDestroy(). Suivez ce modèle quand il existe plusieurs scripts PowerShell dans un composant, mais que la session sous-jacente N’EST PAS partagée entre les composants. Pour de meilleurs résultats, vérifiez que la création de session est gérée à l’intérieur des composants plutôt que des services. Cela permet de garantir la gestion appropriée de la durée de vie et du nettoyage.

Pour de meilleurs résultats, vérifiez que la création de session est gérée à l’intérieur des composants plutôt que des services. Cela permet de garantir la gestion appropriée de la durée de vie et du nettoyage.

Flux PowerShell

Si vous avez un script durable et si les données sont générées progressivement, un flux PowerShell vous permet de traiter les données sans avoir à attendre la fin du script. Le next() observable est appelé dès la réception des données.

this.appContextService.powerShellStream.run(session, script);

Scripts durables

Si vous disposez d’un script durable à exécuter en arrière-plan, vous pouvez envoyer un élément de travail. L’état du script fait l’objet d’un suivi par la passerelle, et des mises à jour de l’état peuvent être envoyées à une notification.

const workItem: WorkItemSubmitRequest = {
	typeId: 'Long Running Script',
	objectName: 'My long running service',
	powerShellScript: script,

	//in progress notifications
	inProgressTitle: 'Executing long running request',
	startedMessage: 'The long running request has been started',
	progressMessage: 'Working on long running script – {{ percent }} %',

	//success notification
	successTitle: 'Successfully executed a long running script!',
	successMessage: '{{objectName}} was successful',
	successLinkText: 'Bing',
	successLink: 'http://www.bing.com',
	successLinkType: NotificationLinkType.Absolute,

	//error notification
	errorTitle: 'Failed to execute long running script',
	errorMessage: 'Error: {{ message }}'

	nodeRequestOptions: {
	   logAudit: true,
	   logTelemetry: true
	}
};

return this.appContextService.workItem.submit('{!TargetNode}', workItem);

Notes

Pour que la progression soit affichée, Write-Progress doit être inclus dans le script que vous avez écrit. Par exemple :

 Write-Progress -Activity ‘The script is almost done!' -percentComplete 95

Options de WorkItem

function Explication
submit() Envoie l’élément de travail
submitAndWait() Envoyer l’élément de travail, et attendre la fin de son exécution
wait() Attendre la fin de l’exécution de l’élément de travail existant
query() Interroger un élément de travail existant en fonction de son ID
find() Rechercher un élément de travail existant en fonction de TargetNodeName, ModuleName ou typeId.

API de traitement par lots PowerShell

Si vous devez exécuter le même script sur plusieurs nœuds, vous pouvez utiliser une session PowerShell de traitement par lots. Par exemple :

const batchSession = this.appContextService.powerShell.createBatchSession(
	['{!TargetNode1}', '{!TargetNode2}', sessionKey);
  this.appContextService.powerShell.runBatchSingleCommand(batchSession, command).subscribe((responses: PowerShellBatchResponseItem[]) => {
	for (const response of responses) {
	  if (response.error || response.errors) {
	    //handle error
	  } else {
	    const results = response.properties && response.properties.results;
	    //response.nodeName
	    //results[0]
	  }
	}
     },
     Error => { /* handle error */ });

Options de PowerShellBatch

Option Explication
runSingleCommand Exécuter une seule commande sur tous les nœuds du tableau
Exécuter Exécuter la commande correspondante sur le nœud appairé
annuler Annuler la commande sur tous les nœuds du tableau