Hi everyone,
I'm having some trouble pushing array results into an object, and then adding the object's members to an array. I've had success using the below method in the past, but I've only (previously) tried it with one cmdlet. In the example below, I am piping multiple cmdlets. Basically, $vms outputs fine, but I can't get any of the instantiated arrays to populate thereafter. The $mainArray always outputs as null in the email. Any ideas? I really don't want to put get-vievent in the foreach loop as it will really slow down the query.
Connect-viserver test.testdomain.com
$mainArray = @()
$userArray = @()
$timeArray = @()
$msgArray = @()
$CDT = Get-Date
$vms = Get-VM | Get-VIEvent -Types Info -Start $CDT.AddDays(-30) -Finish $CDT | Where { $_.Gettype().Name -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $_.Gettype().Name -eq "VmRegisteredEvent"} | Select UserName, CreatedTime, FullFormattedMessage | Format-Table -AutoSize
foreach ($vm in $vms)
{
$username = $vm.UserName
$createdTime = $vm.CreatedTime
$msg = $vm.FullFormattedMessage
$userArray += $username
$timeArray += $createdTime
$msgArray += $msg
}
For($i=0;$i -lt $userArray.Count;$i++)
{
$item = New-Object PSObject
$item | Add-Member -type NoteProperty -Name 'UserName' -Value $userArray[$i]
$item | Add-Member -type NoteProperty -Name 'Created Time' -Value $timeArray[$i]
$item | Add-Member -type NoteProperty -Name 'Message' -Value $msgArray[$i]
$mainArray += $item
}
$Head = @"
<style>
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
</style>
"@
#####begin send email section####
$comp = get-wmiobject win32_computersystem
$mailFrom = $comp.name
$FromAddr = $mailFrom + "@testdomain.com"
$ToAddr = "testuser@testdomain.com"
$Subject = "VMs created over last 30 days"
$SMTPServer = "smtp.testdomain.com"
$Body = $mainArray | ConvertTo-Html -head $Head | Out-String
Send-MailMessage -from $FromAddr -To $toAddr -Subject $Subject -Body ($body) -BodyasHtml -SmtpServer $SMTPServer
disconnect-viserver -confirm:$false
Why so complicated, the following should give the same result.
Connect-viserver test.testdomain.com
$mainArray = @()
$CDT = Get-Date
$mainArray = Get-VM | Get-VIEvent -Types Info -Start $CDT.AddDays(-3) -Finish $CDT | Where { $_.Gettype().Name -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $_.Gettype().Name -eq "VmRegisteredEvent"} |
Select @{N='UserName';E={$_.UserName}},
@{N='Created Time';E={$_.CreatedTime}},
@{N='Message';E={$_.FullFormattedMessage}}
$Head = @"
<style>
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
</style>
"@
#####begin send email section####
$comp = get-wmiobject win32_computersystem
$mailFrom = $comp.name
$FromAddr = $mailFrom + "@testdomain.com"
$ToAddr = "testuser@testdomain.com"
$Subject = "VMs created over last 30 days"
$SMTPServer = "smtp.testdomain.com"
$Body = $mainArray | ConvertTo-Html -head $Head | Out-String
Send-MailMessage -from $FromAddr -To $toAddr -Subject $Subject -Body ($body) -BodyasHtml -SmtpServer $SMTPServer
disconnect-viserver -confirm:$false
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Why so complicated, the following should give the same result.
Connect-viserver test.testdomain.com
$mainArray = @()
$CDT = Get-Date
$mainArray = Get-VM | Get-VIEvent -Types Info -Start $CDT.AddDays(-3) -Finish $CDT | Where { $_.Gettype().Name -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $_.Gettype().Name -eq "VmRegisteredEvent"} |
Select @{N='UserName';E={$_.UserName}},
@{N='Created Time';E={$_.CreatedTime}},
@{N='Message';E={$_.FullFormattedMessage}}
$Head = @"
<style>
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
</style>
"@
#####begin send email section####
$comp = get-wmiobject win32_computersystem
$mailFrom = $comp.name
$FromAddr = $mailFrom + "@testdomain.com"
$ToAddr = "testuser@testdomain.com"
$Subject = "VMs created over last 30 days"
$SMTPServer = "smtp.testdomain.com"
$Body = $mainArray | ConvertTo-Html -head $Head | Out-String
Send-MailMessage -from $FromAddr -To $toAddr -Subject $Subject -Body ($body) -BodyasHtml -SmtpServer $SMTPServer
disconnect-viserver -confirm:$false
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
THanks LucD, that works. I was doing it a more manual way because I wanted to display the header even if no data was returned. I suppose I could setup an if statement so if there are no results, return the header with a message about 0 results.
Curious though, any idea why my original script wasn't returning any results? It would return 5 blank rows with the header in the email.
Sure, it's the line where you collect the Events, you should not do the Format-Table at that point
$vms = Get-VM | Get-VIEvent -Types Info -Start $CDT.AddDays(-30) -Finish $CDT | Where { $_.Gettype().Name -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $_.Gettype().Name -eq "VmRegisteredEvent"} | Select UserName, CreatedTime, FullFormattedMessage
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Gah...I should have figured it would be that simple. Thanks for setting me straight.