Need some help with below tasks:
1. Email Report (csv) a list of VMs - includes parameters CpuHotAddEnabled, MemoryHotAddEnabled, MemoryReservationLockedToMax, VMHost, VMFolderPath, IP Address, OS
2. Exclude Virtual Machines in specific Folders (Parent and it's child folders including) - Folder type VM
Below is what I have for now, but don't understand how to go via Folder and exclude specific.
#Initialize PowerCLI
Import-Module vmware.powercli
# Farm Login
$vCUser = 'username'
$vCPass = 'password'
# LIST OF FARM
$vCenterIP = "vCenter-1 IP"
foreach ($IPAddress in $vCenterIP){
# Connessione a vCenter
Connect-VIServer $IPAddress -User $vCUser -Password $vCPass -port 443
}
#Variables
$Date = get-date
$Datefile = ( get-date ).ToString('yyyy-MM-dd-hhmmss')
$ErrorActionPreference = "SilentlyContinue"
# Variable to change
$CreateCSV= "yes"
$GridView = "no"
$SendEmail = "yes"
$FileCSV = New-Item -type file "C:\Report\VMwareHotAdd_$datefile.csv"
Write-Host "Gathering VM statistics"
$report = @()
foreach($vm in Get-View -ViewType Virtualmachine) {
$vms = "" | Select-Object VMName,VMHost,VMState,CPUHotAdd,MemoryHotAdd,MemoryReservationLockedToMax,Hostname,IPAddress,OS
$vms.VMName = $vm.Name
$vms.VMState = $vm.summary.runtime.powerState
$vms.OS = $vm.Config.GuestFullName
$vms.Hostname = $vm.guest.hostname
$vms.IPAddress = $vm.Guest.Net.IpAddress -join ' , '
$vms.VMHost = Get-View -Id $vm.Runtime.Host -property Name | select -ExpandProperty Name
$vms.CPUHotAdd = $vm.Config.CpuHotAddEnabled
$vms.MemoryHotAdd = $vm.Config.MemoryHotAddEnabled
$vms.MemoryReservationLockedToMax = $vm.Config.MemoryReservationLockedToMax
$Report += $vms
}
#Output
if ($GridView -eq "yes") {
$report | Out-GridView }
if ($CreateCSV -eq "yes") {
$report | Export-Csv $FileCSV -NoTypeInformation }
#file CSV
$filename = "C:\Report\VMwareHotAdd_$datefile.csv"
$smtpServer = “email”
$msg = new-object Net.Mail.MailMessage
$att = new-object Net.Mail.Attachment($filename)
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = "email"
$msg.To.Add("email")
$msg.Subject = "Weekly Report - / VMware Virtual Machine Hot Add CSV - $Date"
$msg.Body = "Please find attached Weekly report of Virtual Machine Hot Add Status"
$msg.Attachments.Add($att)
$smtp.Send($msg)
#Disconnect session from VC
Disconnect-VIserver -Confirm:$false
Try like this
$vms = "" | Select-Object VMName,VMHost,VMState,Folder,CPUHotAdd,MemoryHotAdd,MemoryReservationLockedToMax,Hostname,IPAddress,OS
$vms.VMName = $vm.Name
$vms.VMState = $vm.summary.runtime.powerState
$vms.OS = $vm.Config.GuestFullName
$vms.Hostname = $vm.guest.hostname
$vms.IPAddress = $vm.Guest.Net.IpAddress -join ' , '
$vms.VMHost = Get-View -Id $vm.Runtime.Host -property Name | select -ExpandProperty Name
$vms.CPUHotAdd = $vm.Config.CpuHotAddEnabled
$vms.MemoryHotAdd = $vm.Config.MemoryHotAddEnabled
$vms.MemoryReservationLockedToMax = $vm.Config.MemoryReservationLockedToMax
$vms.Folder = (Get-View -Id $vm.Parent -Property Name).Name
$Report += $vms
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Looks like task 1 is already ok.
For task 2, how do you intend to provide the folders to be excluded?
Just the folder name or the full path?
When just the folder name, can the same name be used for multiple folders?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I see all Parent and Respective child folders are unique, so just a folder name should work fine.
Will prefer just folder name - something with below workflow for exclusion would be great:
1. If Folder Name is a Parent, exclude child as well.
2. If Folder Name is Child, applicable only to that folder.
I see all Parent and Respective child folders are unique, so just a folder name should work fine.
Will prefer just folder name - something with below workflow for exclusion would be great:
1. If Folder Name is a Parent, exclude child as well.
2. If Folder Name is Child, applicable only to that folder.
Just want to add, as we are focusing on Folder Exclusions, there are some VMs with no folder under datacenter, those will also be required in the report.
You could do something like this
$rootFolder = Get-View -ViewType Folder -Property Name -Filter @{Name=$folderName}
$excludeFolders = @($rootFolder.MoRef.Value)
$childFolders = (Get-View -ViewType Folder -SearchRoot $rootFolder.MoRef).MoRef.Value
if($childFolders){
$excludeFolders += $childFolders
}
$regEx = "^((?!$($excludeFolders -join '|')).)*$"
Get-View -ViewType VirtualMachine -Filter @{'Parent'=$regEx}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Just tried this, getting below error:
PS C:\Windows\system32> $childFolders = (Get-View -ViewType Folder -SearchRoot $rootFolder.MoRef).MoRef.Value
if($childFolders) {
$excludeFolders += $childFolders
}
$regEx = "^((?!$($excludeFolders -join '|')).)*$"
Get-View : Cannot convert 'System.Object[]' to the type 'VMware.Vim.ManagedObjectReference'
required by parameter 'SearchRoot'. Specified method is not supported.
At line:1 char:56
+ ... rs = (Get-View -ViewType Folder -SearchRoot $rootFolder.MoRef).MoRef. ...
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-View], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,VMware.VimAutomation.ViCore.Cmdlets.Commands.
DotNetInterop.GetVIView
Did you add more than one name to the $folderName variable?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Attaching complete script as well, not sure if I merged it right.
#Initialize PowerCLI
Import-Module vmware.powercli
# Farm Login
$vCUser = 'username'
$vCPass = 'password'
# LIST OF FARM
$vCenterIP = "vCenter-1 IP"
foreach ($IPAddress in $vCenterIP){
# Connessione a vCenter
Connect-VIServer $IPAddress -User $vCUser -Password $vCPass -port 443
}
#Variables
$Date = get-date
$Datefile = ( get-date ).ToString('yyyy-MM-dd-hhmmss')
$ErrorActionPreference = "SilentlyContinue"
# Variable to change
$CreateCSV= "no"
$GridView = "yes"
$SendEmail = "no"
$FileCSV = New-Item -type file "C:\Report\VMwareHotAdd_$datefile.csv"
Write-Host "Gathering VM statistics"
$report = @()
$folderName = 'Infrastructure'
$rootFolder = Get-View -ViewType Folder -Property Name -Filter @{Name=$folderName}
$excludeFolders = @($rootFolder.MoRef.Value)
$childFolders = (Get-View -ViewType Folder -SearchRoot $rootFolder.MoRef).MoRef.Value
if($childFolders){
$excludeFolders += $childFolders
}
$regEx = "^((?!$($excludeFolders -join '|')).)*$"
Get-View -ViewType VirtualMachine -Filter @{'Parent'=$regEx}
foreach($vm in Get-View -ViewType Virtualmachine) {
$vms = "" | Select-Object VMName,VMHost,VMState,CPUHotAdd,MemoryHotAdd,MemoryReservationLockedToMax,Hostname,IPAddress,OS
$vms.VMName = $vm.Name
$vms.VMState = $vm.summary.runtime.powerState
$vms.OS = $vm.Config.GuestFullName
$vms.Hostname = $vm.guest.hostname
$vms.IPAddress = $vm.Guest.Net.IpAddress -join ' , '
$vms.VMHost = Get-View -Id $vm.Runtime.Host -property Name | select -ExpandProperty Name
$vms.CPUHotAdd = $vm.Config.CpuHotAddEnabled
$vms.MemoryHotAdd = $vm.Config.MemoryHotAddEnabled
$vms.MemoryReservationLockedToMax = $vm.Config.MemoryReservationLockedToMax
$Report += $vms
}
#Output
if ($GridView -eq "yes") {
$report | Out-GridView }
if ($CreateCSV -eq "yes") {
$report | Export-Csv $FileCSV -NoTypeInformation }
#file CSV
$filename = "C:\Report\VMwareHotAdd_$datefile.csv"
$smtpServer = “email”
$msg = new-object Net.Mail.MailMessage
$att = new-object Net.Mail.Attachment($filename)
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = "email"
$msg.To.Add("email")
$msg.Subject = "Weekly Report - / VMware Virtual Machine Hot Add CSV - $Date"
$msg.Body = "Please find attached Weekly report of Virtual Machine Hot Add Status"
$msg.Attachments.Add($att)
$smtp.Send($msg)
#Disconnect session from VC
Disconnect-VIserver -Confirm:$false
No, Tried just 1 folder name for testing. Can it take multiple values?
Then it looks as if there is more than 1 folder with that name
To take multiple values, the code needs to be changed slightly.
$excludeFolders = @()
$folderName |
ForEach-Object -Process {
$rootFolder = Get-View -ViewType Folder -Property Name -Filter @{Name=$_}
$excludeFolders += @($rootFolder.MoRef.Value)
$childFolders = (Get-View -ViewType Folder -SearchRoot $rootFolder.MoRef).MoRef.Value
if($childFolders){
$excludeFolders += $childFolders
}
}
$regEx = "^((?!$($excludeFolders -join '|')).)*$"
Get-View -ViewType VirtualMachine -Filter @{'Parent'=$regEx}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I see only single folder with that name:
PS C:\Windows\system32> get-folder -Name Infrastructure
Name Type
---- ----
Infrastructure VM
And this?
Get-View -ViewType Folder -Property Name -Filter @{Name=$folderName}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Looks like new code is working, will share a final word and script in sometime.
Here is the output. Looks like it is taking all folders with same first name.
PS C:\Windows\system32> $folderName = 'Infrastructure'
Get-View -ViewType Folder -Property Name -Filter @{Name=$folderName}
Name : Infrastructure
ChildType :
ChildEntity :
LinkedView :
Parent :
CustomValue :
OverallStatus : gray
ConfigStatus : gray
ConfigIssue :
EffectiveRole :
Permission :
DisabledMethod :
RecentTask :
DeclaredAlarmState :
TriggeredAlarmState :
AlarmActionsEnabled : False
Tag :
Value :
AvailableField :
MoRef : Folder-group-v10918
Client : VMware.Vim.VimClientImpl
Name : INFRASTRUCTURE TRIBE
ChildType :
ChildEntity :
LinkedView :
Parent :
CustomValue :
OverallStatus : gray
ConfigStatus : gray
ConfigIssue :
EffectiveRole :
Permission :
DisabledMethod :
RecentTask :
DeclaredAlarmState :
TriggeredAlarmState :
AlarmActionsEnabled : False
Tag :
Value :
AvailableField :
MoRef : Folder-group-v4781
Client : VMware.Vim.VimClientImpl
No problem, we can fix that by adapting the RegEx expression
$excludeFolders = @()
$folderName |
ForEach-Object -Process {
$rootFolder = Get-View -ViewType Folder -Property Name -Filter @{Name="^$_$"}
$excludeFolders += @($rootFolder.MoRef.Value)
$childFolders = (Get-View -ViewType Folder -SearchRoot $rootFolder.MoRef).MoRef.Value
if($childFolders){
$excludeFolders += $childFolders
}
}
$regEx = "^((?!$($excludeFolders -join '|')).)*$"
Get-View -ViewType VirtualMachine -Filter @{'Parent'=$regEx}
I noticed in your previous code that you still had your original Get-View foreach loop.
The idea is that the Get-View in there is replaced by this Get-View.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
RegEx and Get-View updated in script as suggested. It worked with no issues but output is showing VMs from Child Folders under 'Infrastructure'.
Strange, works for me.
Can you post your current code?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
#Initialize PowerCLI
Import-Module vmware.powercli
# Farm Login
$vCUser = 'username'
$vCPass = 'password'
# LIST OF FARM
$vCenterIP = "vCenter-1 IP"
foreach ($IPAddress in $vCenterIP){
# Connessione a vCenter
Connect-VIServer $IPAddress -User $vCUser -Password $vCPass -port 443
}
#Variables
$Date = get-date
$Datefile = ( get-date ).ToString('yyyy-MM-dd-hhmmss')
$ErrorActionPreference = "SilentlyContinue"
# Variable to change
$CreateCSV= "no"
$GridView = "yes"
$SendEmail = "no"
$FileCSV = New-Item -type file "C:\Report\VMwareHotAdd_$datefile.csv"
Write-Host "Gathering VM statistics"
$report = @()
$folderName = 'Infrastructure'
$excludeFolders = @()
$folderName |
ForEach-Object -Process {
$rootFolder = Get-View -ViewType Folder -Property Name -Filter @{Name="^$_$"}
$excludeFolders += @($rootFolder.MoRef.Value)
$childFolders = (Get-View -ViewType Folder -SearchRoot $rootFolder.MoRef).MoRef.Value
if($childFolders){
$excludeFolders += $childFolders
}
}
$regEx = "^((?!$($excludeFolders -join '|')).)*$"
foreach($vm in Get-View -ViewType VirtualMachine -Filter @{'Parent'=$regEx}) {
$vms = "" | Select-Object VMName,VMHost,VMState,CPUHotAdd,MemoryHotAdd,MemoryReservationLockedToMax,Hostname,IPAddress,OS
$vms.VMName = $vm.Name
$vms.VMState = $vm.summary.runtime.powerState
$vms.OS = $vm.Config.GuestFullName
$vms.Hostname = $vm.guest.hostname
$vms.IPAddress = $vm.Guest.Net.IpAddress -join ' , '
$vms.VMHost = Get-View -Id $vm.Runtime.Host -property Name | select -ExpandProperty Name
$vms.CPUHotAdd = $vm.Config.CpuHotAddEnabled
$vms.MemoryHotAdd = $vm.Config.MemoryHotAddEnabled
$vms.MemoryReservationLockedToMax = $vm.Config.MemoryReservationLockedToMax
$Report += $vms
}
#Output
if ($GridView -eq "yes") {
$report | Out-GridView }
if ($CreateCSV -eq "yes") {
$report | Export-Csv $FileCSV -NoTypeInformation }
#file CSV
$filename = "C:\Report\VMwareHotAdd_$datefile.csv"
$smtpServer = “email”
$msg = new-object Net.Mail.MailMessage
$att = new-object Net.Mail.Attachment($filename)
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = "email"
$msg.To.Add("email")
$msg.Subject = "Weekly Report - / VMware Virtual Machine Hot Add CSV - $Date"
$msg.Body = "Please find attached Weekly report of Virtual Machine Hot Add Status"
$msg.Attachments.Add($att)
$smtp.Send($msg)
#Disconnect session from VC
Disconnect-VIserver -Confirm:$false
I tried in a different powershell session, it's working ok now, might be some cached variable causing Child Folder VMs to appear.
One more thing, how can we add FOLDER NAME Column in the report?
Try like this
$vms = "" | Select-Object VMName,VMHost,VMState,Folder,CPUHotAdd,MemoryHotAdd,MemoryReservationLockedToMax,Hostname,IPAddress,OS
$vms.VMName = $vm.Name
$vms.VMState = $vm.summary.runtime.powerState
$vms.OS = $vm.Config.GuestFullName
$vms.Hostname = $vm.guest.hostname
$vms.IPAddress = $vm.Guest.Net.IpAddress -join ' , '
$vms.VMHost = Get-View -Id $vm.Runtime.Host -property Name | select -ExpandProperty Name
$vms.CPUHotAdd = $vm.Config.CpuHotAddEnabled
$vms.MemoryHotAdd = $vm.Config.MemoryHotAddEnabled
$vms.MemoryReservationLockedToMax = $vm.Config.MemoryReservationLockedToMax
$vms.Folder = (Get-View -Id $vm.Parent -Property Name).Name
$Report += $vms
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference