解析导入的csv并迭代管道值

时间:2019-01-30 16:20:06

标签: powershell

我有一个名为Get-InstalledApps的函数,该函数连接到使用-computers参数列出的所有计算机,该函数通过管道接受输入。

将计算机名称传递给函数时有两个问题:

(a)我有一个可以传递给它的CSV文件,但是它解析这样的值:@{computername=HOSTNAME},而不只是HOSTNAME

(b)相反,当从Get-ADComputer -Filter *进行管道传输时,它只是获取上次传递的计算机名称。

这是我的职能:

function Get-InstalledApps {

    Param (

    [CmdletBinding()]

    [Parameter(ValueFromPipeline=$true)]

    [Alias('name')]

    [string[]]$computers = $env:COMPUTERNAME

    )

    foreach($computer in $computers){

        write-verbose -verbose -message "`nStarting scan on $computer"

        Invoke-Command -Computername $computer -ErrorAction SilentlyContinue -ErrorVariable InvokeError -Scriptblock  {

            $installPaths = @('HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall','HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall')

            Get-ChildItem -Path $installPaths | Get-ItemProperty | Sort-Object -Property DisplayName | Select-Object -Property DisplayName, DisplayVersion, Publisher, UninstallString, Version

        }

        if ($invokeerror){

                Write-Warning "Could not communicate with $computer"

        }

    }

}

更新:此问题已解决。这是那些想要的人的要点:

https://gist.github.com/TylerJWhit/f596c307cf87540842281a8a20149f9a

1 个答案:

答案 0 :(得分:0)

关于(a):

如果您的函数看到的是@{computername=HOSTNAME}而不是HOSTNAME,则表示您正在执行以下操作:

 Import-Csv ... | Select-Object ComputerName | Get-InstalledApps

代替必需的:

 Import-Csv ... | Select-Object -ExpandProperty ComputerName | Get-InstalledApps

请注意-ExpandProperty开关,这是从输入中提取单个属性 value 所必需的;没有它,您将获得具有该属性的对象-有关更多信息,请参见this answer


关于(b):

为了接受逐个对象管道输入,您的函数必须具有process { ... }块:

function Get-InstalledApps {
  Param (
    [CmdletBinding()]
    [Parameter(ValueFromPipeline=$true)]
    [Alias('name')]
    [string[]]$computers = $env:COMPUTERNAME
  )

  process {  # This ensures that the following code is called for each input object.
    foreach ($computer in $computers){
      # ...
    }
  }

}

请参见Get-Help about_Functions_Advanced

请注意,如果您只希望函数通过管道... | Get-InstalledApps)接收计算机名称列表,而不是通过 by参数({ {1}}),您可以将Get-InstalledApps -Computers ...参数声明为-Computers(而不是 array ),从而消除了内部[string]循环的需要foreach块。
有关这种差异的讨论,请参见this GitHub issue