在 Powershell 中比较数组
Comparing Arrays within Powershell
我希望执行以下步骤:
- 正在读取 CSV 文件
- 将 CSV 文件中的内容添加到数组
- 将 CSV 中的内容与另一个数组中的内容进行比较
- 如果数组中的项目不是 CSV 数组的成员
- 发送电子邮件
我首先尝试 运行在 Reports2 CSV 文件中缺少一个主机的脚本,这个丢失的主机显示在控制台上并写入 Reports2 文件,但是当我重新 运行 它仍然显示最后一个元素的代码(Reports2.CSV 中缺少的主机):
这是我目前正在处理的脚本:
编辑:我现在已经编辑了代码片段以反映工作解决方案
$user = ''
$pswd = ''
$vCenter_Servers = ""
$now = Get-Date
$start = $now.AddDays(-15)
$esxiHosts = Import-CSV C:\Scripts\Report1.csv #Reading CSV File
$MaitanceMode = @()
$Ticket = @()
foreach($ESXI in $esxiHosts){
$Ticket += $ESXI | Select-Object -ExpandProperty Name
}
foreach($vCenter in $vCenter_Servers) {
$srv = Connect-VIServer -Server $vCenter -User $user -Password $pswd
Get-VMHost -PipelineVariable esx -Server $srv | Where-Object {$_.ConnectionState -eq 'Maintenance'} |
ForEach-Object -Process {
$maintEntered = Get-VIEvent -Entity $esx -Start $start -MaxSamples ([int]::MaxValue) -Server $srv |
Where-Object{$_ -is [VMware.Vim.EnteredMaintenanceModeEvent]}
if($maintEntered){
#Skipping
}
else {
$MaitanceMode += $esx | Select-Object -ExpandProperty Name
}
}
} #Ending ForEach Loop
$NoTicket = $MaitanceMode | Where {$Ticket -Contains $_}
$NoTicket
您应该将包含结果的数组实例化为一个空数组,可能在 ForEach-Object -Process {...
之前使用 $MaitanceMode = @()
并且当您想要向其中添加元素时,将此行替换为:
$MaitanceMode = $esx | select name
来自
$MaitanceMode += $esx | select name
编辑:
进一步替换这一行:
$esxiHosts = Import-CSV C:\Scripts\Report2.csv
通过这条线:
$esxiHosts = Import-CSV C:\Scripts\Report2.csv | Select-Object -ExpandProperty Name
这行:
$MaitanceMode += $esx | select name
通过这条线:
$MaitanceMode += $esx | Select-Object -ExpandProperty Name
并且不要忘记将 $MaitanceMode
实例化为一个空数组。现在这是强制性的。否则它将变成一个字符串而不是一个数组。
尽管 @Thomas 接受了答案,但在 PowerShell 中使用递增赋值运算符 (+=
) 创建集合 不 正确。一方面,这是一种非常昂贵的语法。
参见:.
要在 PowerShell 中构建对象集合,您应该通过删除相关命令的 <variable> +=
来使用 PowerShell 管道(这会将对象留在管道上)并通过添加 <variable> =
在迭代器前面(例如 Foreach-Object
)。通过使用此 PowerShell 语法,无需启动数组 (<variable> = @()
).
以你的脚本为例:
$user = ''
$pswd = ''
$vCenter_Servers = ""
$now = Get-Date
$start = $now.AddDays(-15)
$esxiHosts = Import-CSV C:\Scripts\Report1.csv #Reading CSV File
$Ticket = foreach($ESXI in $esxiHosts){
$ESXI | Select-Object -ExpandProperty Name
}
foreach($vCenter in $vCenter_Servers) {
$srv = Connect-VIServer -Server $vCenter -User $user -Password $pswd
Get-VMHost -PipelineVariable esx -Server $srv | Where-Object {$_.ConnectionState -eq 'Maintenance'} |
$MaitanceMode = ForEach-Object -Process {
$maintEntered = Get-VIEvent -Entity $esx -Start $start -MaxSamples ([int]::MaxValue) -Server $srv |
Where-Object{$_ -is [VMware.Vim.EnteredMaintenanceModeEvent]}
if($maintEntered){
#Skipping
}
else {
$esx | Select-Object -ExpandProperty Name
}
}
} #Ending ForEach Loop
$NoTicket = $MaitanceMode | Where {$Ticket -Contains $_}
$NoTicket
我希望执行以下步骤:
- 正在读取 CSV 文件
- 将 CSV 文件中的内容添加到数组
- 将 CSV 中的内容与另一个数组中的内容进行比较
- 如果数组中的项目不是 CSV 数组的成员
- 发送电子邮件
我首先尝试 运行在 Reports2 CSV 文件中缺少一个主机的脚本,这个丢失的主机显示在控制台上并写入 Reports2 文件,但是当我重新 运行 它仍然显示最后一个元素的代码(Reports2.CSV 中缺少的主机):
这是我目前正在处理的脚本:
编辑:我现在已经编辑了代码片段以反映工作解决方案
$user = ''
$pswd = ''
$vCenter_Servers = ""
$now = Get-Date
$start = $now.AddDays(-15)
$esxiHosts = Import-CSV C:\Scripts\Report1.csv #Reading CSV File
$MaitanceMode = @()
$Ticket = @()
foreach($ESXI in $esxiHosts){
$Ticket += $ESXI | Select-Object -ExpandProperty Name
}
foreach($vCenter in $vCenter_Servers) {
$srv = Connect-VIServer -Server $vCenter -User $user -Password $pswd
Get-VMHost -PipelineVariable esx -Server $srv | Where-Object {$_.ConnectionState -eq 'Maintenance'} |
ForEach-Object -Process {
$maintEntered = Get-VIEvent -Entity $esx -Start $start -MaxSamples ([int]::MaxValue) -Server $srv |
Where-Object{$_ -is [VMware.Vim.EnteredMaintenanceModeEvent]}
if($maintEntered){
#Skipping
}
else {
$MaitanceMode += $esx | Select-Object -ExpandProperty Name
}
}
} #Ending ForEach Loop
$NoTicket = $MaitanceMode | Where {$Ticket -Contains $_}
$NoTicket
您应该将包含结果的数组实例化为一个空数组,可能在 ForEach-Object -Process {...
之前使用 $MaitanceMode = @()
并且当您想要向其中添加元素时,将此行替换为:
$MaitanceMode = $esx | select name
来自
$MaitanceMode += $esx | select name
编辑:
进一步替换这一行:
$esxiHosts = Import-CSV C:\Scripts\Report2.csv
通过这条线:
$esxiHosts = Import-CSV C:\Scripts\Report2.csv | Select-Object -ExpandProperty Name
这行:
$MaitanceMode += $esx | select name
通过这条线:
$MaitanceMode += $esx | Select-Object -ExpandProperty Name
并且不要忘记将 $MaitanceMode
实例化为一个空数组。现在这是强制性的。否则它将变成一个字符串而不是一个数组。
尽管 @Thomas 接受了答案,但在 PowerShell 中使用递增赋值运算符 (+=
) 创建集合 不 正确。一方面,这是一种非常昂贵的语法。
参见:
要在 PowerShell 中构建对象集合,您应该通过删除相关命令的 <variable> +=
来使用 PowerShell 管道(这会将对象留在管道上)并通过添加 <variable> =
在迭代器前面(例如 Foreach-Object
)。通过使用此 PowerShell 语法,无需启动数组 ( ).<variable> = @()
以你的脚本为例:
$user = ''
$pswd = ''
$vCenter_Servers = ""
$now = Get-Date
$start = $now.AddDays(-15)
$esxiHosts = Import-CSV C:\Scripts\Report1.csv #Reading CSV File
$Ticket = foreach($ESXI in $esxiHosts){
$ESXI | Select-Object -ExpandProperty Name
}
foreach($vCenter in $vCenter_Servers) {
$srv = Connect-VIServer -Server $vCenter -User $user -Password $pswd
Get-VMHost -PipelineVariable esx -Server $srv | Where-Object {$_.ConnectionState -eq 'Maintenance'} |
$MaitanceMode = ForEach-Object -Process {
$maintEntered = Get-VIEvent -Entity $esx -Start $start -MaxSamples ([int]::MaxValue) -Server $srv |
Where-Object{$_ -is [VMware.Vim.EnteredMaintenanceModeEvent]}
if($maintEntered){
#Skipping
}
else {
$esx | Select-Object -ExpandProperty Name
}
}
} #Ending ForEach Loop
$NoTicket = $MaitanceMode | Where {$Ticket -Contains $_}
$NoTicket