使用 PowerShell 实现虚拟机自动化和管理

可以使用 PowerShell Direct 在 Windows 10 或更高版本或 Windows Server 2016 或更高版本的 Hyper-V 主机上运行任意 PowerShell。 无论网络配置或远程管理设置如何,都使用 PowerShell Direct。

下面是运行 PowerShell Direct 的一些方法:

要求

作系统要求:

  • 主机:运行 Hyper-V 的 Windows 10、Windows Server 2016 或更高版本。
  • 来宾/虚拟机:Windows 10、Windows Server 2016 或更高版本。

如果要管理较旧的虚拟机,请使用虚拟机连接(VMConnect)或 为虚拟机配置虚拟网络

配置要求:

  • 虚拟机必须在主机上本地运行。
  • 必须使用至少一个配置的用户配置文件打开并运行虚拟机。
  • 必须以 Hyper-V 管理员身份登录到主计算机。
  • 必须为虚拟机提供有效的用户凭据。

创建和退出交互式 PowerShell 会话

在虚拟机中运行 PowerShell 命令的最简单方法是启动交互式会话。

会话启动时,键入的命令在虚拟机上运行,就像直接在虚拟机本身的 PowerShell 会话中键入它们一样。

启动交互式会话:

  1. 在 Hyper-V 主机上,以管理员身份打开 PowerShell。

  2. 运行以下命令之一,使用虚拟机名称或 GUID 创建交互式会话:

    Enter-PSSession -VMName <VMName>
    Enter-PSSession -VMId <VMId>
    

    出现提示时,提供虚拟机的凭据。

  3. 在虚拟机上运行命令。 应会看到 VMName 作为 PowerShell 提示符的前缀,如下所示:

    [VMName]: PS C:\>
    

    任何命令运行都将在虚拟机上运行。 若要测试,可以运行 ipconfighostname 确保这些命令在虚拟机中运行。

  4. 完成后,运行以下命令以关闭会话:

     Exit-PSSession 
    

注释

如果会话无法连接,请参阅 潜在原因的故障排除

若要了解有关这些 cmdlet 的详细信息,请参阅 Enter-PSSessionExit-PSSession

使用 Invoke-Command 运行脚本或命令

使用 Invoke-Command 的 PowerShell Direct 非常适合需要在虚拟机上运行一个命令或一个脚本的情况,但不需要继续与超出该点的虚拟机交互。

若要运行单个命令,请执行以下命令:

  1. 在 Hyper-V 主机上,以管理员身份打开 PowerShell。

  2. 运行以下命令之一,使用虚拟机名称或 GUID 创建会话:

    Invoke-Command -VMName <VMName> -ScriptBlock { command } 
    Invoke-Command -VMId <VMId> -ScriptBlock { command }
    

    出现提示时,提供虚拟机的凭据。

    该命令将在虚拟机上执行,如果控制台有输出,则会将其打印到控制台。 一旦命令运行,连接就会自动关闭。

运行脚本:

  1. 在 Hyper-V 主机上,以管理员身份打开 PowerShell。

  2. 运行以下命令之一,使用虚拟机名称或 GUID 创建会话:

    Invoke-Command -VMName <VMName> -FilePath C:\host\script_path\script.ps1 
    Invoke-Command -VMId <VMId> -FilePath C:\host\script_path\script.ps1 
    

    出现提示时,提供虚拟机的凭据。

    该脚本将在虚拟机上执行。 一旦命令运行,连接就会自动关闭。

若要了解有关此 cmdlet 的详细信息,请参阅 Invoke-Command

使用 New-PSSession 和 Copy-Item 复制文件

注释

PowerShell Direct 仅支持 Windows 内部版本 14280 及更高版本中的持久会话

编写跨一个或多个远程计算机协调作的脚本时,持久性 PowerShell 会话非常有用。 创建后,持久性会话将存在于后台,直到你决定删除它们。 这意味着可以使用或不Invoke-Command传递凭据来反复Enter-PSSession引用同一会话。

通过同一令牌,会话保持状态。 由于持久会话仍然存在,因此在会话中创建或传递到会话的任何变量都将在多个调用中保留。 有许多工具可用于处理持久会话。 在此示例中,我们将使用 New-PSSessionCopy-Item 将数据从主机移动到虚拟机,并将数据从虚拟机移到主机。

若要创建会话,请复制文件:

  1. 在 Hyper-V 主机上,以管理员身份打开 PowerShell。

  2. 运行以下命令之一,使用 New-PSSession以下命令创建到虚拟机的持久 PowerShell 会话。

    $s = New-PSSession -VMName <VMName> -Credential (Get-Credential)
    $s = New-PSSession -VMId <VMId> -Credential (Get-Credential)
    

    出现提示时,提供虚拟机的凭据。

    警告

    版本在 14500 之前存在 bug。 如果未使用标志显式指定 -Credential 凭据,则来宾中的服务将崩溃,需要重启。 如果遇到此问题,则“ 错误:远程会话可能已结束”部分中提供了解决方法说明。

  3. 将文件复制到虚拟机。

    若要从主机复制到 C:\host_path\data.txt 虚拟机,请运行:

    Copy-Item -ToSession $s -Path C:\host_path\data.txt -Destination C:\guest_path\
    
  4. 将文件从虚拟机(打开)复制到主机上。

    若要从虚拟机复制到 C:\guest_path\data.txt 主机,请运行:

    Copy-Item -FromSession $s -Path C:\guest_path\data.txt -Destination C:\host_path\
    
  5. 使用 Remove-PSSession. 停止持久会话。

    Remove-PSSession $s
    

Troubleshooting

可通过 PowerShell Direct 显示少量的常见错误消息。 以下部分介绍最常见的错误消息、某些原因和诊断问题的工具。

-VMName 或 -VMID 参数不存在

问题:

Enter-PSSessionInvoke-CommandNew-PSSession 没有 -VMName 参数 -VMId

潜在原因:

最有可能的问题是主机作系统不支持 PowerShell Direct。

可以通过运行以下命令来检查 Windows 版本:

[System.Environment]::OSVersion.Version

如果运行的是受支持的生成,则 PowerShell 版本也有可能不运行 PowerShell Direct。 对于 PowerShell Direct 和 JEA,主版本必须为 5 或更高版本。

可以通过运行以下命令来检查 PowerShell 版本生成:

$PSVersionTable.PSVersion

错误:远程会话可能已结束

注释

对于主机内部版本 10240 和 12400 之间的 Enter-PSSession,以下所有错误都报告为“远程会话可能已结束”。

错误信息:

Enter-PSSession:Windows PowerShell 无法处理的错误。 远程会话可能已结束。

潜在原因:

  • 虚拟机存在但未运行。
  • 来宾 OS 不支持 PowerShell Direct。 请参阅 要求
  • 来宾中尚不提供 PowerShell
    • 作系统尚未完成启动
    • 作系统无法正确启动
    • 某些启动时间事件需要用户输入

可以使用 Get-VM cmdlet 检查主机上正在运行的 VM。

错误信息:

New-PSSession:Windows PowerShell 无法处理的错误。 远程会话可能已结束。

潜在原因:

  • 上面列出的原因之一 - 它们都同样适用于 New-PSSession
  • 当前版本中的一个 bug,其中必须显式传递 -Credential凭据。 发生这种情况时,整个服务在来宾作系统中挂起,需要重启。 可以检查会话是否仍可用于 Enter-PSSession。

若要解决凭据问题,请使用 VMConnect 登录到虚拟机,打开 PowerShell,并使用以下 PowerShell 重启 vmicvmsession 服务:

Restart-Service -Name vmicvmsession

错误:无法解析参数集

错误信息:

Enter-PSSession:无法使用指定的命名参数解析参数集。

潜在原因:

  • -RunAsAdministrator 连接到虚拟机时不受支持。

    连接到 Windows 容器时,标志 -RunAsAdministrator 允许管理员在没有显式凭据的情况下进行连接。 由于虚拟机不授予主机隐含管理员访问权限,需要显式输入凭据。

可以使用参数将管理员凭据传递给虚拟机 -Credential ,或者在出现提示时手动输入凭据。

错误:凭据无效

错误信息:

Enter-PSSession:凭据无效。

潜在原因:

  • 无法验证来宾凭据
    • 提供的凭据不正确。
    • 来宾中没有用户帐户(以前未启动 OS)
    • 如果以管理员身份进行连接:管理员尚未设置为活动用户。 在 “启用和禁用内置管理员帐户”中了解详细信息。

错误:输入 VMName 参数无法解析为任何虚拟机。

错误信息:

Enter-PSSession:输入 VMName 参数不解析为任何虚拟机。

潜在原因:

  • 你不是 Hyper-V 管理员。
  • 虚拟机不存在。

可以使用 Get-VM cmdlet 检查所使用的凭据是否具有 Hyper-V 管理员角色,并查看主机上本地运行的 VM 并启动。

示例和用户指南

PowerShell Direct 支持 Just Enough Administration (JEA)。

查看 GitHub 上的示例。