如果ComputerName是localhost或'则将powershell脚本作为本地脚本运行。'

时间:2014-08-28 17:16:12

标签: powershell powershell-remoting

我有这个应该能够在远程和localhost上运行的脚本。它接受-ComputerName作为参数'。' (localhost)默认为。

目前我正在测试如何验证新的远程会话并为其编写一个小cmdlet。问题是,如果我用'运行这个脚本。'或localhost作为ComputerName,脚本尝试连接到我的计算机上的新远程会话。这不起作用,因为我没有启用PSRemoting。

这是我的测试脚本:

Function Test-PsRemoting {
[CmdletBinding()]
param(
    $ComputerName = ".",
    $Credentials    
)

$ErrorActionPreference = "Stop"

Test-Connection -ComputerName $ComputerName -Count 1 | 
    Format-List -Property PSComputerName,Address,IPV4Address,IPV6Address

Test-WSMan $ComputerName

$session = New-PSSession -ComputerName $ComputerName -Credential $Credentials
Invoke-Command -ComputerName $computername { 1 }
}

所有命令,Test-WSMan,New-PSSession和Invoke-Command都将失败,因为他们假设我想建立远程连接

如果$ ComputerName是'是否可以让Powershell在本地会话中运行命令。'或localhost或我是否必须在if / else子句中自行处理?

该脚本旨在运行本地和远程计算机,我不希望启用PSRemoting是本地运行脚本的必要条件

3 个答案:

答案 0 :(得分:2)

AFAIK没有$localsession - 变量。你可以使用if-tests:

Function Test-PsRemoting {
    [CmdletBinding()]
    param(
        $ComputerName = ".",
        $Credentials    
    )

    $ErrorActionPreference = "Stop"

    $remote = $ComputerName -notmatch '\.|localhost'
    $sc = { 1 }

    #If remote computer, test connection create sessions
    if($remote) {
        Test-Connection -ComputerName $ComputerName -Count 1 | 
            Format-List -Property PSComputerName,Address,IPV4Address,IPV6Address

        Test-WSMan $ComputerName

        $session = New-PSSession -ComputerName $ComputerName -Credential $Credentials
    }

    if($remote) {
        #If remote computer
        Invoke-Command -ComputerName $computername -ScriptBlock $sc
    } else { 
        #Localhost
        Invoke-Command -ScriptBlock $sc
    }

}

答案 1 :(得分:0)

看起来您正在尝试检查PowerShell Remoting是否已在计算机上启用/运行。如果您不希望yoru函数针对本地计算机运行,则可以过滤掉本地计算机,或将其留给任何正在调用Test-PsRemoting的人传递非本地计算机名称。如果他们确实通过本地计算机,那么他们将得到PowerShell Remoting未启用的结果。

function Test-PsRemoting 
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string[]]
        # The computers to check.
        $ComputerName,

        [Management.Automation.PSCredential
        # The credentials to use to connect to the computers.
        $Credentials    
    )

    # Filter out local computer names
    $ComputerName = $ComputerName | Where-Object { $_ -ne '.' -and $_ -ne $env:COMPUTERNAME }

    Test-Connection -ComputerName $ComputerName -Count 1 | 
        Format-List -Property PSComputerName,Address,IPV4Address,IPV6Address

    $credentialsParam = @{ }
    if( $Credentials )
    {
        $credentialsParam.Credentials = $Credentials
    }

    Test-WSMan -ComputerName $ComputerName @credentialsParam

    Invoke-Command -ComputerName $ComputerName { hostname } @credentialsParam
}

答案 2 :(得分:0)

响应一个非常旧的线程,以防其他人偶然发现它。 Frode的答案很好用,但是我也想分享自己的解决方案,因为它更易于维护。如果定义了ComputerName参数,则该函数将远程调用自身。

这不适用于所有脚本,并且您需要小心避免递归错误。这是一个简单的示例:

function Invoke-LocalOrRemote
{
    param
    (
        [string]$ExampleArgument,
        [string]$ComputerName
    )

    # Invoke the function remotely if a valid computer name is defined
    if ( $ComputerName -and ( Test-Connection $ComputerName -Count 1 -ErrorAction SilentlyContinue ) )
    {
        return Invoke-Command -ComputerName $ComputerName -ScriptBlock ${function:Invoke-LocalOrRemote} -ArgumentList $ExampleArgument
    }
    elseif ( $ComputerName ) { return "Error: Could not connect to remote computer '$ComputerName'" }

    # Actual function contents
    return "Function run with argument '$ExampleArgument' on computer '$($env:COMPUTERNAME)'"
}