当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 如何使用 PowerShell 调用命令

作者:精品下载站 日期:2024-12-14 03:44:33 浏览:14 分类:玩电脑

如何使用 PowerShell 调用命令


您想在远程计算机或服务器上运行 PowerShell 命令吗?然后您不需要打开远程桌面连接,因为您只需使用 PowerShell Invoke-Command 即可。

Invoke-Command 允许您在一台或多台远程计算机上运行 PowerShell 命令和脚本。同时将结果重定向到您自己的控制台。这使其成为快速管理远程设备的绝佳 cmdlet。

在本文中,我们将了解使用 Invoke-Command 的要求以及如何使用 cmdlet。

先决条件调用命令

在远程服务器或计算机上使用 Invoke-Command 之前,我们需要确保 Windows 远程管理服务正在运行。此外,如果您的网络中启用了 Windows 防火墙,那么我们需要检查防火墙是否没有阻止连接。

要检查远程计算机是否接受远程管理,我们可以使用简单的 PowerShell 命令 Test-WSMan

Test-WSMan -Computername la-srv-dc01

[玩转系统] 如何使用 PowerShell 调用命令

如果出现无法连接到目标的错误,则 Windows 远程管理服务未运行。要启用它,我们可以在远程计算机上使用 PowerShell cmdlet Enable-PSRemoting

Enable-PSRemoting

该命令的优点是它不仅启动远程管理服务,还将其设置为自动启动并在防火墙中创建所需的例外规则。

但更好的选择是创建一个新的组策略对象 (GPO)。这样您就可以轻松地在多台计算机或服务器上启用远程管理服务。

您可以在计算机配置 > Windows 设置 > 安全设置 > 系统服务中找到策略设置。

防火墙规则

Windows 防火墙将阻止所有传入连接,包括 Windows 远程管理连接。因此,在使用 Invoke-Command 之前,我们需要允许入站连接。

我们也可以使用相同的 GPO 来创建入站规则。

  1. 导航到计算机配置 > Windows 设置 > 安全设置 > 具有高级安全性的 Windows Defender 防火墙
  2. 右键单击入站规则,然后选择新建规则
  3. 选择预定义并选择Windows远程管理
  4. 选择配置文件域、私有的规则
  5. 选择允许连接并点击完成

[玩转系统] 如何使用 PowerShell 调用命令

确保使用 GPUpdate 命令在服务器/客户端上更新新策略。

使用调用命令

PowerShell 中的 Invoke-Command 允许您在远程计算机上运行命令或脚本。当您需要在远程计算机上运行多个命令时,最好使用 New-PSSession cmdlet。

Invoke-Command 的结构非常简单,但仍然有很多我们可以使用的选项(参数):

ComputerName

要运行命令的计算机名或 IP 地址。对于多台计算机,用逗号分隔名称 ,

Credential

连接到远程计算机的凭据

FilePath

指定要在远程计算机上运行的本地脚本的路径

AsJob

在本地计算机上将远程命令作为后台作业运行

InDisconnectedSession

用于在远程计算机上的断开连接的会话中运行命令

ScriptBlock

要运行的脚本或命令

ArgumentList

用于将参数传递给脚本块中的 cmdlet

因此,要在远程计算机上简单地运行 PowerShell 命令,我们只需指定远程计算机的名称以及我们要在脚本块内运行的命令。例如,要从域控制器检索计算机信息,我们可以执行以下操作:

Invoke-Command -ComputerName la-srv-dc01 {Get-ComputerInfo}

[玩转系统] 如何使用 PowerShell 调用命令

这将在域控制器 (la-srv-dc01) 上运行命令 Get-ComputerInfo 并将结果返回到控制台。

运行脚本

在上面的示例中,我们仅运行一个简单的 PowerShell cmdlet。但我们也可以在远程计算机上运行完整的脚本。您可以只在 scriptblock 参数内编写脚本,但将脚本存储在变量或使用文件中更容易。

下面的例子工作得很好,但是这样读起来有点困难:

Invoke-Command -ComputerName la-srv-dc01 -ScriptBlock {Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID, MediaType, @{Name="FreeSpace (GB)"; Expression={"{0:N2}" -f ($_.FreeSpace / 1GB)}}}

更好的选择是首先将脚本存储在变量中。然后我们可以简单地将变量传递给脚本块:

$script = {
    Get-CimInstance Win32_LogicalDisk | 
        Select-Object DeviceID, MediaType, @{Name="FreeSpace (GB)"; Expression={"{0:N2}" -f ($_.FreeSpace / 1GB)}}
}

Invoke-Command -ComputerName la-srv-dc01 -ScriptBlock $script

第三个选项是将脚本存储在本地计算机上,并使用 -FilePath 参数引用该脚本:

Invoke-Command -ComputerName la-srv-dc01 -FilePath c:\test\diskInfo.ps1

在多台计算机上运行

PowerShell 中 Invoke-Command cmdlet 的一大优势是您还可以同时在多台计算机上运行它。有几个选项可以做到这一点,我们可以简单地指定用逗号分隔的计算机名称:

Invoke-Command -ComputerName la-srv-dc01, la-srv-app01, la-srv-file01 -FilePath c:\test\diskInfo.ps1

编写此代码的另一种选择是使用哈希表和展开。当您需要添加大量属性时,展开参数将使您的脚本更易于阅读。

$parameters = @{
    ComputerName      = 'la-srv-dc01', 'la-srv-app01', 'la-srv-file01', 'la-win11-lab03'
    ScriptBlock       = { Get-ComputerInfo }
  }
Invoke-Command @parameters

当您需要在多台计算机(假设有一百台或更多)上运行命令时,您希望最大程度地减少本地计算机上的负载。为此,我们可以使用 InDisconnectedSession 参数。

如果正常运行 Invoke-Command cmdlet,则本地计算机将连接到远程计算机,启动脚本,等待结果,然后断开连接。等待部分会消耗本地计算机的大部分时间和资源,尤其是在连接到 100 台或更多计算机时。

使用 InDisconnectedSession 参数,cmdlet 将仅连接到远程计算机,启动脚本,然后断开连接。这大大减少了整个过程的时间。

$parameters = @{
    ComputerName          = (Get-Content -Path C:\Test\Servers.txt)
    InDisconnectedSession = $true
    FilePath              = '\a-d\scripts\InstallWinUpdates.ps1'
}
Invoke-Command @parameters

使用凭证

您需要拥有远程计算机的权限才能运行 PowerShell 命令。在服务器上运行该命令时,您可能没有本地工作站的正确权限。

为了解决这个问题,我们可以使用 -Credentials 参数。您可以在此处输入要用于运行命令的用户帐户。当您使用 -Credential 参数执行 Invoke-Command cmdlet 时,PowerShell 将提示您输入密码:

Invoke-Command -ComputerName la-srv-dc01 -Credential a-d\administrator -Scriptblock {Get-ComputerInfo}

就像大多数 PowerShell cmdlet 一样,您也可以将凭据对象传递给 -Credential cmdlet。当您想要运行多个命令或需要在不同的远程计算机上运行不同的命令时,此方法特别方便:

$cred = Get-Credential

Invoke-Command -ComputerName la-srv-dc01 -Credential $cred -Scriptblock {Get-ComputerInfo}

包括局部变量

在脚本块内使用变量与您的预期略有不同。让我们看下面的简化示例,我们想要获取远程计算机上给定路径的所有文件。在本例中,我们将路径存储在变量中:

$path = "c:\test"
Invoke-Command -ComputerName la-srv-dc01 -Scriptblock {Get-Childitem -Path $path}

上面的例子是行不通的。远程计算机(在本例中为 la-srv-dc01)不知道变量 $path 是什么,因此不会返回任何结果。

要将变量路径传递到脚本块中,我们必须使用 Using 范围修饰符。使用范围指示该变量是在本地会话中创建的,而不是在远程会话中创建的。因此,要将 $path 变量传递到远程会话,我们需要执行以下操作:

$path = "c:\test"
Invoke-Command -ComputerName la-srv-dc01 -Scriptblock {Get-Chiditem -Path $Using:path}

总结

PowerShell Invoke-Command 是管理远程计算机的绝佳工具。它允许您快速执行命令,而无需打开远程桌面。特别是当您需要同时在多台计算机上运行该命令时。

确保您还查看了 New-PSSession cmdlet,当您需要在远程计算机上执行多个命令时,这确实是一个更好的选择。

我希望这篇文章对您有所帮助,如果您有任何疑问,请在下面发表评论。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯