programing

UNC 경로에서 Get-ChildItem을 실행하면 Powershell에서는 작동하지만 배치 파일에서는 실행되지 않음

testmans 2023. 9. 7. 21:35
반응형

UNC 경로에서 Get-ChildItem을 실행하면 Powershell에서는 작동하지만 배치 파일에서는 실행되지 않음

하여 한 UNC 를 하여 을 하는 하고 을 를 에서 으로 하고 을 하는 에서 Get-ChildItem그 길들에서.미니멀 버전에서는 스크립트에서 다음과 같은 일이 발생합니다.

주인님.배트

powershell -ExecutionPolicy ByPass -File "Slave.ps1"

슬레이브 .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
}

제가 직면한 문제는 마스터.bat을 실행할 때 실패한다는 것입니다.Get-ChildItem

get-childitem : Cannot find path '\\remote-server\foothing' because it does not exist.

하지만 파워셸을 이용해서 직접 Slave.ps1 파일을 실행하면 완벽하게 잘 되는 것 같습니다.Master.bat 파일을 실행할 때만 이 문제가 발생할 수 있는 이유는 무엇입니까?

내가 시도해본 것들

  • 에 UNC 에 과 FileSystem::http://powershell.org/wp/2014/02/20/powershell-gotcha-unc-paths-and-providers/ 제공업체와 함께
  • 실제 경로에 이상한 문자가 없는지 확인합니다.
  • 을 해서.-literalPath신개수e 매개 변수-path개에 대한 매개 Get-ChildItem
  • 실행중 입니다.Get-ChildItem \\remote-server\foothing 서버에서격한결인공에공인결n격에한rd

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을 통해 당신이 실제로 파일시스템이 아닌 위치에서 실행되고 있는지 확인하겠습니다.

로리의 대답은 효과적인 해결책을 제공하지만, 우선 현재 위치를 파일 시스템 공급자 위치로 변경할 필요가 없는 솔루션이 있습니다.

UNC 경로가 현재 위치에 관계없이 올바르게 인식되는지 확인하기 위해 UNC 경로 앞에 를 붙입니다.

$foo = @{
   Name = "Foo"
   Path = "FileSystem::\\remote-server\foothing"
}

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

또는 현재 위치를 세션 전체적으로 변경하지 않도록(현재 위치가 무엇이든 보존하도록) 로리의 답변을 수정합니다.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
}

선택적 배경 정보

이 우수한 블로그 게시물은 근본적인 문제를 설명합니다(강조 추가).

[UNC 경로]가 PSD에 없기 때문에 PowerShell은 이 경로를 "루티드"로 인식하지 않습니다. 따라서 PowerShell의 현재 위치와 관련된 공급업체는 이 경로를 처리하려고 시도할 것입니다.

접두사 추가하기FileSystem::그 길은 하나의 존재로서 명확하게 식별됩니다.FileSystem현재 위치의 기본 공급자에 관계없이 공급자 경로를 지정합니다.

이런 문제에 대응하기 위한 명령과 명령에 대해 다른 곳에서 읽었습니다. 스크립트에 푸시/팝 기능이 있는 새로운 루틴을 수동으로, 단계적으로 테스트하는 동안 귀하의 질문에 도달했지만 PS 창에서 이 작업을 수행하는 것을 잊어버렸습니다.@Rory의 답변을 확인한 후 PS C:\ 프롬프트 대신 PS SQL Server:\ 프롬프트에 있는 것을 확인했습니다.

따라서 "슬레이브" 스크립트에서 이를 사용하는 방법은 다음과 같습니다.

$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장소를 바꾸는 것들인 것 같기 때문입니다.

언급URL : https://stackoverflow.com/questions/23574653/running-get-childitem-on-unc-path-works-in-powershell-but-not-in-powershell-run

반응형