3

UserData by default will run with Powershell V5.1 on the Windows Server 2022 AMI on an AWS EC2 instance that spins up. However, I want to use some cmdlets that are only supported in Powershell version 7 and greater.

How am I best able to run a script with Powershell 7+ when booting the instance with UserData?

I currently have a script that installs powershell 7, but then from that point I am not sure how to use v7 to run the rest of the commands that I have.

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

I am using the WINDOWS_SERVER_2022_ENGLISH_FULL_BASE AMI.

I have tried using something like Invoke-Expression, and also have tried to get the script to call itself recursively with some conditionals, e.g.

# 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...
}

Both of my attempts have been silently failing, and with ec2 userdata it is very hard to get info on why.

8
  • how about placing the code you want to run inside a scriptblock ({...}), call it using the invocation operator (&), then do the same with PowerShell 7 by calling the application itself, or entering into pwsh as an interactive console. Commented Jan 18, 2023 at 22:34
  • Would you be able to give a short example of the scriptblock and invocation operator? I don't think that I would be able to enter into pwsh interactively, as it all needs to be done via script, and there won't be any human intervention. Commented Jan 18, 2023 at 22:47
  • Sure. Like this: $scriptblock = {Param($text)Write-Host -Object "$text " -NoNewline;};& $scriptblock 'Hello';pwsh.exe -Command "$scriptblock 'World'" Commented Jan 18, 2023 at 22:52
  • @Michael - is there anything useful in /var/log/cloud-init-output.log? Have you tried putting some print statements etc to see where it is failing by any chance? What exactly is your UserData? Is it even running PowerShell code within<PowerShell>.. </PowerShell> ? Commented Jan 19, 2023 at 0:48
  • 1
    @AdilHindistan Thanks! This idea of downloading the second script from S3 and executing it via the initial UserData turned out to be a bit easier and more ergonomic than putting the code inside a script block (which did work). Commented Jan 20, 2023 at 1:42

1 Answer 1

4

The approach that ended up working was to have 2 different scripts. The first script installs PS7, and then downloads the second script from S3 and executes it using PS7.

User Data exectued with 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 script, executed separately:

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

All that needs to happen to make this work is to make sure that you copy the setup.ps1 script to an S3 location. Which can be achieved in lots of different ways depending on the rest of your setup.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.