다음을 통해 공유


확장에 PowerShell 사용

적용 대상: Windows 관리 Center, Windows 관리 Center 미리 보기

Windows 관리 Center 확장 SDK에 대해 자세히 알아보겠습니다. 확장에 PowerShell 명령을 추가하는 방법에 대해 살펴보겠습니다.

TypeScript의 PowerShell

gulp 빌드 프로세스에는 폴더에 \src\resources\scripts 배치된 모든 {!ScriptName}.ps1 항목을 가져와서 폴더 아래의 클래스에 powershell-scripts 빌드하는 생성 단계가 \src\generated 있습니다.

참고 항목

파일이나 strings.ts 파일을 수동으로 업데이트 powershell-scripts.ts 하지 마세요. 변경한 내용은 다음 생성에서 덮어씁니다.

PowerShell 스크립트 실행

노드에서 실행하려는 모든 스크립트를 에 배치 \src\resources\scripts\{!ScriptName}.ps1할 수 있습니다.

Important

파일에서 {!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 command = PowerShell.createCommand(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 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()
  }

이제 방금 만든 관찰 가능한 함수를 구독해야 합니다. PowerShell 스크립트를 실행하기 위해 함수를 호출해야 하는 위치에 배치합니다.

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

createSession 메서드에 노드 이름을 제공하면 PowerShell 호출이 완료되면 새 PowerShell 세션이 생성, 사용 및 즉시 제거됩니다.

키 옵션

PowerShell API를 호출할 때 몇 가지 옵션을 사용할 수 있습니다. 세션이 만들어질 때마다 키와 함께 만들거나 키 없이 만들 수 있습니다.

키: 구성 요소 간에 조회하고 다시 사용할 수 있는 키 세션을 만듭니다(즉, 구성 요소 1은 키 "SME-ROCKS"를 사용하여 세션을 만들 수 있고 구성 요소 2는 동일한 세션을 사용할 수 있습니다). 키가 제공되면 위의 예제에서 수행한 것처럼 dispose()를 호출하여 만든 세션을 삭제해야 합니다. 세션을 5분 이상 삭제하지 않고 유지하면 안 됩니다.

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

Keyless: 세션에 대한 키가 자동으로 만들어집니다. 이 세션은 3분 후에 자동으로 삭제됩니다. 키리스를 사용하면 확장을 통해 세션을 만들 때 이미 사용할 수 있는 모든 Runspace의 사용을 재활용할 수 있습니다. 사용할 수 있는 Runspace가 없으면 새 Runspace가 만들어집니다. 이 기능은 일회성 호출에 적합하지만 반복되는 사용은 성능에 영향을 줄 수 있습니다. 세션을 만드는 데 약 1초가 걸리므로 세션을 지속적으로 재활용하면 속도가 느려질 수 있습니다.

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

또는

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

대부분의 경우 메서드에서 ngOnInit() 키 세션을 만든 다음 , 에서 삭제합니다 ngOnDestroy(). 구성 요소에 PowerShell 스크립트가 여러 개 있지만 기본 세션이 구성 요소 간에 공유되지 않는 경우 이 패턴을 따릅니다. 최상의 결과를 위해 세션 생성이 서비스가 아닌 구성 요소 내에서 관리되는지 확인합니다. 이렇게 하면 수명 및 클린 기능을 제대로 관리할 수 있습니다.

최상의 결과를 위해 세션 생성이 서비스가 아닌 구성 요소 내에서 관리되는지 확인합니다. 이렇게 하면 수명 및 클린 기능을 제대로 관리할 수 있습니다.

PowerShell 스트림

장기 실행 스크립트가 있고 데이터가 점진적으로 출력되는 경우 PowerShell 스트림을 사용하면 스크립트가 완료될 때까지 기다리지 않고도 데이터를 처리할 수 있습니다. 관찰 가능한 next()는 데이터를 받는 즉시 호출됩니다.

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

WorkItem 옵션

function 설명
submit() 작업 항목을 제출합니다.
submitAndWait() 작업 항목을 제출하고 실행이 완료될 때까지 기다립니다.
wait() 기존 작업 항목이 완료되기를 기다립니다.
query() ID별 기존 작업 항목 쿼리
find() TargetNodeName, ModuleName 또는 typeId를 사용하여 기존 작업 항목을 찾습니다.

PowerShell Batch API

여러 노드에서 동일한 스크립트를 실행해야 하는 경우 일괄 처리 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 옵션

옵션 설명
runSingleCommand 배열의 모든 노드에 대해 단일 명령 실행
실행 쌍을 이루는 노드에서 해당 명령 실행
cancel 배열의 모든 노드에서 명령 취소