Jon*_*han 22 powershell cmd unc batch-file
我正在编写一个执行Powershell脚本的批处理文件,该脚本在某一时刻将具有UNC路径的项作为属性循环并Get-ChildItem在这些路径上使用.在最小版本中,这是我的脚本中发生的事情:
Master.bat
powershell -ExecutionPolicy ByPass -File "Slave.ps1"
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,当我运行Master.bat时,它会因为Get-ChildItem错误而失败
get-childitem : Cannot find path '\\remote-server\foothing' because it does not exist.
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用Powershell直接运行Slave.ps1文件,它似乎完全正常.为什么只有在运行Master.bat文件时才会发生这种情况?
我尝试过的事情
FileSystem::提供商之前添加UNC路径http://powershell.org/wp/2014/02/20/powershell-gotcha-unc-paths-and-providers/-literalPath参数而不是plain -path参数Get-ChildItemGet-ChildItem \\remote-server\foothing在PowerShell中运行并成功验证与远程服务器的连接Ror*_*ory 40
我在运行引用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
}
Run Code Online (Sandbox Code Playgroud)
所以我的决心是确保在执行此代码之前将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
}
Run Code Online (Sandbox Code Playgroud)
我希望这会有所帮助 - 我会对赏金感到非常满意,因为这是我对堆栈溢出的第一个答案.PS我忘了添加 - PS命令提示符root可以由机器配置中的自动加载模块设置.我会检查Get-Location,看看你是否真的从非FileSystem位置执行.
mkl*_*nt0 12
Rory的回答提供了一种有效的解决方法,但是有一种解决方案不需要首先将当前位置更改为FileSystem提供者位置:
使用UNC路径前缀FileSystem::以确保它们被正确识别,而不管当前位置如何:
$foo = @{Name = "Foo"}
$foo.Path = "FileSystem::\\remote-server\foothing"
$bar = @{Name = "Bar"}
$bar.Path = "FileSystem::\\remote-server\barthing"
Run Code Online (Sandbox Code Playgroud)
或者,这里是对Rory回答的一个调整,以避免在全局范围内更改当前位置会话(以保留当前位置),使用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
}
Run Code Online (Sandbox Code Playgroud)
这篇优秀的博客文章解释了潜在的问题(强调增加):
PowerShell不会将[UNC路径]识别为"root",因为它们不在PSDrive上; 因此,与PowerShell当前位置关联的任何提供程序都将尝试处理它们.
添加前缀FileSystem::明确地将路径标识为FileSystem提供者路径,而不考虑当前位置下的提供者.
| 归档时间: |
|
| 查看次数: |
46620 次 |
| 最近记录: |