本文介绍连接到以及使用 JEA 终结点的各种方式。
以交互方式使用 JEA
如果要测试 JEA 配置或为用户提供简单的任务,则可以使用 JEA,就像常规 PowerShell 远程处理会话一样。 对于复杂的远程处理任务,建议使用 隐式远程处理。 隐式远程处理允许用户在本地操作数据对象。
若要以交互方式使用 JEA,需要提供以下信息:
- 要连接到的计算机的名称(可以是本地计算机)
- 在该计算机上注册的 JEA 端点的名称
- 有权访问该计算机上的 JEA 终结点的凭据
鉴于该信息,可以使用 New-PSSession 或 Enter-PSSession cmdlet 启动 JEA 会话。
$sessionParams = @{
ComputerName = 'localhost'
ConfigurationName = 'JEAMaintenance'
Credential = Get-Credential
}
Enter-PSSession @sessionParams
如果当前用户帐户有权访问 JEA 终结点,则可以省略 Credential 参数。
当 PowerShell 提示符变为 [localhost]: PS>
时,你就知道你正在与远程 JEA 会话交互。 可以运行 Get-Command
来检查哪些命令可用。 请咨询管理员,了解是否对可用参数或允许的参数值有任何限制。
请记住,JEA 会话以 NoLanguage
模式运行。 通常使用 PowerShell 的某些方法可能不可用。 例如,不能使用变量来存储数据或检查从 cmdlet 返回的对象的属性。 以下示例演示了两种方法,用于获取相同命令以在 NoLanguage
模式下工作。
# Using variables is prohibited in NoLanguage mode. The following will not work:
# $vm = Get-VM -Name 'SQL01'
# Start-VM -VM $vm
# You can use pipes to pass data through to commands that accept input from the pipeline
Get-VM -Name 'SQL01' | Start-VM
# You can also wrap subcommands in parentheses and enter them inline as arguments
Start-VM -VM (Get-VM -Name 'SQL01')
# You can also use parameter sets that don't require extra data to be passed in
Start-VM -VMName 'SQL01'
对于那些因命令调用过于复杂而使此方法变得困难的情况,建议考虑使用 隐式远程处理 或 创建自定义函数 来封装所需的功能。
有关NoLanguageMode
的更多信息,请参阅about_Language_Modes。
将 JEA 与隐式远程处理结合使用
PowerShell 具有隐式远程处理模型,可用于从远程计算机导入代理 cmdlet 并与其交互,就像它们是本地命令一样。 隐式远程处理在 Hey, Scripting Guy!博客文章中有解释。 隐式远程处理在使用 JEA 时非常有用,因为它允许你在完整语言模式下使用 JEA cmdlet。 可以使用制表符补全、变量、操作对象,甚至使用本地脚本针对 JEA 终结点自动化处理任务。 每当调用代理命令时,数据将发送到远程计算机上的 JEA 终结点并在那里执行。
隐式远程处理的工作原理是从现有的 PowerShell 会话导入 cmdlet。 您可以选择为每个代理 cmdlet 的名词添加一个您选择的字符串作为前缀。 前缀允许区分远程系统的命令。 在本地 PowerShell 会话期间创建并导入包含所有代理命令的临时脚本模块。
# Create a new PSSession to your JEA endpoint
$jeaSession = New-PSSession -ComputerName 'SERVER01' -ConfigurationName 'JEAMaintenance'
# Import the entire PSSession and prefix each imported cmdlet with "JEA"
Import-PSSession -Session $jeaSession -Prefix 'JEA'
# Invoke "Get-Command" on the remote JEA endpoint using the proxy cmdlet
Get-JEACommand
重要
某些系统可能无法导入整个 JEA 会话,因为默认 JEA cmdlet 中存在约束。 若要解决此问题,请通过在 -CommandName
参数中显式指定命令名称,从 JEA 会话中仅导入所需的命令。 将来的更新将解决在受影响的系统上导入整个 JEA 会话的问题。
如果由于默认参数的 JEA 约束而无法导入 JEA 会话,请按照以下步骤从导入集筛选出默认命令。 可以继续使用类似 Select-Object
命令,但只需使用计算机上安装的本地版本,而不是从远程 JEA 会话导入的本地版本。
# Create a new PSSession to your JEA endpoint
$jeaSession = New-PSSession -ComputerName 'SERVER01' -ConfigurationName 'JEAMaintenance'
# Get a list of all the commands on the JEA endpoint
$commands = Invoke-Command -Session $jeaSession -ScriptBlock { Get-Command }
# Filter out the default cmdlets
$jeaDefaultCmdlets = @(
'Clear-Host'
'Exit-PSSession'
'Get-Command'
'Get-FormatData'
'Get-Help'
'Measure-Object'
'Out-Default'
'Select-Object'
)
$filteredCommands = $commands.Name | Where-Object { $jeaDefaultCmdlets -notcontains $_ }
# Import only commands explicitly added in role capabilities and prefix each
# imported cmdlet with "JEA"
Import-PSSession -Session $jeaSession -Prefix 'JEA' -CommandName $filteredCommands
还可以使用 Export-PSSession 将隐式远程处理中的代理 cmdlet 持久化。 有关隐式远程处理的详细信息,请参阅 Import-PSSession 和 Import-Module 的文档。
以编程方式使用 JEA
JEA 还可用于自动化系统和用户应用程序中,例如内部技术支持应用程序和网站。 此方法与生成与不受约束的 PowerShell 终结点通信的应用的方法相同。 确保该程序设计能够应对 JEA 施加的限制。
对于简单的一次性任务,可以使用 Invoke-Command 在 JEA 会话中运行命令。
Invoke-Command -ComputerName 'SERVER01' -ConfigurationName 'JEAMaintenance' -ScriptBlock {
Get-Process
Get-Service
}
若要检查连接到 JEA 会话时可以使用哪些命令,请运行 Get-Command
并循环访问结果以检查允许的参数。
$commandParameters = @{
ComputerName = 'SERVER01'
ConfigurationName = 'JEAMaintenance'
ScriptBlock = { Get-Command }
}
Invoke-Command @commandParameters |
Where-Object { $_.CommandType -in @('Function', 'Cmdlet') } |
Format-Table Name, Parameters
如果要生成 C# 应用,可以通过在 WSManConnectionInfo 对象中指定配置名称来创建连接到 JEA 会话的 PowerShell 运行空间。
// using System.Management.Automation;
var computerName = "SERVER01";
var configName = "JEAMaintenance";
// See https://learn.microsoft.com/dotnet/api/system.management.automation.pscredential
var creds = // create a PSCredential object here
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(
false, // Use SSL
computerName, // Computer name
5985, // WSMan Port
"/wsman", // WSMan Path
// Connection URI with config name
string.Format(
CultureInfo.InvariantCulture,
"http://schemas.microsoft.com/powershell/{0}",
configName
),
creds // Credentials
);
// Now, use the connection info to create a runspace where you can run the commands
using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
// Open the runspace
runspace.Open();
using (PowerShell ps = PowerShell.Create())
{
// Set the PowerShell object to use the JEA runspace
ps.Runspace = runspace;
// Now you can add and invoke commands
ps.AddCommand("Get-Command");
foreach (var result in ps.Invoke())
{
Console.WriteLine(result);
}
}
// Close the runspace
runspace.Close();
}
将 JEA 与 PowerShell Direct 配合使用
Windows 10 和 Windows Server 2016 中的 Hyper-V 提供了 PowerShell Direct,此功能允许 Hyper-V 管理员使用 PowerShell 管理虚拟机,而不管虚拟机上的网络配置或远程管理设置如何。
可以将 PowerShell Direct 与 JEA 配合使用,以便向 Hyper-V 管理员授予对 VM 的有限访问权限。 如果失去与 VM 的网络连接,并且需要数据中心管理员来修复网络设置,这非常有用。
无需其他配置即可通过 PowerShell Direct 使用 JEA。 但是,在虚拟机中运行的来宾作系统必须是 Windows 10、Windows Server 2016 或更高版本。 Hyper-V 管理员可以在 PSRemoting cmdlets 上使用 -VMName
或 -VMId
参数连接到 JEA 终结点:
$sharedParams = @{
ConfigurationName = 'NICMaintenance'
Credential = Get-Credential -UserName 'localhost\JEAformyHoster'
}
# Entering a JEA session using PowerShell Direct when the VM name is unique
Enter-PSSession -VMName 'SQL01' @sharedParams
# Entering a JEA session using PowerShell Direct using VM ids
$vm = Get-VM -VMName 'MyVM' | Select-Object -First 1
Enter-PSSession -VMId $vm.VMId @sharedParams
建议创建具有 Hyper-V 管理员使用系统所需的最低权限的专用用户帐户。 请记住,即使是非特权用户也可以默认登录到 Windows 计算机,包括使用不受约束的 PowerShell。 这样,他们就可以浏览文件系统并了解有关 OS 环境的详细信息。 若要锁定 Hyper-V 管理员并限制他们仅使用 PowerShell Direct 和 JEA 访问 VM,必须拒绝 Hyper-V 管理员的 JEA 帐户的本地登录权限。