Запуск UserData с Powershell >= 7.0 в Windows Server 2022 на EC2

UserData по умолчанию будет работать с Powershell V5.1 в AMI Windows Server 2022 на экземпляре AWS EC2, который раскручивается. Однако я хочу использовать некоторые командлеты, которые поддерживаются только в Powershell версии 7 и выше.

Как мне лучше всего запустить скрипт с Powershell 7+ при загрузке экземпляра с UserData?

В настоящее время у меня есть скрипт, который устанавливает powershell 7, но с этого момента я не уверен, как использовать v7 для запуска остальных команд, которые у меня есть.

Invoke-WebRequest -Uri https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/PowerShell-7.3.1-win-x64.msi -OutFile PowerShell.msi
Start-Process msiexec.exe -ArgumentList '/i PowerShell.msi /quiet' -Wait

Я использую WINDOWS_SERVER_2022_ENGLISH_FULL_BASE AMI.

Я пытался использовать что-то вроде Invoke-Expression, а также пытался заставить скрипт вызывать себя рекурсивно с некоторыми условными выражениями, например.

# First Run with ps 5.1
if ($PSVersionTable.PSVersion -lt [Version]"7.0") {
    Invoke-WebRequest -Uri https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/PowerShell-7.3.1-win-x64.msi -OutFile PowerShell.msi
    Start-Process msiexec.exe -ArgumentList '/i PowerShell.msi /quiet' -Wait
    cd "C:\Program Files\PowerShell\7"
    # Run this same script with ps7
    ./pwsh $PSCommandPath
    exit
}

# 
if ($PSVersionTable.PSVersion -gt [Version]"7.0") {
    # Do the things I need to do with ps7...
}

Обе мои попытки потерпели неудачу, и с пользовательскими данными ec2 очень сложно получить информацию о том, почему.

как насчет того, чтобы поместить код, который вы хотите запустить, в блок сценария ({...}), вызвать его с помощью оператора вызова (&), а затем сделать то же самое с PowerShell 7, вызвав само приложение или войдя в pwsh в качестве интерактивной консоли.

Abraham Zinala 18.01.2023 23:34

Не могли бы вы привести краткий пример блока сценария и оператора вызова? Я не думаю, что смогу войти в pwsh в интерактивном режиме, так как все это нужно делать через скрипт, и никакого вмешательства человека не будет.

Michael 18.01.2023 23:47

Конечно. Вот так: $scriptblock = {Param($text)Write-Host -Object "$text " -NoNewline;};& $scriptblock 'Hello';pwsh.exe -Command "$scriptblock 'World'"

Abraham Zinala 18.01.2023 23:52

@Michael, есть ли что-нибудь полезное в /var/log/cloud-init-output.log? Вы пытались поместить некоторые операторы печати и т. д., Чтобы увидеть, где он случайно не работает? Что такое ваши пользовательские данные? Выполняется ли даже код PowerShell внутри <PowerShell>.. </PowerShell>?

Adil Hindistan 19.01.2023 01:48

@AdilHindistan, это экземпляр Windows, поэтому журналы находятся здесь: C:\ProgramData\Amazon\EC2Launch\log\agent.log Я обнаружил, что когда что-то пошло не так, обычно я даже не могу подключиться к экземпляр через SSM. Я использую CDK и класс UserData, поэтому мой скрипт корректно помещается в теги <powershell>. Я знаю, что мой сценарий UserData попадает туда, потому что я могу найти его в экземпляре, как только у меня будет соединение.

Michael 19.01.2023 05:24

Использовать два скрипта, один для установки powershell, а другой для запуска вашего кода?

Paolo 19.01.2023 10:34

@ Майкл - конечно, ты прав насчет местоположения. Честно говоря, ваш сценарий выглядит хорошо. Возможно, стоит рассмотреть возможность разделения кода PS7 на другой сценарий, как предложил Паоло. Вы можете включить команды для загрузки и запуска скрипта из s3. Вам нужен способ получения журналов, что означает, что вам сначала нужен функционирующий экземпляр, а затем запустить код pwsh. Как только вы выясните проблему, вы можете вернуть его обратно.

Adil Hindistan 19.01.2023 14:24

@AdilHindistan Спасибо! Эта идея загрузить второй скрипт с S3 и выполнить его через начальные данные пользователя оказалась немного проще и удобнее, чем размещение кода внутри блока скрипта (что действительно сработало).

Michael 20.01.2023 02:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Подход, который в конечном итоге сработал, заключался в том, чтобы иметь 2 разных сценария. Первый скрипт устанавливает PS7, а затем загружает второй скрипт с S3 и выполняет его с помощью PS7.

Пользовательские данные, выполненные с PS5:

#init.ps1
<powershell>
Invoke-WebRequest -Uri https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/PowerShell-7.3.1-win-x64.msi -OutFile PowerShell.msi
Start-Process msiexec.exe -ArgumentList '/i PowerShell.msi /quiet' -Wait
cd "C:\Program Files\PowerShell\7"
mkdir (Split-Path -Path 'C:/temp/setupGateway.ps1' ) -ea 0
Read-S3Object -BucketName 'my-bucket' -key 'setupGateway.ps1' -file 'C:/temp/setupGateway.ps1' -ErrorAction Stop
& "C:\Program Files\PowerShell\7\pwsh" "C:\temp\setupGateway.ps1"
</powershell>
<persist>true</persist>

Скрипт PS7, выполняемый отдельно:

# setup.ps1
Write-Output $PSVersionTable
Write-Output "Hello from PS7"

Все, что нужно сделать, чтобы это заработало, — убедиться, что вы скопировали скрипт setup.ps1 в папку S3. Это может быть достигнуто множеством различных способов в зависимости от остальной части вашей установки.

Другие вопросы по теме