VMware Cloud Community
tekhie
Contributor
Contributor

Function to filter by VM Notes

hi everyone - i am trying to create a function that will allow me to filter out vm's by a value that is defined in the notes section on each vm. As i have no VC i cannot use the custom fields which i have been able to get working ok. i have copied the code below but it does not seem to work. what i want to do is run the function with a value after it. the VM's with that same value are then returned to another variable - can anyone help advise what i need to change ?

function Filter-VMbyNotes {

param ($val)

foreach ($vm in $vmlist) {

$cf = $_

if ($_.Description -eq $val){

return $vm.name

}

}

}

Tags (3)
Reply
0 Kudos
12 Replies
LucD
Leadership
Leadership

If you want to use the function as a filter (in a pipeline), you have to use the process block.

Like this

function Filter-VMbyNotes {
	param ($val)

	process{
		if ($_.Description -match $val){
			return $_
		}
	}
} 

A sample run could be

Get-vm | Filter-VMbyNotes "myText"

____________

Blog: LucD notes

Twitter: lucd22


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

RvdNieuwendijk
Leadership
Leadership

You can even do this shorter by using a filter instead of a function. A filter is like a function with only the process block:

filter Filter-VMbyNotes {
  param ($val)

  if ($_.Description -match $val){return $_}
} 

Regards, Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
LucD
Leadership
Leadership

Your definition of a filter is imho not correct.

A filter is a function with at least a Process block.

See also Developing Genuine Pipeline Functions where Tobias explains it much better then I could.

____________

Blog: LucD notes

Twitter: lucd22


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

Reply
0 Kudos
RvdNieuwendijk
Leadership
Leadership

Luc you are right. I didn't know this but you can use the begin, process and end script blocks in a filter also. As I just tried this with the following function:

filter Filter-VMbyNotes {
  param ($val)
  begin {"filter begin"}
  process {if ($_.Description -match $val){return $_}}
  end {"filter end"} 
} 

The "official" definition of a filter by Bruce Payette,[Windows PowerShell in Action, Second Edition|http://www.manning.com/payette2/] page 254 is:

"Filters are a variation on the general concept of functions. Where a function in a pipeline runs once, a filter is run for each input object coming from the pipeline."

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
Reply
0 Kudos
tekhie
Contributor
Contributor

great - thanks guys for the info - the links were useful too Smiley Wink

Reply
0 Kudos
stuartgmilton
Enthusiast
Enthusiast

Could this be used to filter on custom fields??

Specifically, I'm looking to retrieve a list of all VMs which have not had a Project Reference filled in.

Reply
0 Kudos
LucD
Leadership
Leadership

Sure, what is the exact name of the custom field ?


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

Reply
0 Kudos
stuartgmilton
Enthusiast
Enthusiast

Theres 2 actually;

ProjectRef

&

ReportingGroup

If either or both is blank, we'd like the VM returned in the collection.

Many Thanks

Reply
0 Kudos
LucD
Leadership
Leadership

Try something like this

function Filter-VMCheckProject {

    process{

        if (!(Get-Annotation -Entity $_ -CustomAttribute ProjectRef).Value -or

                !(Get-Annotation -Entity $_ -CustomAttribute ReportingGroup).Value){

            return $_

        }

    }

}


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

Reply
0 Kudos
stuartgmilton
Enthusiast
Enthusiast

Super, thanks!

Reply
0 Kudos
stuartgmilton
Enthusiast
Enthusiast

Sorry, could this be used using Get-View, as I find its quicker than Get-VM?

We have about 700 VMs, so Get-VM takes a while.

Reply
0 Kudos
LucD
Leadership
Leadership

For a fast solution I would do something like this

$key1 = Get-CustomAttribute -Name ProjectRef | Select -ExpandProperty Key

$key2 = Get-CustomAttribute -Name ReportingGroup | Select -ExpandProperty Key

Get-View -ViewType VirtualMachine -Property Name,CustomValue |

where {$present = $_.CustomValue | %{$_.Key}; $present -notcontains $key1 -or $present -notcontains $key2} |

Select Name


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

Reply
0 Kudos