0

I'm looking to do the Following Steps:

  • Reading in a CSV File
    • Add The Contents from the CSV File to An Array
  • Compare the Contents from the CSV with the Contents from another Array
  • If the Items in the Array aren't members of the CSV Array
    • Send Email

I First Tried Running the Script with One Host Missing from the Reports2 CSV File, This Missing Host was displayed to the Console and Written to the Reports2 File, but Still when i Re-Run the Code it still displays the last Element (Host that was Missing From Reports2.CSV):

This is the script I'm currently working On:

EDIT: I have now edited the code snippet to reflect the working solution

$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
n_foley
  • 13
  • 4

2 Answers2

1

You should instantiate your array containing the results as an empty array, probably before ForEach-Object -Process {... with $MaitanceMode = @() and when you want to add elements to it, replace this line:

$MaitanceMode = $esx | select name

by

$MaitanceMode += $esx | select name

Edit:

Further replace this line:

$esxiHosts = Import-CSV C:\Scripts\Report2.csv

by this line:

$esxiHosts = Import-CSV C:\Scripts\Report2.csv | Select-Object -ExpandProperty Name

and this line:

$MaitanceMode += $esx | select name

by this line:

$MaitanceMode += $esx | Select-Object -ExpandProperty Name

And don't forget to instantiate $MaitanceMode as an empty array. This is now mandatory. Otherwise it will become a string and not an array.

stackprotector
  • 10,498
  • 4
  • 35
  • 64
1

Despite the accepted answer from @Thomas, it is not correct to use the increase assignment operator (+=) to create a collection in PowerShell. For one thing, it is a very expensive syntax.
see: Why should I avoid using the increase assignment operator (+=) to create a collection.

To build a collection of objects in PowerShell, you should use the PowerShell pipeline by removing the <variable> += of the concerned commands (this will leave the objects on the pipeline) and catch the whole collection by adding <variable> = in front of the iterator (e.g. Foreach-Object). By using this PowerShell syntax, there is no need to initiate the arrays (<variable> = @()).
Taking your script as an example:

$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
iRon
  • 20,463
  • 10
  • 53
  • 79