확장에 PowerShell 사용
Windows Admin Center 확장 SDK에 대해 자세히 알아보겠습니다. 확장에 PowerShell 명령을 추가하는 방법에 대해 살펴볼 것입니다.
TypeScript의 PowerShell
gulp 빌드 프로세스에는 \src\resources\scripts
폴더에 배치된 {!ScriptName}.ps1
항목을 가져와서 \src\generated
폴더 아래의 powershell-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 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}');
키리스: 세션에 대한 키가 자동으로 만들어집니다. 이 세션은 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
작업 항목 옵션
함수 | 설명 |
---|---|
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 | 배열의 모든 노드에 대하여 단일 명령 실행 |
run | 쌍을 이루는 노드에서 해당 명령 실행 |
취소 | 배열의 모든 노드에서 명령 취소 |