我正在编写一个批处理文件,它执行一个Powershell脚本,该脚本在某一点上循环项目,将UNC路径作为属性,并在这些路径上使用Get-ChildItem。在最低版本中,这就是我的脚本中正在发生的情况:
Master.bat
powershell -ExecutionPolicy ByPass -File "Slave.ps1"Slave.ps1
$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上失败,并在
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并成功验证到远程服务器的连接发布于 2014-05-13 08:14:21
在运行引用UNC路径的脚本时,我发现了这个问题--但只有当脚本的根设置为非文件系统位置时,才会发生错误。例如PS SQLSEVER\
因此,下面的错误与相同的错误一起失败:
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提示符返回到文件系统位置。例如:
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位置执行的。
发布于 2017-02-28 16:06:28
罗里的回答提供了一个有效的解决方案,但解决方案不需要将当前位置更改为FileSystem提供者位置优先
FileSystem::为您的UNC路径加上前缀,以确保它们被正确识别,无论当前位置如何:
$foo = @{
Name = "Foo"
Path = "FileSystem::\\remote-server\foothing"
}
$bar = @{
Name = "Bar"
Path = "FileSystem::\\remote-server\barthing"
}或者,下面是对罗里的答案( to )的修改,避免更改当前位置会话--全局(以保留当前位置),使用Push-Location和Pop-Location
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提供程序路径,而不管当前位置的基础是哪个提供程序。
发布于 2015-09-21 16:15:09
我在其他地方读过一些关于Push-Location和Pop-Location命令来解决这类问题的文章--我是在手动一步一步地测试脚本有push/pop的新例程时遇到的,但是我忘了在PS窗口上执行它们。在检查了@Rory的答案之后,我注意到我使用的是:\,而不是PS C:\提示符。
因此,在您的“奴隶”脚本中使用此功能的一种方法是:
$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,因为似乎正是这些东西改变了位置。
https://stackoverflow.com/questions/23574653
复制相似问题