Разбор импорта CSV и итерации значений конвейера - PullRequest
0 голосов
/ 30 января 2019

У меня есть функция с именем 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 голосов
/ 30 января 2019

Re (a):

Если ваша функция видит @{computername=HOSTNAME} вместо HOSTNAME, это означает, что вы делаете что-то вроде:

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

вместоОбязательно:

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

Обратите внимание на переключатель -ExpandProperty, который необходим для извлечения отдельного свойства значение из входных данных;без него вы получите объект с этим свойством - подробности см. в этом ответе .


Re (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.

Обратите внимание, что если вы только ожидаете, что ваша функция получит список имен компьютеров через pipe (... | Get-InstalledApps), а не по параметру (Get-InstalledApps -Computers ...)), вы можете объявить параметр -Computers как просто [string] (а не как массив ), что устраняет необходимость в цикле foreach внутри блока process { ... }.
Дляобсуждение этой разницы, см. этот выпуск GitHub .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...