首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在UNC路径上运行Get-ChildItem在Powershell中工作,而在批处理文件中运行的Powershell中不起作用。

在UNC路径上运行Get-ChildItem在Powershell中工作,而在批处理文件中运行的Powershell中不起作用。
EN

Stack Overflow用户
提问于 2014-05-09 22:04:00
回答 3查看 65.8K关注 0票数 25

我正在编写一个批处理文件,它执行一个Powershell脚本,该脚本在某一点上循环项目,将UNC路径作为属性,并在这些路径上使用Get-ChildItem。在最低版本中,这就是我的脚本中正在发生的情况:

Master.bat

代码语言:javascript
复制
powershell -ExecutionPolicy ByPass -File "Slave.ps1"

Slave.ps1

代码语言:javascript
复制
$foo = @{Name = "Foo"}
$foo.Path = "\\remote-server\foothing"

$bar = @{Name = "Bar"}
$bar.Path = "\\remote-server\barthing"

@( $foo, $bar ) | ForEach-Object {
    $item = Get-ChildItem $_.Path
    # Do things with item
}

我遇到的问题是,当我运行Master.bat时,它会在Get-ChildItem上失败,并在

代码语言:javascript
复制
get-childitem : Cannot find path '\\remote-server\foothing' because it does not exist.

但是,如果我直接使用Powershell运行Slave.ps1文件,它似乎工作得很好。为什么只有在运行Master.bat文件时才会发生这种情况?

我试过的东西

  • 使用FileSystem::在UNC路径前面加上提供程序http://powershell.org/wp/2014/02/20/powershell-gotcha-unc-paths-and-providers/
  • 确保在实际路径中没有奇怪的字符
  • 使用-literalPath参数代替Get-ChildItem的普通-path参数
  • Get-ChildItem \\remote-server\foothing中运行PowerShell并成功验证到远程服务器的连接
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-13 08:14:21

在运行引用UNC路径的脚本时,我发现了这个问题--但只有当脚本的根设置为非文件系统位置时,才会发生错误。例如PS SQLSEVER\

因此,下面的错误与相同的错误一起失败:

代码语言:javascript
复制
cd env:
$foo = @{Name = "Foo"}
$foo.Path = "\\remote-server\foothing"

$bar = @{Name = "Bar"}
$bar.Path = "\\remote-server\barthing"

@( $foo, $bar ) | ForEach-Object {
    $item = Get-ChildItem $_.Path
    # Do things with item
     Write-Host $item
}

因此,我的解决方案是确保在执行此代码之前将PS提示符返回到文件系统位置。例如:

代码语言:javascript
复制
cd env:
$foo = @{Name = "Foo"}
$foo.Path = "\\remote-server\foothing"

$bar = @{Name = "Bar"}
$bar.Path = "\\remote-server\barthing"

cd c: #THIS IS THE CRITICAL LINE
@( $foo, $bar ) | ForEach-Object {
    $item = Get-ChildItem $_.Path
    # Do things with item
     Write-Host $item
}

我希望这能帮上忙--我很高兴得到赏赐,因为这是我第一次回答堆栈溢出问题。我忘了添加- PS命令提示符根可能是由机器配置中的自动加载模块设置的。我会检查Get-Location,看看您是否实际上是从非FileSystem位置执行的。

票数 47
EN

Stack Overflow用户

发布于 2017-02-28 16:06:28

罗里的回答提供了一个有效的解决方案,但解决方案不需要将当前位置更改为FileSystem提供者位置优先

FileSystem::为您的UNC路径加上前缀,以确保它们被正确识别,无论当前位置如何:

代码语言:javascript
复制
$foo = @{
   Name = "Foo"
   Path = "FileSystem::\\remote-server\foothing"
}

$bar = @{
   Name = "Bar"
   Path = "FileSystem::\\remote-server\barthing"
}

或者,下面是对罗里的答案( to )的修改,避免更改当前位置会话--全局(以保留当前位置),使用Push-LocationPop-Location

代码语言:javascript
复制
try {
  # Switch to the *filesystem provider's* current location, whatever it is.
  Push-Location (Get-Location -PSProvider FileSystem)

  # Process the paths.
  $foo, $bar | ForEach-Object {
      $item = Get-ChildItem $_.Path
      # Do things with item
  }
} finally {
   # Restore the previous location.
   Pop-Location
}

可选背景信息

这篇优秀的博客文章解释了根本的问题(强调是加在后面的):

PowerShell不承认UNC路径是“根”路径,因为它们不是在PSDrive上;因此,不管与PowerShell当前位置相关的提供者是什么,都会尝试处理它们,

添加前缀FileSystem::毫不含糊地将路径标识为FileSystem提供程序路径,而不管当前位置的基础是哪个提供程序。

票数 13
EN

Stack Overflow用户

发布于 2015-09-21 16:15:09

我在其他地方读过一些关于Push-LocationPop-Location命令来解决这类问题的文章--我是在手动一步一步地测试脚本有push/pop的新例程时遇到的,但是我忘了在PS窗口上执行它们。在检查了@Rory的答案之后,我注意到我使用的是:\,而不是PS C:\提示符。

因此,在您的“奴隶”脚本中使用此功能的一种方法是:

代码语言:javascript
复制
$foo = @{Name = "Foo"}
$foo.Path = "\\remote-server\foothing"

$bar = @{Name = "Bar"}
$bar.Path = "\\remote-server\barthing"

@( $foo, $bar ) | ForEach-Object {
    $item = Get-ChildItem $_.Path
    Push-Location
    # Do things with item
    Pop-Location
}

考虑在# Do things之前和之后添加Push/Pop,因为似乎正是这些东西改变了位置。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23574653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档