无法访问 Powershell 远程会话中的 UNC 路径

Posted

技术标签:

【中文标题】无法访问 Powershell 远程会话中的 UNC 路径【英文标题】:Unable to access UNC Paths in Powershell remote session 【发布时间】:2013-07-22 16:31:58 【问题描述】:

我无法在本地计算机的 Powershell 远程会话中访问服务器上的 UNC 路径。我可以直接在 Servers Cmd 提示符下使用它们。

实际上,我已经登录到服务器并将 UNC 路径映射为本地驱动器(比如 X:)。使用登录时重新连接选项。

我有一个位于此 X: 驱动器中的批处理文件,我想使用本地脚本中的调用命令远程运行它。但是,它失败了。

它说“找不到驱动器。名称为 X 的驱动器不存在”。

此外,当我尝试在脚本块中使用 net use 命令映射驱动器时,它也会引发错误 - 系统错误 1223 - 本机命令错误。

我使用管理员凭据登录此服务器。

谁能帮我解决这个问题,我要做的就是远程运行驻留在这个 UNC 路径上的脚本?

另外,当我将服务器中的 UNC 路径映射为本地驱动器时,为什么我无法在 PS 远程会话中使用它?

提前致谢。 TS

【问题讨论】:

您是否尝试过在文件路径中的“x”之后放置$,例如:"\\ServerName\X$\Folder\PowershellFile.ps1" 我试过了,但是没有用。 【参考方案1】:

这里确实发生了 3 种不同的事情。

1 & 3. 只有在您以交互方式登录时才会映射驱动器。因此,当您远程访问另一台计算机,映射驱动器,然后注销/断开连接时,该映射驱动器已断开连接。除了在交互式 GUI 用户会话中,您不能依赖不是您自己创建的映射驱动器号。在脚本或任何远程会话中,只需对所有内容使用 UNC 路径 - 它更可靠。

2 。当您尝试在远程 PS 会话中映射驱动器时,您会遇到所谓的“双跳”问题。有一个解决方案,但是您必须做一些额外的设置。见Double hop access to copy files without CredSSP

【讨论】:

您提供的信息非常有用。我刚刚想出了另一种方法 - 只需将凭据传递到您在 Scriot 块中使用的 UNC 路径,作为 net use 命令的一部分 - 请参阅 Net Use 命令的语法。这解决了我的问题。一开始我使用 Get-Credential cmd-let 从用户那里获取 AD 凭据,它适用于所有服务器。将用户名和密码传递给 net use cmd - 我使用了 GetNetworkCredential().Username 和 GetNetworkCredential().Password 并且它有效 - 此密码是纯文本的。你甚至可以在输出控制台上打印它。 PS 并不安全,因为即使您使用 Get-Credential cmd-let,您也可以获得纯文本形式的密码。因此,我无法实现我的脚本。密码以纯文本形式提供,在公司中不安全。【参考方案2】:

您可以尝试通过调用 WmiMethod 来打开脚本:

$cmd = "CMD.EXE /c *\\\servername\somefolder\yourscript*.cmd" 

Invoke-WmiMethod -class Win32_process -name Create -ArgumentList $cmd -ComputerName *servername*

请注意,这将在服务器上运行脚本。你可以用它做更多的事情,比如远程安装一个包(在远程机器上本地复制包之后)。

希望对您有所帮助!

【讨论】:

这种方法并没有解决我的问题。我相信双跳问题仍然存在。直接从 WMI 像这样使用它:“powershell -ExecutionPolicy Bypass -file “\\server\path\file.ps1。”Powershell 抱怨它找不到文件。还尝试将其作为 .bat 脚本中的嵌入式命令远程服务器。直接从服务器(ps1 或 bat -> ps1)运行时,它可以工作。powershell 看到的用户名在所有情况下都是相同的。【参考方案3】:

alroc's helpful answer 很好地解释了问题并指出了通过先前配置解决问题的资源。

可以找到对底层问题(臭名昭著的 Kerberos双跳问题的解释,以及可用解决方案概述在this blog post。

关于在远程会话 (PSv3+) 中访问网络共享的临时解决方案

通过变量传递会话的凭据;例如,-Credential $cred

然后在会话中使用这些凭据 - 例如,$using:cred - 使用 New-PSDrive 建立映射网络位置的会话范围辅助驱动器。 映射驱动器后,即可访问目标位置 - 无论是通过驱动器名称还是直接通过 UNC 路径。

注意:这是 OP 他/她自己发现的方法的一种变体,并在对 alroc 答案的评论中进行了简要讨论,除了使用 New-PSDrive 而不是 net use,这消除了对以纯文本形式检索密码。

以下示例代码演示了从远程会话内部的网络共享运行脚本:

# A sample script to run from a network share on a remote computer.
$script = '\\server-001\install\Install-Agent.ps1'

# A sample target computer.
$computer = 'ws-002'

# Obtain the credentials for the remote session and store them in a variable.
$cred = Get-Credential $env:USERNAME

Invoke-Command -ComputerName $computer -Credential $cred 
  # Map the target network share as a dummy PS drive using the passed-through
  # credentials.
  # You may - but needn't - use this drive; the mere fact of having established
  # a drive with valid credentials makes the network location accessible in the
  # session, even with direct use of UNC paths.
  $null = New-PSDrive -Credential $using:cred -Name dummy -Root (Split-Path -Parent $using:script) -PSProvider FileSystem
  # Invoke the script via its UNC path.
  & $using:script

注意:

$null = ... 抑制 New-PSDrive 的输出(它输出一个描述新创建的驱动器的对象)。

由于New-PSDrive 创建的驱动器不是持久的(除非您传递-Persist),因此无需再次显式删除虚拟驱动器,但您可以使用Remove-PSDrive 这样做。

另请注意,PS 驱动器定义是作用域,因此只有调用作用域及其后代才能看到驱动器;这使得 & ... 中的包装语句可以在 child 范围内调用它们,这意味着在该块内创建的 PS 驱动器将在退出该块时自动超出范围。

【讨论】:

以上是关于无法访问 Powershell 远程会话中的 UNC 路径的主要内容,如果未能解决你的问题,请参考以下文章

在 powershell ssh 会话中访问 Windows 网络驱动器

无法使用 jinterop 打开 dcom 会话

如何在 powershell 远程会话(powershell)中编辑文件

Powershell 远程配置文件

powershell 在PowerShell中启动远程会话

跨脚本重用/共享powershell远程会话