Функция Powershell неожиданно не возвращает объект

Я хочу иметь в файле .ps1 некоторый код, создающий сеанс PSSession, который можно использовать в других сценариях .ps1 (во избежание дублирования кода).

Сначала я подумал, что мне нужна функция, которая создает PSSession и возвращает ее, но я не понимаю, как работают выходные данные функции.

Вот моя функция:

function newRemoteSession
{
    param([string]$ipAddress)

    $accountName = 'admin'
    $accountPassword = 'admin'
    $accountPasswordSecure = ConvertTo-SecureString $accountPassword -AsPlainText -Force
    $accountCredential = New-Object System.Management.Automation.PSCredential ($accountName, $accountPasswordSecure)

    Try
    {
        $remoteSession = New-PSSession -ComputerName $ipAddress -UseSSL -Credential $accountCredential -SessionOption (New-PSSessionOption -SkipCACheck -SkipCNCheck) -ErrorAction Stop
    }
    Catch [System.Management.Automation.RuntimeException] #PSRemotingTransportException
    {
        Write-Host 'Could not connect with default credentials. Please enter credentials...'    
        $remoteSession = New-PSSession -ComputerName $ipAddress -UseSSL -Credential (Get-Credential) -SessionOption (New-PSSessionOption -SkipCACheck -SkipCNCheck) -ErrorAction Stop
        Break
    }

    return $remoteSession
}

Однако, когда я звоню $s = newRemoteSession(192.168.1.10), $s пусто.

Когда я запускаю скрипт с

Write-Host '00'
$s = newRemoteSession('192.168.1.10')
$s
Write-Host '02'

function newRemoteSession
{
        ........
    Write-Host '01'
    $remoteSession
}

Я получаю только «00» в консоли, но я знаю, что функция работает, потому что я получаю запрос учетных данных.

РЕДАКТИРОВАТЬ:

Хорошо, теперь это работает:

  • Break in the Catch останавливал все.
  • Вызов функции должен быть без скобок.
  • Второй код был неправильным, потому что функция должна быть определена до вызова.

person Axel Williot    schedule 01.03.2018    source источник
comment
Если вы поместите функцию в тот же файл, где вы пытаетесь ее вызвать, она сработает?   -  person EBGreen    schedule 01.03.2018
comment
Запустите $s = newRemoteSession '192.168.1.10' без скобок.   -  person JosefZ    schedule 02.03.2018
comment
Я получаю одинаковые результаты с $s = newRemoteSession '192.168.1.10' и с $s = newRemoteSession -ipAddress '192.168.1.10'   -  person Axel Williot    schedule 02.03.2018
comment
Код, который вы разместили, должен привести к ошибке при первом запуске.   -  person EBGreen    schedule 02.03.2018
comment
Кроме того, если вы получили приглашение и не видите узел записи, значит, выполняется только часть кода функции.   -  person EBGreen    schedule 02.03.2018
comment
Попробуйте убрать квалификатор из вашего блока catch   -  person EBGreen    schedule 02.03.2018
comment
Является ли ваш второй блок полным сценарием? функция должна быть определена до вызова. Как сказал @JosefZ, вам также необходимо удалить скобки из вызова функции. Попробуйте написать сценарий в PowerShell_ISE, если это возможно, а затем выполните отладку. Вам также не нужен разрыв в блоке catch.   -  person Matthew Wetmore    schedule 02.03.2018
comment
Вы не захватываете New-PSSession … -ErrorAction Stop внутри Catch блока.   -  person JosefZ    schedule 02.03.2018
comment
@JozefZ Загвоздка для первой New-PSSession: если она терпит неудачу (из-за неправильных учетных данных по умолчанию), я вспоминаю ее с запросом учетных данных.   -  person Axel Williot    schedule 02.03.2018


Ответы (1)


Вы сами нашли проблемы, но, поскольку они являются распространенными ловушками, позвольте мне немного уточнить:

  • Используйте break / continue только внутри цикла (for, foreach, while, do) или в обработчиках ветвлений switch оператора.

    • В противном случае PowerShell ищет в стеке вызовов замыкающий цикл и, при его отсутствии, выходит из сценария.

    • Это то, что произошло с break в вашем блоке catch.

  • Не используйте (...) для включения списка аргументов функции (команды) и не разделяйте аргументы с помощью ,:

    • В PowerShell функции, как и командлеты, вызываются с синтаксисом похожим на оболочку, без круглых скобок и с пробелами. разделенные аргументы (, используется только для создания массива для передачи в качестве одного аргумента)[1] .

      # WRONG: method-invocation syntax does NOT apply to *functions*
      # (It *happens* to work *in this case*, however, because only a
      # a *single* argument is passed and the (...) is a no-op in this case,
      # but this syntax should never be used.)
      newRemoteSession('192.168.1.10')
      
      # OK: Shell-like syntax, which PowerShell calls *argument mode*:
      # Note that the argument needn't be quoted, because it 
      # contains no shell metacharacters.
      # If there were additional arguments, you'd separate them with *whitespace*
      newRemoteSession 192.168.1.10
      
      # BETTER: You can even use *parameter names* (again, as with cmdlets),
      # which helps readability.
      newRemoteSession -ipAddress 192.168.1.10
      
  • В PowerShell функции должны быть определены до их вызова.

    • You initially didn't notice, because a previous definition of your newRemoteSession function happened to exist.

[1] Для получения дополнительной информации о двух основных режимах синтаксического анализа PowerShell — режиме аргументов и режиме выражений — см. этот мой ответ.

person mklement0    schedule 01.03.2018