英文:
Script Headless Install .NET 7 SDK on Windows Server 2022 via PowerShell
问题
是否可以在全新安装的 Windows Server 2022 实例上通过 PowerShell 或批处理脚本无头安装 .NET 7 SDK?
我的目标是启动一个新实例,然后能够安装并执行全局工具,例如这个 PowerShell 命令:
> dotnet tool install -g nbgv
> nbgv --version
3.5.13
然而,如果我使用 dotnet 安装 PowerShell 脚本,我会收到“dotnet”命令未找到的错误:
dotnet : The term 'dotnet' is not recognized as the name of a cmdlet, function, script file, or operable program.
到目前为止,我正在使用 AWS EC2 创建一个新的 Microsoft Windows Server 2022 基础镜像:
private async<string> Task StartWindowsServer(Amazon.EC2.IAmazonEC2 ec2Client)
{
var response = await _ec2Client.RunInstancesAsync(new RunInstanceRequest{
InstanceType = InstanceType.C4Large,
ImageId = "ami-0bde1eb2c18cb2abe", //windows2022BaseUSEast1
KeyName = ...,
IamInstanceProfile ...
});
return response.Reservation.Instances.First();
}
然后,一旦实例被创建,我使用系统管理器运行 PowerShell 脚本进行安装:
private async Task InstallDotNetAndThirdPartyTool(
Amazon.SimpleSystemsManagement.IAmazonSimpleSystemsManagement ssmClient,
string instanceId)
{
var installDotNet7 =
// https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script?WT.mc_id=dotnet-35129-website#examples
@"&powershell -NoProfile -ExecutionPolicy unrestricted -Command ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Channel 7.0""" +
Environment.NewLine +
"Restart-Computer";
await ExecuteRemotePowerShell(ssmClient, instanceId, installDotNet7);
var installNerdBank = "dotnet tool install -g nbgv";
await ExecuteRemotePowerShell(ssmClient, instanceId, installNerdBank);
// 脚本报错 - 找不到“dotnet”
}
private async Task ExecuteRemotePowerShell(
Amazon.SimpleSystemsManagement.IAmazonSimpleSystemsManagement _ssmClient,
string instanceId,
string powershellScript)
{
await _ssmClient.SendCommandAsync(
new SendCommandRequest
{
DocumentName = commandName,
Targets = new ()
{
new Target
{
Key = "InstanceIds",
Values = new List<string>{ instanceId }
}
},
Parameters = new Dictionary<string, List<string>>
{
{
"commands",
new List<string> { powershellScript }
}
}
});
}
错误:
dotnet : The term 'dotnet' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\ProgramData\Amazon\SSM\InstanceData\i-07f13f9a7dacaf6b0\document\orchestration\c8de6390-d27f-4e78-ad88-cf62e85b07
0d\downloads\ExampleScript-638208821382795610.ps1:18 char:1
+ dotnet tool install `
我尝试过的其他事情
- 我在 .NET 7 安装脚本中添加了“Restart-Computer”,以为这样会刷新,但没有解决问题。
- 怀疑是路径问题,所以尝试在 .NET 7 安装脚本中手动设置路径,也没有成功:
$env:PATH=";C:\Users\Administrator\AppData\Local\Microsoft\dotnet"
[Environment]::SetEnvironmentVariable("Path", $env:Path,[System.EnvironmentVariableTarget]::Machine)
英文:
Is it possible to headlessly install the .NET 7 SDK on a fresh instance of Windows Server 2022 via powershell or batch script?
My goal is to spin up a new Instance and then be able to install and execute a global tool, ie this powershell:
> dotnet tool install -g nbgv
> nbgv --version
3.5.13
However, if I use the dotnet install powershell scripts, I get command not found errors on dotnet
:
dotnet : The term 'dotnet' is not recognized as the name of a cmdlet, function, script file, or operable program.
So far, I'm using AWS EC2 to create a new Microsoft Windows Server 2022 Base image:
private async<string> Task StartWindowsServer(Amazon.EC2.IAmazonEC2 ec2Client)
{
var response = await _ec2Client.RunInstancesAsync(new RunInstanceRequest{
InstanceType = InstanceType.C4Large,
ImageId = "ami-0bde1eb2c18cb2abe", //windows2022BaseUSEast1
KeyName = ...,
IamInstanceProfile ...
});
return response.Reservation.Instances.First();
}
Then, once the instance is provisioned, I am using System Manager to run a powershell script to do the install:
private async Task InstallDotNetAndThirdPartyTool(
Amazon.SimpleSystemsManagement.IAmazonSimpleSystemsManagement ssmClient,
string instanceId)
{
var installDotNet7 =
// https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script?WT.mc_id=dotnet-35129-website#examples
@"&powershell -NoProfile -ExecutionPolicy unrestricted -Command ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Channel 7.0""" +
Environment.NewLine +
"Restart-Computer";
await ExecuteRemotePowerShell(ssmClient, instanceId, installDotNet7);
var installNerdBank = "dotnet tool install -g nbgv";
await ExecuteRemotePowerShell(ssmClient, instanceId, installNerdBank);
// scritp errors out - can't find `dotnet`
}
private async Task ExecuteRemotePowerShell(
Amazon.SimpleSystemsManagement.IAmazonSimpleSystemsManagement _ssmClient,
string instanceId,
string powershellScript)
{
await _ssmClient.SendCommandAsync(
new SendCommandRequest
{
DocumentName = commandName,
Targets = new ()
{
new Target
{
Key = "InstanceIds",
Values = new List<string>{ instanceId }
}
},
Parameters = new Dictionary<string, List<string>>
{
{
"commands",
new List<string> { powershellScript }
}
}
});
}
ERROR:
dotnet : The term 'dotnet' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\ProgramData\Amazon\SSM\InstanceData\i-07f13f9a7dacaf6b0\document\orchestration\c8de6390-d27f-4e78-ad88-cf62e85b07
0d\downloads\ExampleScript-638208821382795610.ps1:18 char:1
+ dotnet tool install `
Additional things I tried
- I added the
Restart-Computer
into the .NET 7 install script thinking that would refresh things, but didn't solve it. - Figured there was a path issue, so I tried to manually set the path in the .NET 7 installd script, also did NOT work.:
$env:PATH=";C:\Users\Administrator\AppData\Local\Microsoft\dotnet"
[Environment]::SetEnvironmentVariable("Path", $env:Path,[System.EnvironmentVariableTarget]::Machine)
答案1
得分: 2
以下是翻译好的内容:
"Turns out I was missing two pieces:
- I need to manually set PATH as the .NET Install Script does not set environment variables (https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script#set-environment-variables)
- I need to refresh the Path environment variable.
Here is the final PowerShell Script I ended up using (note the explicit -InstallDir
):
&powershell -NoProfile -ExecutionPolicy unrestricted -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((iwr -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Channel STS -InstallDir c:\dotnet"
[Environment]::SetEnvironmentVariable("DOTNET_ROOT","$HOME\.dotnet", "User")
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\dotnet\;$HOME\.dotnet;$HOME\.dotnet\Tools", "User")
[Environment]::SetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT","1", "Machine")
[Environment]::SetEnvironmentVariable("DOTNET_NOLOGO", "true", "Machine")
[Environment]::SetEnvironmentVariable("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "true", "Machine")
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
dotnet --version
And special thanks to https://stackoverflow.com/questions/17794507/reload-the-path-in-powershell for the answer on how to reload Path."
英文:
Turns out I was missing two pieces:
- I need to manually set PATH as the .NET Install Script does not set environment variables (https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script#set-environment-variables)
- I need to refresh the Path environment variable.
Here is the final PowerShell Script I ended up using (note the explicit -InstallDir
):
&powershell -NoProfile -ExecutionPolicy unrestricted -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((iwr -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Channel STS -InstallDir c:\dotnet"
[Environment]::SetEnvironmentVariable("DOTNET_ROOT","$HOME\.dotnet", "User")
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\dotnet\;$HOME\.dotnet;$HOME\.dotnet\Tools", "User")
[Environment]::SetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT","1", "Machine")
[Environment]::SetEnvironmentVariable("DOTNET_NOLOGO", "true", "Machine")
[Environment]::SetEnvironmentVariable("DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "true", "Machine")
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
dotnet --version
And special thanks to https://stackoverflow.com/questions/17794507/reload-the-path-in-powershell for the answer on how to reload Path.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论