適用於:Windows Admin Center、Windows Admin Center 預覽版

讓我們更深入探索 Windows Admin Center Extensions SDK-讓我們來談談如何將 PowerShell 命令新增至您的擴充功能。

TypeScript 中的 PowerShell

Gulp 組建程式的產生步驟會採用放置在資料夾中的任何 {!ScriptName}.ps1 步驟,並將其建立到資料夾下 \src\generated powershell-scripts 類別。 \src\resources\scripts

請勿手動更新 powershell-scripts.ts strings.ts 檔案。 您所做的任何變更都會在下一次產生時覆寫。

執行 PowerShell 腳本

任何您想要在節點上執行的腳本都可以放入 \src\resources\scripts\{!ScriptName}.ps1

在檔案中 {!ScriptName}.ps1 進行的任何變更都不會反映在您的專案中,直到執行為止 gulp generate

API 的運作方式是先在您的目標節點上建立 PowerShell 會話、使用需要傳入的任何參數建立 PowerShell 腳本,然後在建立的會話上執行腳本。

例如,我們有這個腳本 \src\resources\scripts\Get-NodeName.ps1

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

我們會為目標節點建立 PowerShell 會話:

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

接著,我們將使用輸入參數來建立 PowerShell 腳本:

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

最後,我們需要在我們所建立的會話中執行該腳本:

  public ngOnInit(): void {
    this.session = this.appContextService.powerShell.createAutomaticSession('{!TargetNode}');
  public getNodeName(): Observable<any> {
    const script = PowerShell.createScript(PowerShellScripts.Get_NodeName.script, { stringFormat: 'The name of the node is {0}!'});
    return this.appContextService.powerShell.run(this.session, script)
    .pipe(
        response => {
            if (response && response.results) {
                return response.results;
            return 'no response';
  public ngOnDestroy(): void {
    this.session.dispose()

現在,我們必須訂閱剛才建立的可觀察函數。 將此設為您需要呼叫函式以執行 PowerShell 腳本的位置:

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

藉由提供節點名稱給 createSession 方法,即會建立並使用新的 PowerShell 會話,然後在 PowerShell 呼叫完成時立即終結。

呼叫 PowerShell API 時,有幾個選項可供使用。 每次建立會話時,都可以使用或不使用金鑰來建立。

關鍵: 這會建立一個可查閱和重複使用的金鑰會話,甚至是跨元件 (表示 Component1 可以建立金鑰為 "SME ROCKS" 的會話,而 Component2 可以使用該相同的會話) 。如果提供了金鑰,則必須藉由呼叫 dispose () (如同上述範例中所做的)處置所建立的會話。 不應將會話保留,而不會被處置超過5分鐘。

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

無索引鍵: 系統會自動為會話建立金鑰。 此會話會在3分鐘後自動處置。 使用無索引鍵可讓您的延伸模組回收在建立會話時已可使用的任何執行時間。 如果沒有可用的運行空間,將會建立新的運行時。 這項功能適用于一次性呼叫,但重複使用會影響效能。 會話大約需要1秒的時間來建立,因此持續回收會話可能會導致速度變慢。

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

在大多數情況下,在方法中 ngOnInit() 建立索引會話,然後在中 ngOnDestroy() 處置它。 當元件中有多個 PowerShell 腳本,但基礎會話並非跨元件共用時,請遵循此模式。 為了獲得最佳結果,請確定已在元件中管理會話,而不是在服務中進行管理,這有助於確保存留期和清除可以正確地進行管理。

為了獲得最佳結果,請確定已在元件中管理會話,而不是在服務中進行管理,這有助於確保存留期和清除可以正確地進行管理。

PowerShell 資料流程

如果您有長時間執行的腳本,而且資料會逐漸輸出,PowerShell 資料流程將可讓您處理資料,而不需要等候腳本完成。 一旦收到資料,就會立即呼叫可觀察的下一個 () 。

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

長時間執行的腳本

如果您有想要在背景中執行的長時間執行腳本,可以提交工作專案。 閘道將會追蹤腳本的狀態,並可將狀態的更新傳送至通知。

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);

若要顯示進度,Write-Progress 必須包含在您撰寫的腳本中。 例如:

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

工作專案選項

PowerShell Batch Api

如果您需要在多個節點上執行相同的腳本,則可以使用 batch PowerShell 會話。 例如:

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 */ });

PowerShellBatch 選項