VMware Cloud Community
MandeepJ
Enthusiast
Enthusiast
Jump to solution

Report Hot Add VMs

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

Tags (1)
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try like this

foreach($vm in Get-View -ViewType VirtualMachine -Filter @{'Parent'=$regEx}) {  

    $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

View solution in original post

20 Replies
LucD
Leadership
Leadership
Jump to solution

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

0 Kudos
MandeepJ
Enthusiast
Enthusiast
Jump to solution

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.

0 Kudos
MandeepJ
Enthusiast
Enthusiast
Jump to solution

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.

LucD
Leadership
Leadership
Jump to solution

You could do something like this

$folderName = 'ExcludeFolder'

$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

0 Kudos
MandeepJ
Enthusiast
Enthusiast
Jump to solution

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

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you add more than one name to the $folderName variable?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
MandeepJ
Enthusiast
Enthusiast
Jump to solution

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

MandeepJ
Enthusiast
Enthusiast
Jump to solution

No, Tried just 1 folder name for testing. Can it take multiple values?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Then it looks as if there is more than 1 folder with that name

Get-Folder -Name 'Infrastructure'


To take multiple values, the code needs to be changed slightly.

$folderName = 'MyFolder1','MyFolder2'

$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

0 Kudos
MandeepJ
Enthusiast
Enthusiast
Jump to solution

I see only single folder with that name:

PS C:\Windows\system32> get-folder -Name Infrastructure

Name                           Type          

----                           ----          

Infrastructure                 VM            

0 Kudos
LucD
Leadership
Leadership
Jump to solution

And this?

$folderName = 'Infrastructure'

Get-View -ViewType Folder -Property Name -Filter @{Name=$folderName}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
MandeepJ
Enthusiast
Enthusiast
Jump to solution

Looks like new code is working, will share a final word and script in sometime.

0 Kudos
MandeepJ
Enthusiast
Enthusiast
Jump to solution

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

0 Kudos
LucD
Leadership
Leadership
Jump to solution

No problem, we can fix that by adapting the RegEx expression

$folderName = 'MyFolder1','MyFolder2'

$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

0 Kudos
MandeepJ
Enthusiast
Enthusiast
Jump to solution

RegEx and Get-View updated in script as suggested. It worked with no issues but output is showing VMs from Child Folders under 'Infrastructure'.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Strange, works for me.

Can you post your current code?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
MandeepJ
Enthusiast
Enthusiast
Jump to solution

#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

MandeepJ
Enthusiast
Enthusiast
Jump to solution

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?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try like this

foreach($vm in Get-View -ViewType VirtualMachine -Filter @{'Parent'=$regEx}) {  

    $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