VMware Cloud Community
houghtp
Contributor
Contributor

Get tools status - PowerGui

Hi,

I'm trying to run a a script via PowerGui to get the tools status. I've seen many posts on getting tools status and thought I was on the right lines - apparently not! The script runs if I run it using PowerGui script editor but the values for $_.config.tools.toolsVersion and $_.guest.toolsstatus are returned blank which leads me to believe I'm not accessing the VM's full properties correctly using get-view (hence my posting here not the PowerGui forum!!).

The error I get from PowerGui is

cannot bind argument to parameter 'Moref' becasue it is null

Also, I'm sure there must be more effecient ways to run this code using get-cluster and the pipeline rather than my way of using 'if statements' to ignore standalone VMHosts - so if anyone can point me in the right direction it would be much appreciated!!!

$AllVirtualMachines = Get-VM -Server $global:VIServer

foreach ($VirtualMachine in $AllVirtualMachines){

if ($VirtualMachine.Host.name -notlike "Host name"){

get-view $_.ID

$Tools = New-Object System.Management.Automation.PSObject

$Tools.PSObject.TypeNames[0] = "System.Management.Automation.PSObject#VMToolsInfo"

$Tools | Add-Member -force -Name VMName -MemberType NoteProperty -Value $_.Name

$Tools | Add-Member -force -Name ToolsVersion -MemberType NoteProperty -Value $_.config.tools.toolsVersion

$Tools | Add-Member -force -Name ToolsStatus -MemberType NoteProperty -Value $_.guest.toolsstatus

$Tools

}

}

thansk in advance!!

0 Kudos
13 Replies
LucD
Leadership
Leadership

Did you try running the script from the VI Toolkit shell ?

Perhaps try stopping/starting your PowerGui session.


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

0 Kudos
houghtp
Contributor
Contributor

just tried that same result...

I'm definately connected to VI-Server.

Can you confirm I'm using get-view correcly?

cheers.

0 Kudos
LucD
Leadership
Leadership

The problem is indeed in your Get-View cmdlet.

You use the $_ variable but you don't use a Powershell pipe (| symbol)

For some pointers on learning Powershell have a look at some of the links halr9000 gave in .

The way you are trying to do it you should use


$vm = get-view $VirtualMachine.ID 

The same is true where you use the $_ symbol later in the script, use $vm instead.

If I understand correctly what you are trying to do your script should be


$AllVirtualMachines = Get-VM -Server $global:VIServer
 
foreach ($VirtualMachine in $AllVirtualMachines){
if ($VirtualMachine.Host.name -notlike "Host name"){
$vm = get-view $VirtualMachine.ID
$Tools = New-Object System.Management.Automation.PSObject
$Tools.PSObject.TypeNames[0] = "System.Management.Automation.PSObject#VMToolsInfo"
$Tools | Add-Member -force -Name VMName -MemberType NoteProperty -Value $vm.Name
$Tools | Add-Member -force -Name ToolsVersion -MemberType NoteProperty -Value $vm.config.tools.toolsVersion
$Tools | Add-Member -force -Name ToolsStatus -MemberType NoteProperty -Value $vm.guest.toolsstatus
 
$Tools
}
}


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

0 Kudos
houghtp
Contributor
Contributor

Hi LucD

copying your script exaclty and running it in powerGui I get

"cannot index into a null array"

If i change the formating as follows :

(I've also changed the script to only run against opur cluster, removing the IF statement)

$AllClusters = Get-Cluster -Server $global:VIServer

$AllVirtualMachines = Get-VM -Location $AllClusters

foreach ($VirtualMachine in $AllVirtualMachines){

$vm = get-view $VirtualMachine.ID

$Tools = New-Object System.Management.Automation.PSObject

$Tools.PSObject.TypeNames[0] = "System.Management.Automation.PSObject#VMToolsInfo"

$Tools | Add-Member -force -Name VMName -MemberType NoteProperty -Value $vm.Name

$Tools | Add-Member -force -Name ToolsVersion -MemberType NoteProperty -Value $vm.config.tools.toolsVersion

$Tools | Add-Member -force -Name ToolsStatus -MemberType NoteProperty -Value $vm.guest.toolsstatus

$Tools

}

I get

" Object instance not set to an instance of an object"

0 Kudos
LucD
Leadership
Leadership

My mistake, I copied the wrong version.

This is the correct one with your latest changes incorporated.

$AllClusters = Get-Cluster -Server $global:VIServer
$AllVirtualMachines = Get-VM -Location $AllClusters
$toolsarray = @()

foreach ($VirtualMachine in $AllVirtualMachines){
$vm = get-view $VirtualMachine.ID
$Tools = New-Object System.Management.Automation.PSObject
$Tools | Add-Member -force -Name VMName -MemberType NoteProperty -Value $vm.Name
$Tools | Add-Member -force -Name ToolsVersion -MemberType NoteProperty -Value $vm.config.tools.toolsVersion
$Tools | Add-Member -force -Name ToolsStatus -MemberType NoteProperty -Value $vm.guest.toolsstatus
$toolsarray += $Tools
}

$toolsarray | Out-Default

Some notes:

1) I have used an array ($toolsarray) to store each object (Tools) that is filled in for each guest

2) Once the object is filled in with the properties it is added to the array ($toolsarray += $Tools)

3) After the loop through all guests the array is displayed with the default output controller.


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

0 Kudos
halr9000
Commander
Commander

There's a shortcut that BSonPosh came up with some time ago to create custom objects. It takes advantage of how select-object creates a new custom object to hold its output. Despite shortcuts sometimes being evil because the teach the wrong lessons or skip the underlying concepts, thus leaving you with a shallow basis for learning, this one is just so much clearer I have to put it out here anyway:

$customObject = "" | select-object Property1, Property2, Property3

That one-liner replaces the new-object command and each add-member command. You still have to assign values, but...as I said, it's just so succinct I can hardly stand it. Smiley Happy

Hal Rottenberg

Co-Host, PowerScripting Podcast (http://powerscripting.net)

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
LucD
Leadership
Leadership

Great stuff from BSonPosh !!

The script looks a lot simpler and is more readable.

This tip definitely goes in my toolkit.

$AllClusters = Get-Cluster -Server $global:VIServer
$AllVirtualMachines = Get-VM -Location $AllClusters
$toolsarray = @()
 
foreach ($VirtualMachine in $AllVirtualMachines){
$vm = get-view $VirtualMachine.ID
$Tools = "" | Select-Object VMName, ToolsVersion, ToolsStatus
$Tools.VMName = $vm.Name
$Tools.ToolsVersion = $vm.config.tools.toolsVersion
$Tools.ToolsStatus = $vm.guest.toolsstatus
$toolsarray += $Tools
}
 
$toolsarray | Out-Default


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

houghtp
Contributor
Contributor

both scripts work when running through a script editor - so thanks for that!

unfortunatley neither work when ran through powergui, I'm still getting

object reference not set to an instance of an object

I think i'll post something in the powergui forums

many thanks for your help!!

0 Kudos
Niket
Enthusiast
Enthusiast

Hi,

There are some cmdlets/script which leads an error and terminate the PowerGUI session with errors like "Exception has been thrown by target of an invocation" while runs fine using VI toolkit console. This is the problem on PowerGUI end and not related with VI toolkit.

Try to run this script with PowerGUI will throw the error and close the application while run successfully using VI toolkit

$Hs = get-viserver -server

$vms = Get-VM

foreach($vm in $vms) {

$vm | Get-Stat -Cpu -Memory

}

Thanks

Niket

0 Kudos
halr9000
Commander
Commander

You've reported it to them, right?

Hal Rottenberg

Co-Host, PowerScripting Podcast (http://powerscripting.net)

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
houghtp
Contributor
Contributor

Running your code in PowerGui works fine for me. i'm using version 1.0.1.410.

however I'm still seeing my origional issue. I'm running several other scripts using the vi toolkit through PowerGui and all work well. the only one that doesn't run is the one using Get-View.

I've posted the issue in their forums..

cheers.

0 Kudos
Dr_Sandy
Contributor
Contributor

First of all you should invoke Get-VIServer cmdlet before using Get-View. It seems Get-VIServer initializes something that afterwards is used by Get-View cmdlet. Secondly these two commands should be used only together within the same pipe.

For example this script works correctly:

$global:serv = @()

$global:serv += get-viserver -server 10.30.34.124 -port 443 -protocol https -credential (get-credential administrator)

$vmhost = Get-VMHost -server $global:serv

get-view $vmhost.Id

But if Get-VIServer was invoked from a function, the connection would be lost and the following script would complete with errors:

global:serv = @()

function GetServ {$global:serv += get-viserver -server 10.30.34.124 -port 443 -protocol https -credential (get-credential administrator)}

GetServ

$vmhost = Get-VMHost -server $global:serv

get-view $vmhost.Id

0 Kudos
yboychev
Hot Shot
Hot Shot

If you invoke Get-VIServer within a function in order not to loose your connection you should source the function later in the script instead of invoking it. So the modified script would be:

global:serv = @()

function GetServ {$global:serv += get-viserver -server 10.30.34.124 -port 443 -protocol https -credential (get-credential administrator)}

. GetServ

$vmhost = Get-VMHost -server $global:serv

get-view $vmhost.Id

Now this will work just fine

0 Kudos