接受来自管道 Powershell 函数的值

接受来自管道 Powershell 函数的值

我想创建一个脚本来告诉用户是否在多台远程计算机上启用了 PSRemoting。以下是我目前所拥有的:

function Test-PSRemoting
{
   Param(
   [Parameter(Mandatory=$True, ValueFromPipeline=$True)] 
   [string[]] $ComputerName,

   [string] $Credential)

   $file = Read-Host "Enter file location for all error details: "

   try {
    $result = Invoke-Command -ComputerName $ComputerName -Credential $Credential { 1 } -ErrorAction SilentlyContinue -ErrorVariable Problem 
    If ($Problem){
    $result = 0}
   } catch {
    $result = 0}

   If ($result -eq 1){
   write-host "PSRemoting is enabled on: " $ComputerName
   } else {
   write-host "PSRemoting is not enabled/working on: " $ComputerName    
   $Problem | Out-File $file -Append}

} 

如果我只指定一台计算机,该功能就可以完美运行:

Test-PSRemoting -ComputerName Server1 - Credentials Admin

但是,如果我指定多台计算机,则该功能无法正常工作:

Test-PSRemoting -ComputerName Server1, Server2 - Credentials Admin
Server1, Server2 | Test-PSRemoting -Credentials Admin

答案1

在这种情况下,我会使用 Process{} 块(也回答了您关于为什么只检查 Server2 的评论)。

function test-ps
{
    param(
     [Parameter(ValueFromPipeline=$true)]
     [string[]] $CN
    )
    process{
        Write-Host $CN "h"
    }
}

'test1','test2' | test-ps

http://ss64.com/ps/syntax-function-input.html

答案2

尝试以下内容,下面的评论请注意重点。

function Test-PSRemoting
{

[CmdletBinding()]
param
    (
        [Parameter(Mandatory = $True, ValueFromPipeline = $True)] 
        [string[]]$ComputerName,

        [Parameter(Mandatory = $False)]
        [System.Management.Automation.PSCredential]$Credential = (Get-Credential),

        [Parameter(Mandatory = $True)]
        [String]$OutFile
    )

process
    {
        # Pass computer name along the pipeline to allow for more then one.
        $ComputerName | % `
        {
            $pcName = $_;

            $problem = $Null;

            try
            {
                $result = Invoke-Command -ComputerName $pcName -Credential $Credential { 1 } -ErrorAction SilentlyContinue -ErrorVariable problem;

                if ($problem -eq $Null -and $result -eq 1)
                {
                    # Use Write-Verbose instead. Test-* commands are meant to return true/false.
                    # But additional status can be viewed by adding the -Verbose parameter to Test-PSRemoting. i.e. Test-PSRemoting -Verbose
                    Write-Verbose "PSRemoting is enabled on: $pcName";

                    return $True;
                }
                else
                {
                    Write-Verbose "PSRemoting is not enabled/working on: $pcName";

                    $problem | Out-File $OutFile -Append;

                    return $False;
                }
            }
            catch
            {
                return $False
            }
        }
    }
}

要点是:

  • 使用$ComputerName |允许Test-PSRemoting -ComputerName Server1,Server2通过处理每个指定的计算机名称的条件逻辑来进行使用。Invoke-Command 自然会处理多个计算机名称,但您的if语句不会。
  • 移至$file参数$OutFile而非 Read-Host,并标记为强制输入的强制参数。留Read-Hostprocess { }块中意味着如果Server1,Server2 | Test-PSRemoting使用,文件路径将被多次请求。还具有能够作为参数传递而不是每次手动输入的优点。
  • 将详细输出移至Write-Verbose而不是Write-Host。Test-* 命令应返回 True/False 而不是字符串。用于-Verbose查看详细输出。此外,您可以将Write-Verbose "PSRemoting is not enabled/working on: $pcName";行更改为Write-Warning

相关内容