Вообще говоря:
select $item.Name,$item.CanonicalName,$item.OperatingSystem
должно быть:
select Name, CanonicalName, OperatingSystem
То есть вам нужно передать свойство names (например, Name
), а не свойство текущего входного объекта значения (например, $item.Name
) to select
(командлет Select-Object
).
Эффект net заключается в том, что Select-Object
создает пользовательские объекты, свойства которых (по ошибке) названы для свойства значения и сами по себе не имеют значения , учитывая, что входные объекты не имеют таких свойств. Это объясняет вывод, который вы видели.
Однако большая проблема в том, что даже это не сработает, учитывая, что имена свойств относятся к объекту $item
, а не к объектам, выводимым Get-HotFix
, то есть те, с которыми select
работает.
Как выясняется, вам действительно нужно использовать Get-HotFix
вызов как условное , чтобы записать строку CSV для компьютера под рукой, только если установлено хотя бы одно из указанных исправлений :
$hotfixIds = 'KB4534310', 'KB4534314', 'KB4534283', 'KB4534288', 'KB4534297', 'KB4534309', 'KB4534271', 'KB4534273'
if (0 -ne (Get-HotFix -ErrorAction SilentlyContinue -Id $hotfixIds -ComputerName $item.Name).Count) {
$result += $item | select Name, CanonicalName, OperatingSystem
}
Примечание:
Обратите внимание, что теперь $item
(компьютер под рукой) передается по каналу select
, чтобы обеспечить извлечение его свойств (в виде пользовательских объект с этими свойствами).
Вы можете вообще пропустить 0 -eq
и полагаться на неявное преобразование PowerShell в булево, где любое ненулевое число равно $true
(см. нижний раздел этого ответа для краткого изложения всех правил.
- Если вместо этого вы хотите проверить все указанных установленных исправлений, заменив
0 -ne
на $hotfixIds.Count -eq
.
-ErrorAction SilentlyContinue
, чтобы заставить ошибки замолчать с компьютеров, на которых нет указанных исправлений; затем вы можете проверить коллекцию automati c $Error
или использовать -ErrorVariable err
для сбора всех указанных в команде ошибок c в переменной $err
.
Кроме того, ваш Общая команда может быть значительно упрощена - см. нижний раздел.
Решение для другого сценария, которое также может представлять интерес:
Если вы требуемые до объединяют свойства из выходных объектов Get-HotFix
со свойствами из $item
объектов (представляющих компьютер под рукой):
Следующая команда:
- выбирает все свойства из
Get-HotFix
объектов вывода (-Property *
) - добавляет интересующие свойства из текущего
$item
, используя вычисленные свойства
# Additional 'KB...' values omitted for brevity.
Get-HotFix -Id KB4534310, KB4534314 -ComputerName $item.Name |
Select-Object -Exclude Name -Property *,
@{ n = 'Name'; e = { $item.Name } },
@{ n = 'CanonicalName'; e = { $item.CanonicalName } },
@{ n = 'OperatingSystem'; e = { $item.OperatingSystem } }
Обратите внимание, что -Exclude Name
исключает свойство Name
из входных объектов (Get-HotFix
выходные объекты, имеющие такое свойство , но это пусто ), так что Name
может быть добавлено как свойство co имя компьютера.
Что касается того, что вы пытались:
Помимо упомянутой выше проблемы с именем свойства Select-Object
, ваша главная проблема заключалась в том, что вы ожидали, что сегмент конвейера условный , который не работает как конвейеры:
Get-HotFix ... | select ...
Выше просто отправляет Get-HotFix
'* выходные данные объекты с по select
(Select-Object
), которые затем безоговорочно обрабатывают их (и, как уже говорилось, ищут свойства с данными именами в этих объектах ).
Теперь, если Get-HotFix
произвел no output, тогда условная логика c применяется неявно: команда select
тогда просто не будет вызываться.
И наоборот, если Get-HotFix
выдает несколько выходных данных, select
будет вызываться для каждого .
То есть, если мы наивно пытались исправить вашу команду из:
Get-HotFix ... | select ...
до:
Get-HotFix ... | ForEach-Object { $item | select ... }
вы могли бы потенциально создать несколько выходных объектов для каждого компьютера, а именно всякий раз, когда на конкретном компьютере установлено более одного установленного исправления.
Модернизированная версия Ваша (исправленная) команда:
Ваша команда может быть упрощена для использования только одного конвейера, без необходимости aux. переменные:
Get-ADComputer -Filter '(OperatingSystem -like "Windows Server 2019*") -and (enabled -ne $false)' -Property * |
ForEach-Object {
if (0 -ne (Get-HotFix -ErrorAction SilentlyContinue -ComputerName $item.Name -Id KB4534310,KB4534314,KB4534283,KB4534288,KB4534297,KB4534309,KB4534271,KB4534273).Count) {
$item | select Name, CanonicalName, OperatingSystem
}
} | Export-Csv -Path C:\Users\user1\Desktop\Servers.csv -NoTypeInformation
Примечание:
Если вы заканчиваете строку с |
, вы делаете не нужен трейлинг `
для сигнализации о продолжении линии.
- PowerShell [Core] v7.0 + теперь также позволяет помещать
|
в начале следующей строки .
Строка в одинарных кавычках ('...'
) используется вместо блока скрипта ({ ... }
) для передачи аргумента -Filter
, потому что tt лучше всего избегать использования блоков сценариев ({ ... }
) в качестве -Filter
аргументов .
Выходные экземпляры пользовательских объектов, созданные с помощью $item | select Name, CanonicalName, OperatingSystem
, отправляются непосредственно в конвейер .