Могу ли я найти причину сбоя Get-Item или Test-Path?

Существует множество сообщений о том, как использовать Test-Path или [System.IO.File]::Exists(), чтобы проверить, существует ли файл или папка. Однако эти посты не дают каких-либо нюансов. Следующее вернет true:

Test-Path -Path "\\Server\Share\path that exists"

Это вернет false:

Test-Path -Path "\\Server\Share\path that doesn't exist"

Но это также вернет false:

Test-Path -Path "\\Server\Share\path that exists but can't be access because network issues"

Я подумал, что вместо этого могу использовать Get-Item и перехватить сообщение об ошибке, чтобы использовать тип ошибки, чтобы определить, был ли путь просто недоступен или он действительно не существует. Однако Get-Item просто возвращает ItemNotFoundException, даже если целевой путь должен существовать, но недоступен.

Есть ли способ отличить недоступный путь от пути, которого на самом деле не существует?

Обновлено: в Windows уже есть коды системных ошибок, которые могут сказать вам, не был ли файл найден, или это была проблема с сетью, или доступ запрещен и т. д. Я ищу способ использовать этот уровень детализации. чтобы выяснить, почему путь недоступен в Powershell.

Как удаленный компьютер узнает о «пути, который существует, но не может быть доступен из-за проблем с сетью», если он не может получить к нему доступ? Если возникла проблема с сетью, например, маршрутизатор не работает и путь недоступен, сможет ли этот удаленный компьютер каким-то образом получить доступ к некоему магическому кешу всех путей, которые когда-то были ему доступны, и предположить, что этот путь все еще существует, и предложить этот другой путь? сообщение об ошибке? Я действительно пытаюсь понять, как это возможно.

Daniel 12.07.2024 07:11

Небольшая мысль: сначала проверьте «\\Server\Share», чтобы обнаружить проблемы с сетью (если вы точно знаете, что \\Server\Share существует). Затем проверьте подкаталог, чтобы обнаружить проблемы с не найденным путем. В качестве первого шага вы даже можете пропинговать «Сервер», чтобы определить, жив ли он, и только затем проверить наличие общего ресурса.

zett42 12.07.2024 08:22

Так чего же вы ожидаете от него, если путь недоступен и кто-то просто изменил или удалил путь/файл откуда-то еще?

iRon 12.07.2024 09:47

Почему бы ему не знать причину? Windows уже знает это по кодам ошибок. net helpmsg 5 = доступ запрещен, net helpmsg 2 = файл не найден, net helpmsg 53 = сетевой путь не найден и т. д. Поскольку Windows уже способна различать такие ситуации, я ожидаю, что в Powershell тоже будет какой-то способ сделать это. .

Tanaka Saito 16.07.2024 01:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
80
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Короткий ответ: нет. По сути, вы спрашиваете, как узнать, существует ли путь на USB-накопителе... пока диск не подключен.

Более развернутый ответ: вроде? Лучшее, что вы можете сделать, это сначала проверить соединение с помощью Test-Connection или чего-то еще, что в случае неудачи должно дать вам объяснение неудавшегося соединения.
Этого МОЖЕТ быть достаточно в вашем случае, если вам просто нужно контролировать, недоступен ли путь из-за проблем с подключением.

Ответ принят как подходящий

Это эксперимент, но, похоже, он работает хорошо:

Следующая функция PowerShell использует класс .NET DirectoryInfo для проверки существования пути и обработки исключений, которые предоставляют более подробную информацию об ошибке.

function Test-NetworkPath([string]$Path) {
   try {
      $dirInfo = [IO.DirectoryInfo]::new($Path)
      if ($dirInfo.Exists) { Write-Host 'Path exists.' }
      else {
         Write-Host 'Path does not exist.'
         # Attempt to access the directory to trigger an error for further diagnosis
         $null = $dirInfo.GetDirectories()
      }
   }
   catch [System.ArgumentNullException] {
      Write-Host 'Path is null.'
   }
   catch [System.ArgumentException] {
      Write-Host 'Path contains invalid characters such as ", <, >, or |.'    # .NET Framework and .NET Core versions older than 2.1
   }
   catch [System.IO.PathTooLongException] {
      Write-Host 'Path is too long.'
   }
   catch [System.IO.DirectoryNotFoundException] {
      Write-Host 'Directory not found.'
   }
   catch [System.Security.SecurityException] {
      Write-Host 'Path is inaccessible due to: Caller does not have the required permission.'
   }
   catch [System.IO.IOException] {
      Write-Host 'Path is inaccessible, likely due to network issues.'
   }
   catch {
      Write-Host ('Unexpected error: {0}' -f $_.Exception.GetType().FullName)
   }
}

Объяснение:

  • $dirInfo = [IO.DirectoryInfo]::new($Path)
    • Получите информацию о каталоге и, возможно, выдайте ошибку, если $Path сформирован неправильно.
  • if ($dirInfo.Exists) { Write-Output 'Path exists.' }
    • Простая проверка наличия.
  • $null = $dirInfo.GetDirectories()
    • Попытка вернуть подкаталоги несуществующего $Path.
    • Выдает довольно информативную ошибку.

Действительный путь:

Test-NetworkPath '\\ValidServer\C$\ValidFolder'

Выход:

Path exists.

Неверная папка:

Test-NetworkPath '\\ValidServer\C$\InvalidFolder'

Выход:

Path does not exist.
Directory not found.

Несуществующий сервер (ошибка сети):

Test-NetworkPath '\\InvalidServer\C$\SomeFolder'

Выход:

Path does not exist.
Path is inaccessible, likely due to network issues.

Да, это именно то, что я искал! Я пытался инициировать эти типы тонких сообщений об ошибках с помощью Get-Item и Get-ChildItem, но эти командлеты имеют много встроенной отказоустойчивости, которая мне не нужна (например, если -Path имеет значение null или пусто, это будет по умолчанию используется текущее местоположение, что в моем случае дает неправильный возврат и т. д.) Большое спасибо за помощь!

Tanaka Saito 16.07.2024 05:16

Одно из улучшений, которое я обнаружил, заключается в том, что [IO.DirectoryInfo]::New() действительно будет работать с путями длиной более 246 символов и находить путь, но .Exists по-прежнему будет сообщать ложь, потому что он слишком длинный. Поэтому я добавил раздел if ($Path.Length -gt 246){#use Get-Item here на всякий случай} и удалил исключение слишком длинного пути. Одна интересная вещь: -Path $Null по-прежнему говорит «недопустимые символы». Для меня «Доступ запрещен» вызывает исключение System.Management.Automation.MethodInvocationException, а не SecurityException.

Tanaka Saito 16.07.2024 08:01

@TanakaSaito, это странно! Я не проверял эти сценарии и в основном использовал информацию, найденную здесь. Но с другой стороны, это не совсем удивительно. Я придумал System.IO.IOException для сети так: я попробовал несуществующий сервер, и это выдало ошибку. Кроме того, теперь, когда я об этом думаю, я специально поставил System.IO.IOException последним, PathTooLongException наследуется от него. Не проверял, но предполагаю, что порядок важен.

Darin 16.07.2024 10:16

Я думал, что найти информацию о том, почему вы получаете исключение MethodInvocationException, будет легко, но пока это не так. Но, как ни странно, поиск его без «PowerShell» по-прежнему вызывает множество проблем, связанных с PowerShell. Заставляет меня задуматься, является ли фактическим источником PowerShell, а не DirectoryInfo или GetDirectories, но я не понимаю, как это могло быть. Если я найду время сегодня, я мог бы попробовать несколько экспериментов и посмотреть, получу ли я ту же ошибку.

Darin 16.07.2024 10:42

Возможно, я сказал слишком рано: категория ошибки — MethodInvoctionException, но полный идентификатор ошибки — UnauthorizedAccessException, что имеет гораздо больше смысла.

Tanaka Saito 16.07.2024 17:05

Другие вопросы по теме