无法将命令正确传递给 Powershell 中的远程计算机

Unable to pass command properly to remote computers in Powershell

我有一个 Powershell 脚本,当它被复制到本地远程服务器并使用 PSExec 远程执行时,它 运行s 正确地完成了我需要它做的事情。我试图改编相同的脚本,使其能够远程 运行,而不依赖于使用 PSExec 远程复制和执行的脚本。它是让 Citrix XenApp 服务器加入其场的命令。

# Establish Variables
$ZoneName = "MyZone"
$OdbcUserName = "MyCitrixUserAcct"
$OdbcPassword = "MyPassword"
$LicenseServerName = "mylicenseserver.company.com"
$XAConfigConsoleExe = "C:\Progra~2\Citrix\XenApp\ServerConfig\XenAppConfigConsole.exe"
$Servers = Get-Content -path .\serverlist.txt
ForEach ($Server in $Servers)
{
# Creating mf20.dsn File
if ((Test-Path \$Server\c$\temp\mf20.dsn) -eq $true)
{
remove-item \$Server\c$\temp\mf20.dsn
}
add-Content \$Server\c$\temp\mf20.dsn "[ODBC]"
add-content \$Server\c$\temp\mf20.dsn "DRIVER=SQL Server"
add-content \$Server\c$\temp\mf20.dsn "DATABASE=MyDB"
add-content \$Server\c$\temp\mf20.dsn "APP=Citrix IMA"
add-content \$Server\c$\temp\mf20.dsn "UID="
add-content \$Server\c$\temp\mf20.dsn "SERVER=dbserver.company.com,1433" 
add-content \$Server\c$\temp\mf20.dsn "Trusted_Connection=No"

# Setting setup arguments

[Array]$XAArguments = @()

$XAArguments += "/ExecutionMode:Join"
$XAArguments += "/ZoneName:$ZoneName"
$XAArguments += "/ImaWorkerMode:True"
$XAArguments += "/DsnFile:c:\temp\mf20.dsn"
$XAArguments += "/AuthenticationType:Sql"
$XAArguments += "/OdbcUserName:$OdbcUserName"
$XAArguments += "/OdbcPassword:$OdbcPassword"
$XAArguments += "/LicenseServerName:$LicenseServerName"
$XAArguments += "/LicenseServerPort:27000"
$XAArguments += "/LicenseModel:XA"
$XAArguments += "/CustomXMLServicePort:8080"

# running setup with arguments

Invoke-Command -ComputerName $Server {$XAConfigConsoleExe + $XAArguments}
}

我已经尝试了很多通过搜索找到的东西的不同排列和组合(即使用-scriptblock,使用pssessions)。我知道我的命令行很好,因为如果我获取 write-host $XAConfigConsoleExe $XAArguments 的输出并将其传递给它工作的服务器的 Powershell 控制台。

我确定我遗漏了一些明显的东西。原剧本不是我写的。我无法为论点的构建方式辩护,所以如果有更好(更可靠的方法)那么我在这里所做的事情我愿意接受任何想法。

这是我可以使用 PSExec 远程执行的原始脚本的样子:

# Establish Variables
$ZoneName = "MyZone"
$OdbcUserName = "MyCitrixUserAcct"
$OdbcPassword = "MyPassword"
$LicenseServerName = "mylicenseserver.company.com"
$XAConfigConsoleExe = "C:\Program Files (x86)\Citrix\XenApp\ServerConfig\XenAppConfigConsole.exe"

# Creating mf20.dsn File
if ((Test-Path C:\temp\mf20.dsn) -eq $true)
{
remove-item C:\temp\mf20.dsn
}
add-Content C:\temp\mf20.dsn "[ODBC]"
add-content C:\temp\mf20.dsn "DRIVER=SQL Server"
add-content C:\temp\mf20.dsn "DATABASE=MyDB"
add-content C:\temp\mf20.dsn "APP=Citrix IMA"
add-content C:\temp\mf20.dsn "UID="
add-content C:\temp\mf20.dsn "SERVER=mydbserver.company.com,1433" 
add-content C:\temp\mf20.dsn "Trusted_Connection=No"

# Setting setup arguments
[Array]$XAArguments = @()

$XAArguments += "/ExecutionMode:Join"
$XAArguments += "/ZoneName:$ZoneName"
$XAArguments += "/ImaWorkerMode:True"
$XAArguments += "/DsnFile:C:\Temp\mf20.dsn"
$XAArguments += "/AuthenticationType:Sql"
$XAArguments += "/OdbcUserName:$OdbcUserName"
$XAArguments += "/OdbcPassword:$OdbcPassword"
$XAArguments += "/LicenseServerName:$LicenseServerName"
$XAArguments += "/LicenseServerPort:27000"
$XAArguments += "/LicenseModel:XA"
$XAArguments += "/CustomXMLServicePort:8080"

# running setup with arguments

& $XAConfigConsoleExe $XAArguments

I've edited this answer to reflect the final version of the script I went with. I didn't change any logic or methods. I merely cleaned up some things and added more variables to make the script more flexible for editing in the future.

嗯,这不是最漂亮的解决方案,但它是我能找到的唯一可靠的解决方案,它是完全独立的(在服务器列表的输入 .txt 文件之外)。任何地方都不会复制 from/to,一切都是动态创建的。任何有冒险精神的人都可以随意查看并提出 better/cleaner 实现我目标的方法。

# Establish Variables
$ZoneName = Read-Host 'Zone Name?'
$OdbcUserName = "Citrixuser"
$OdbcPassword = Read-Host 'Password for Citrixuser?'
$LicenseServerName = "MyLicenseServer.company.com"
$DataBase= "DBName"
$DBServer= "MyDBServer.company.com"
$EdgeSightServer = "MyEdgeSightServer.company.com"

$XAConfigConsoleExe = "C:\Program Files (x86)\Citrix\XenApp\ServerConfig\XenAppConfigConsole.exe"
$Servers = Get-Content -path .\serverlist.txt

# Setting setup arguments

[Array]$XAArguments = @()

$XAArguments += "/ExecutionMode:Join"
$XAArguments += "/ZoneName:$ZoneName"
$XAArguments += "/ImaWorkerMode:True"
$XAArguments += "/DsnFile:C:\temp\mf20.dsn"
$XAArguments += "/AuthenticationType:Sql"
$XAArguments += "/OdbcUserName:$OdbcUserName"
$XAArguments += "/OdbcPassword:$OdbcPassword"
$XAArguments += "/LicenseServerName:$LicenseServerName"
$XAArguments += "/LicenseServerPort:27000"
$XAArguments += "/LicenseModel:XA"
$XAArguments += "/CustomXMLServicePort:8080"
$XAArguments += "/EdgeSightCompanyName:CompanyName"
$XAArguments += "/EdgeSightServerName:$EdgeSightServer"
$XAArguments += "/EdgeSightServerPort:80"

# Running against server list

ForEach ($Server in $Servers)
{
# Creating joinfarm.bat file on the remote server
if ((Test-Path \$Server\c$\temp\joinfarm.bat) -eq $true) {Remove-Item \$Server\c$\temp\joinfarm.bat}
Add-Content \$Server\c$\temp\joinfarm.bat "$([char]34)$XAConfigConsoleExe$([char]34) $XAArguments"
Add-Content \$Server\c$\temp\joinfarm.bat "shutdown.exe /r /f /t 10"
Add-Content \$Server\c$\temp\joinfarm.bat "del c:\temp\mf20.dsn /q"
Add-Content \$Server\c$\temp\joinfarm.bat "del c:\temp\joinfarm.bat /q"

# Creating mf20.dsn file on the remote server
if ((Test-Path \$Server\c$\temp\mf20.dsn) -eq $true) {remove-item \$Server\c$\temp\mf20.dsn}
add-Content \$Server\c$\temp\mf20.dsn "[ODBC]"
add-content \$Server\c$\temp\mf20.dsn "DRIVER=SQL Server"
add-content \$Server\c$\temp\mf20.dsn "DATABASE=$DataBase"
add-content \$Server\c$\temp\mf20.dsn "APP=Citrix IMA"
add-content \$Server\c$\temp\mf20.dsn "UID="
add-content \$Server\c$\temp\mf20.dsn "SERVER=$DBServer,1433" 
add-content \$Server\c$\temp\mf20.dsn "Trusted_Connection=No"

# running setup with arguments
Invoke-Command -ComputerName $Server -ScriptBlock {c:\temp\joinfarm.bat} -AsJob
}

我正在做的是写一个批处理文件(我尝试写一个 PS1 文件,但当我 运行 PS1 -AsJob 即使如果我不使用 -AsJob) 到远程服务器并使用 -AsJob 开关执行批处理以便我可以加入多个服务器,它似乎可以工作同时。如果没有 -AsJob,每个服务器都必须在处理下一个服务器之前完成。批次清理自身、dsn 文件并重新启动服务器。