#powershell #networking #ip #stderr #smb
#powershell #сеть #ip #stderr #smb
Вопрос:
Я хотел захватить общие ресурсы SMB с помощью PowerShell, но это не работает
# Cannot use CIM as it throws up WinRM errors.
# Could maybe use if WinRM is configured on all clients, but this is not a given.
$cim = New-CimSession -ComputerName $hostname
$sharescim = Get-SmbShare -CimSession $cim
Итак, это привело меня к другому методу с использованием net view, и это вполне нормально, если хост — Windows
# This method uses net view to collect the share names (including hidden shares like C$) into an array
# https://www.itprotoday.com/powershell/view-all-shares-remote-machine-powershell
try { $netview = $(net view \$hostname /all) | select -Skip 7 | ?{$_ -match 'disk*'} | %{$_ -match '^(. ?)s Disk*'|out-null ; $matches[1]} }
catch { $netview = "No shares found" }
Итак, если хост — Linux, я получаю сообщение об ошибке, и, как вы можете видеть, я пытаюсь выше подавить эту ошибку с помощью try / catch, но это не удается.
Очевидно, это связано с тем, что «net view» — это CMD, поэтому он не управляется try / catch. Итак, мой вопрос: как я могу а) подавить системную ошибку ниже? и б) обработать эту ошибку, когда она произойдет (т. Е. выдать сообщение «Этот хост не отвечает на «net view»» или что-то вместо ошибки)?
System error 53 has occurred.
The network path was not found.
Комментарии:
1. В качестве отступления: вам не нужно
$(...)
запускать внешнюю программу; короче говоря:$(...)
требуется только в расширяемых строках ("..."
) или для встраивания целых операторов в другие операторы.2. Еще один аспект:
net.exe
это консольное приложение и, как таковое, не связано с какой-либо конкретной оболочкой. Как консольное приложение, оно имеет в своем распоряжении только два выходных потока: stdout (стандартный вывод) для данных и stderr (стандартная ошибка) для сообщений об ошибках и / или сообщений о состоянии.
Ответ №1:
Вывод Stderr (стандартная ошибка) из внешних программ не интегрирован с обработкой ошибок PowerShell, в первую очередь потому, что этот поток используется не только для передачи ошибок, но и информации о состоянии.
(Поэтому вы должны только выводить успех или сбой вызова внешней программы из ее кода выхода, как показано в $LASTEXTICODE
[1]).
Однако вы можете перенаправить вывод stderr, и перенаправление его на $null
( 2>$null
) отключает его [2]:
$netview = net view \$hostname /all 2>$null | ...
if (-not $netview) { $netview = 'No shares found' }
[1] Действие с ненулевым кодом выхода, который по соглашению сигнализирует об ошибке, также не интегрировано в обработку ошибок PowerShell начиная с версии 7.1, но исправление этого предлагается в этом RFC.
[2] Вплоть до PowerShell 7.1.x любое 2>
перенаправление неожиданно также записывает строки stderr в автоматическую $Error
коллекцию. Эта проблема была исправлена в версии 7.1
как неприятный побочный эффект, в версиях до версии 7.0 2>
перенаправление может также выдавать ошибку завершения сценария $ErrorActionPreference = 'Stop'
, если она имеет место, если выдается хотя бы одна строка stderr.