Powershell函数意外地不返回任何对象

时间:2018-03-01 20:40:08

标签: powershell syntax control-flow

我希望在.ps1文件中有一些代码可以创建一个可以在其他.ps1脚本中使用的PSSession(为了避免代码重复)。

起初我以为我需要一个创建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',但我知道该函数运行是因为我得到了凭证提示。

编辑:

好的,现在可以了:

  • Catch的中断正在阻止一切。
  • 函数调用必须不带括号。
  • 第二个代码错误,因为必须在调用之前定义函数。

1 个答案:

答案 0 :(得分:1)

您自己已经发现了问题,但由于它们是常见的陷阱,请让我详细说明一下:

  • 仅在循环中使用break / continue forforeach,{{1} },while)或 do语句的分支处理程序。

    • 否则, PowerShell会查找封闭循环的调用堆栈,如果没有,退出脚本

    • 这是switch区块中break发生的情况。

  • 不要使用catch括起函数(命令)参数列表,也不要将参数与(...) 分开:

    • 在PowerShell中,函数 - 就像cmdlet一样 - 使用类似shell的语法调用,不带括号和使用以空格分隔的参数,仅用于构造数组以作为单个参数传递) [1]

      ,
  • 在PowerShell中,函数必须先定义才能调用

    • 您最初没有注意到,因为# 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 函数的以前的定义恰好存在。

[1]有关PowerShell的两种基本解析模式的更多信息 -  参数模式表达模式 - 请参阅我的this answer