所以我正在尝试使用Enter-PSSession
针对远程计算机运行powershell脚本。我可以连接并运行单个脚本文件,其内容没问题。但是当我运行时:
.\RemoteFile.ps1 "dev-web01" "builder" "test" "2.5.0.0" "Web" ".\stage_properties.xml"
如您所见,此脚本有5个参数。 帕拉姆(
[Parameter(Mandatory=$true)]
$Computername,
[Parameter(Mandatory=$true)]
$Username,
[Parameter(Mandatory=$true)]
$Password,
[Parameter(Mandatory=$true)]
$Version,
[Parameter(Mandatory=$true)]
$Packagenames,
[Parameter(Mandatory=$true)]
$Propfile
)
$securePassword = ConvertTo-SecureString -AsPlainText -Force $Password
$cred = New-Object System.Management.Automation.PSCredential $Username, $securePassword
Enter-PSSession -ComputerName $Computername -Credential $cred
Invoke-Command -ComputerName $Computername -Credential $cred -FilePath
.\DeploymentRun.ps1 -ArgumentList $Propfile -EnableNetworkAccess
当它使用Invoke-Command
参数(stage_properties.xml)运行$Propfile
时,它正在远程计算机上查找,因为我假设位置上下文已更改,而不是相同RemoteFile.ps1和DeploymentRun.ps1所在的本地目录。这是我收到的错误:
Cannot find path 'C:\User\builder\Documents\stage_properties.xml' because it does not exist.
我如何解决这个问题?我做了一些搜索,但似乎无法找到解决方案。
非常感谢任何建议。
答案 0 :(得分:2)
正如你所描述的那样;您传递的文件 name 是相对于本地计算机的路径,因此远程计算机上运行的代码无法在该路径中找到该文件。
没有办法获得"周围"因为您只是在远程计算机上运行代码。结果被序列化并发送回调用客户端。
您最好的选择可能是将文件内容作为参数而不是文件本身发送。当然,必须修改目标脚本来处理它。
您还可以将路径作为UNC路径传递到本地计算机上的共享,甚至是管理共享,例如\\localmachine\c$\users\builder\documents\stage_properties.xml
。但是,您可能会遇到身份验证问题(双跳)。
为什么使用Enter-PSSession
然后使用Invoke-Command
?
首先,如果要在远程计算机的单个会话中进行多次调用,请首先创建一个PSSession:
$session = New-PSSession -ComputerName $ComputerName
然后在所有后续调用中使用该会话:
Invoke-Command -Session $session -File $filename
Invoke-Command -Session $session -ScriptBlock {
# Some code
}
然后在您完成后关闭会话:
Remove-PSSession -Session $session
请注意,Enter-PSSession
仅供交互式使用。您通常不会在脚本中使用它。但它也需要-Session
参数才能使用之前创建的会话。
关于调用多个文件的问题,这里有几个泡菜。首先,让我们记住,当您使用Invoke-Command
参数调用-File
时,它就像您自己阅读文件的内容一样,制作了一个脚本块它,并将其传递给脚本块。
所有这些命令都在远程端进程的上下文中执行。因此,如果这些脚本引用任何资源,包括其他脚本,模块等,则必须从远程执行的上下文访问这些资源。
基于此,您理论上可以将所有这些文件放在共享上,双方都可以访问,并使用UNC路径。
实际上,您遇到了另一个问题:The so-called "double hop" authentication problem会阻止远程计算机委派您的凭据。这意味着,一旦您对远程计算机进行了身份验证,您就无法将凭据传递给第三台计算机(例如托管UNC共享的文件服务器)。
在大多数关于此的文章中(包括我所链接的文章),他们将谈论"启用"通过使用CredSSP进行多跳。在没有完全理解CredSSP的情况下启用CredSSP非常容易。在我看来,它一般不是一个好的解决方案;在大多数情况下,你想重新思考你是如何做事的。
如果您的脚本文件不需要调用或引用其他脚本文件,那么您可以轻松地执行多个Invoke-Command
调用,按顺序执行每个调用。
您提出了解决问题的可能方法:首先将所有文件复制到目标计算机。您只需确保脚本中使用的路径可以正常工作(如果您将其作为参数传递,则不会出现问题!)。
您可以做的另一件事是:不要远程执行代码!只需在本地运行。
但我认为这是不可能的,否则你不会尝试远程操作,所以你可以做的是在远程机器上创建一个预定的任务(或一系列任务)(它们可以在 - 仅需要任务)。
然后,您可以将远程呼叫减少为:
Invoke-Command -Session $session -ScriptBlock {
# PowerShell 3.0+
Start-ScheduledTask -TaskName 'My Special Task'
# Any version of PS
schtasks.exe /RUN /TN "My Special Task"
}