1

我有一个包含服务器列表的文本文件,每行一个,例如:

SERVER1
SERVER2
SERVER3

当我Get-Content对文件执行 a 时,我确实看到输出为:

SERVER1
SERVER2
SERVER3

所以现在我正在编写一个函数,我想将多个服务器作为一个数组接收,并迭代函数中的数组。该功能目前是这样的:

function Get-LocalAdministrators 
{
    param(
        [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        [string[]]$computers
    )

    foreach ($computername in $computers)
    {
        $ADMINS = get-wmiobject -computername $computername -query "select * from win32_groupuser where GroupComponent=""Win32_Group.Domain='$computername',Name='administrators'""" | % {$_.partcomponent}

        foreach ($ADMIN in $ADMINS) 
        {
            $admin = $admin.replace("\\$computername\root\cimv2:Win32_UserAccount.Domain=","") # trims the results for a user
            $admin = $admin.replace("\\$computername\root\cimv2:Win32_Group.Domain=","") # trims the results for a group
            $admin = $admin.replace('",Name="',"\")
            $admin = $admin.REPLACE("""","") # strips the last "

            $objOutput = New-Object PSObject -Property @{
                Machinename = $($computername)
                Fullname = ($admin)
                #DomainName  =$admin.split("\")[0]
                #UserName = $admin.split("\")[1]
            }

        $objReport+=@($objOutput)
        }

        return $objReport
    }
}

然后我打算将该函数称为:

Get-Content “C:\temp\computers.txt” | Get-LocalAdministrators

但是,当我运行该函数时,我可以看到 $computers 的值是{SERVER3}(即文件中的最后一行。)我试图通过谷歌找到答案,虽然有很多数组参考/示例,我找不到一个将文件中的值结合到param语句中的数组中的位置。请原谅我的 PS newb 无知,并提供我需要的线索......谢谢。

更新:链接到在 PowerGUI 脚本编辑器中运行的脚本的屏幕截图,显示运行期间 $computers 的值:调试运行屏幕截图

4

1 回答 1

1

当您通过管道将对象传递给函数时,一次只传递一个对象 - 而不是整个数组。所以你不需要foreach循环,也不需要$computers在函数中创建一个数组。

此外,当您拥有管道功能时,您应该使用begin,processend关键字。每个表示一个脚本块 -begin是一个执行一次的脚本块(当管道“设置”时),process是要为通过管道传递的每个对象执行的脚本块,end就像begin它只在最后一个项目之后运行通过传递。

所以至少,你的功能应该是这样的:

function Get-LocalAdministrators
{
    param(
    [Parameter(Mandatory=$True,Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
    [string]$computer
    )
process{
$ADMINS = get-wmiobject -computername $computername -query "select * from win32_groupuser where GroupComponent=""Win32_Group.Domain='$computername',Name='administrators'""" | % {$_.partcomponent}
# Do other stuff here
}
}

MSDN 文档说(这在get-help about_functions- 比这更多):

管道对象到函数
任何函数都可以从管道中获取输入。您可以使用 Begin、Process 和 End 关键字来控制函数如何处理来自管道的输入。以下示例语法显示了三个关键字:

      function <name> { 
          begin {<statement list>}
          process {<statement list>}
          end {<statement list>}
      }

  The Begin statement list runs one time only, at the beginning of 
  the function.  

  The Process statement list runs one time for each object in the pipeline.
  While the Process block is running, each pipeline object is assigned to 
  the $_ automatic variable, one pipeline object at a time. 

  After the function receives all the objects in the pipeline, the End 
  statement list runs one time. If no Begin, Process, or End keywords are 
  used, all the statements are treated like an End statement list.

编辑:在看到 OP 添加的完整代码后,这行得通。请注意,如上所述,我已对您的代码进行了更改。

function Get-LocalAdministrators 
{
    param(
        [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        [string]$computer
    )

    process{
        $ADMINS = get-wmiobject -computername $computer -query "select * from win32_groupuser where GroupComponent=""Win32_Group.Domain='$computer',Name='administrators'""" | % {$_.partcomponent}

        foreach ($ADMIN in $ADMINS) 
        {
            $admin = $admin.replace("\\$computername\root\cimv2:Win32_UserAccount.Domain=","") # trims the results for a user
            $admin = $admin.replace("\\$computername\root\cimv2:Win32_Group.Domain=","") # trims the results for a group
            $admin = $admin.replace('",Name="',"\")
            $admin = $admin.REPLACE("""","") # strips the last "

            $objOutput = New-Object PSObject -Property @{
                Machinename = $($computer)
                Fullname = ($admin)
                #DomainName  =$admin.split("\")[0]
                #UserName = $admin.split("\")[1]
            }

        $objReport+=@($objOutput)
        }

        $objReport
    }
}
于 2013-07-11T21:10:53.830 回答