Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Давайте рассмотрим более подробные сведения о пакете SDK расширений Windows Admin Center. Давайте поговорим о добавлении команд PowerShell в расширение.
PowerShell в TypeScript
Процесс сборки gulp имеет шаг создания, который будет принимать любые {!ScriptName}.ps1 элементы, помещенные в \src\resources\scripts папку, и встраивать их в powershell-scripts класс под папкой \src\generated .
Note
Не обновляйте powershell-scripts.tsstrings.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.
Ключевые параметры
При вызове API PowerShell доступны несколько вариантов. Каждый раз при создании сеанса его можно создать с помощью ключа или без него.
Ключ: Это создает сеанс с ключом, который можно найти и повторно использовать, даже в разных компонентах (то есть компонент 1 может создать сеанс с ключом SME-ROCKS, а компонент 2 может использовать этот же сеанс). Если указан ключ, созданный сеанс должен быть удален путем вызова dispose(), как было сделано в приведенном выше примере. Сеанс не должен храниться без удаления более 5 минут.
const session = this.appContextService.powerShell.createSession('{!TargetNode}', '{!Key}');
Бесключевой доступ: Ключ будет автоматически создан для сеанса. Этот сеанс будет удален автоматически через 3 минуты. Использование без ключа позволяет расширению повторно использовать любое пространство выполнения, которое уже доступно во время создания сеанса. Если пространство выполнения недоступно, будет создан новый. Эта функция хороша для одноуровневых вызовов, но многократное использование может повлиять на производительность. Сеанс занимает около 1 секунды для создания, поэтому непрерывное перезапуск сеанса может привести к замедлению.
const session = this.appContextService.powerShell.createSession('{!TargetNodeName}');
or
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);
Note
Для отображения хода выполнения записи необходимо включить в написанный сценарий. Рассмотрим пример.
Write-Progress -Activity ‘The script is almost done!' -percentComplete 95
Параметры WorkItem
| function | Explanation |
|---|---|
| submit() | Отправка рабочего элемента |
| submitAndWait() | Отправка рабочего элемента и ожидание завершения его выполнения |
| wait() | Дождитесь завершения существующего рабочего элемента |
| query() | Запрос существующего рабочего элемента по идентификатору |
| find() | Найдите и существующий рабочий элемент с помощью TargetNodeName, ModuleName или typeId. |
API пакетной службы PowerShell
Если необходимо запустить один и тот же сценарий на нескольких узлах, можно использовать сеанс 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
| option | Explanation |
|---|---|
| runSingleCommand | Выполните одну команду для всех узлов в массиве. |
| run | Выполните соответствующую команду на парном узле |
| cancel | Отмена команды на всех узлах в массиве |