【问题标题】:Run interactive 'master' PowerShell script on local PC as well as remote PCs and log在本地 PC 和远程 PC 上运行交互式“主”PowerShell 脚本并记录
【发布时间】:2016-02-16 18:04:18
【问题描述】:

我编写了一个大型(983 行)交互式 PowerShell 脚本,用于管理本地服务器的几乎所有方面。我有一个包含服务器列表的文本文件。我想疯了。

文本文件内容:

Server1Name
Server2Name

PowerShell 交互式菜单:

Write-Host "Welcome to the environment control script."
Write-Host " "
Write-Host "What would you like to do? Select the number:"
Write-Host "========================================================================="
Write-Host "1. Create a backup of the environment (existing servers)"
Write-Host "2. Backup environment and deploy updated environment (existing servers)"
Write-Host "3. Deploy new environment including IIS (clean servers)"
Write-Host "4. Deploy just IIS (clean servers)"
Write-Host "5. Remove Build w/ backup and cleanup IIS (existing servers)"
Write-Host "6. Remove Build w/out backup and cleanup IIS (existing servers)"
Write-Host "7. Remove and cleanup only IIS (existing servers)"
Write-Host "8. Deploy new DLL's (existing servers)"
Write-Host "9. [EXIT]" -foregroundcolor "yellow"
Write-Host " "

目的:

试图避免在我的服务器上有 1000 个批处理文件

示例:

我在“主”服务器上运行脚本,文本文件中还有 10 个其他服务器。起初,该脚本仅在主服务器上运行。一旦我选择了选项 6,就会运行一个命令在所有 11 台服务器(主服务器 + 10 台其他服务器)上执行相同的命令。

如果使用invoke-commandenter-pssession 等内容进行简单的文件复制或服务重置(无需用户交互),我知道如何跨服务器运行相同的脚本......但是,在我的情况下,我必须远程访问每台服务器,因为它是交互式的……除非有办法做到这一点?

此外,如果可能,启用日志记录,以便我可以确认每台 PC 都运行了脚本并成功完成了所有操作。现在,我让它开始一个成绩单并在最后停止。在本地效果很好。

任何帮助将不胜感激。

更新:2016 年 3 月 8 日

所以,@Cobster 帮助了我,我们已经完成了 99%。

使用下面的代码,看起来脚本正在尝试运行,但是还有一个问题。

$sessions = New-PSSession -ComputerName $servers 
$job = Invoke-Command -Session $sessions -ScriptBlock ${function:Backup} -AsJob

If you want a different job for each machine, you can do the following:

$jobs = $sessions | ForEach-Object { Invoke-Command -Session $_ -ScriptBlock ${function:Backup} -AsJob } 
Wait-Job -Job $jobs

问题是,完成此操作后,invoke-command 似乎不会在我的脚本顶部导入我之前声明的所有变量(其中几乎包括我的所有路径等,因为它们没有定义在那个函数中。

这会导致一堆这些类型的错误(准确地说是 7 个,一个用于执行步骤之前的每个测试路径检查):

Cannot bind argument to parameter 'Path' because it is null.
    + CategoryInfo          : InvalidData: (:) [Test-Path], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.TestPathCommand
    + PSComputerName        : *ServerName*

解决方案:

invoke-command 中使用-ArgumentList $variable1, $variable2

param ( $variable1, $variable2 ) 函数内的方法...由 Cobster 提供。

【问题讨论】:

  • 主帖已更新,在成员的帮助下大部分内容都已解决,但似乎遇到了最后一个障碍。

标签: powershell server interactive administration


【解决方案1】:

Invoke-Command 可以使用 -AsJob 开关在后台运行。

还可以通过使用 Receive-Job cmdlet 在完成后获取每个后台作业的输出来进行日志记录。

【讨论】:

  • 谢谢@Cobster。我终于开始尝试这个(暂时放在另一个项目上)。当我运行以下命令时,它似乎实际上并没有做任何事情。例如,它不会出错,但实际上并没有运行备份功能。调用命令 -ComputerName $Servers -ScriptBlock ${function:Backup} -AsJob
  • 在这些作业上调用Receive-Job 时是否有任何输出或错误?
  • 我从我的主脚本@Cobster 中运行了以下内容...我选择了选项 1(创建备份)。 $s = New-PSSession -ComputerName $Servers 后跟 $j = Invoke-Command -Session $s -ScriptBlock {Start-Job -ScriptBlock ${function:Backup}} 后跟 $j,然后是 $results = Invoke-Command -Session $s -ScriptBlock {param($j) Recieve-Job -Job $j} -ArgumentList $j。我收到一条错误消息:Cannot bind argument to parameter 'ScriptBlock' because it is null. 这出现了两次,后面跟着消息指出 'Recieve-Job' 不是有效的 cmdlet b> 每个服务器(现在总共 2 个)
  • 啊,问题出在${function:Backup} 脚本块上。您需要将此作为变量传递给Invoke-Command 脚​​本块。 Invoke-Command -Session $s -ScriptBlock { param ($s) Start-Job -ScriptBlock $s } -ArgumentList ${function:Backup}
  • 嗯......这很有意义@Cobster。我对其进行了更改,并收到了两条消息(对于每个服务器)说 cannot bind parameter 'ScriptBlock'. Cannot convert the value **prints out my whole function here** of type 'System.String' to type "System.Management.Automation.ScriptBlock'... 还有两个之前的接收作业错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 2019-04-05
相关资源
最近更新 更多