Arrays 如何将cmdlet的输出添加到数组?
我正在尝试确定我们的Windows服务器上是否安装了特定的Windows修补程序。我对PowerShell脚本非常陌生,到目前为止,我已经掌握了以下内容:Arrays 如何将cmdlet的输出添加到数组?,arrays,powershell,Arrays,Powershell,我正在尝试确定我们的Windows服务器上是否安装了特定的Windows修补程序。我对PowerShell脚本非常陌生,到目前为止,我已经掌握了以下内容: $servers = Get-ADComputer -Filter {(OperatingSystem -like "Windows Server 2019*") -and (enabled -ne $false)} -Property * $result = @() ForEach ($item in $servers) { $te
$servers = Get-ADComputer -Filter {(OperatingSystem -like "Windows Server 2019*") -and (enabled -ne $false)} -Property *
$result = @()
ForEach ($item in $servers) {
$testhotfix = Get-HotFix -Id KB4534310,KB4534314,KB4534283,KB4534288,KB4534297,KB4534309,KB4534271,KB4534273 -ComputerName $item.Name | `
select $item.Name,$item.CanonicalName,$item.OperatingSystem
$result += $testhotfix
}
$result | Export-Csv -Path C:\Users\user1\Desktop\Servers.csv -NoTypeInformation
创建的CSV文件包含一行我要查找的信息,后面是几行逗号,如下所示:
“SERVER1”、“somedomain.com/Servers/Non-Prod/New\u Server\u Staging/SERVER1”、“Windows Server 2019标准”
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,,
,
我们有几个服务器,其中至少安装了一个修补程序。如何将每个服务器添加到$result数组中
谢谢总的来说:
选择$item.Name、$item.CanonicalName、$item.OperatingSystem
应该是:
选择名称、规范名称、操作系统
也就是说,您需要传递属性名称(例如,名称
),而不是当前输入对象的属性值(例如,$item.Name
)到选择
(cmdlet)
净效果是,Select Object
创建自定义对象,这些对象的属性(错误地)以属性值命名,并且它们本身没有值,因为输入对象没有此类属性。
这解释了您看到的输出
然而,更大的问题是,即使这样也不行,因为属性名称与$item
对象相关,而不是与获取修补程序输出的对象相关,这些对象是选择
操作的对象。
事实证明,您真正需要的是使用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
- 您可以完全省略
,并依赖于PowerShell的隐式到布尔转换,其中任何非零数的计算结果都是0-eq
(有关所有规则的摘要,请参阅的底部部分)$true
- 如果您想测试正在安装的所有指定修补程序,请将
替换为0-ne
$hotfixIds.Count-eq
- 如果您想测试正在安装的所有指定修补程序,请将
可使未安装任何指定修补程序的计算机的错误静音;您可以随后检查自动-ErrorAction SilentlyContinue
集合,或使用$Error
收集变量-ErrorVariable err
中的所有命令特定错误$err
针对不同场景的解决方案,也可能会引起兴趣: 如果希望将
获取修补程序的属性
输出对象与$item
对象的属性组合(表示手头的计算机):
以下命令:
- 从
输出对象中选择所有属性(获取修补程序
)-Property*
- 使用添加当前
中感兴趣的属性$item
-Exclude Name
将Name
属性从输入对象中排除(Get HotFix
具有此属性但为空的输出对象),因此可以将Name
添加为包含计算机名称的属性
至于你尝试了什么: 除了上面提到的
Select Object
属性名问题外,您的主要问题是希望管道段作为条件,而不是管道的工作方式:
Get HotFix…|选择…
上述操作只是将Get HotFix
的输出对象发送到select
(select Object
),然后无条件地处理它们(如上所述,在这些对象上查找具有给定名称的属性)
现在,如果Get HotFix
没有生成任何输出,那么条件逻辑将隐式应用:select
命令将不会被调用
相反,如果Get HotFix
生成多个输出,则会对每个输出调用select
也就是说,如果我们天真地试图纠正您的命令:
Get HotFix…|选择…
致:
Get HotFix…| ForEach对象{$item | select…}
您可能会在每台计算机上创建多个输出对象,也就是说,当一台给定的计算机碰巧安装了多个热修复程序时
简化版的(已更正)命令: 您的命令可以简化为仅使用单个管道,而不需要辅助变量:
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+现在还允许将
放在下一行的开头|
- PowerShell[Core]v7.0+现在还允许将
- 使用单引号字符串(
)而不是脚本块(“…”
)来传递{…}
参数,因为tt最好使用-Filter
- 使用
创建的输出自定义对象实例直接发送到管道$item | select Name、CanonicalName、OperatingSystem
选择$item.Name、$item.CanonicalName、$item.OperatingSystem
应该是:
选择名称、规范名称、操作系统
也就是说,您需要传递属性名称(例如,Name
),而不是当前输入对象的属性
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
$array = foreach($item in $obj)
{
[PSCustomObject]@{
Name = $item.Name
CanonicalName = $item.CanonicalName
OS = $item.OperatingSystem
}
}