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!!
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
just tried that same result...
I'm definately connected to VI-Server.
Can you confirm I'm using get-view correcly?
cheers.
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
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"
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
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.
Hal Rottenberg
Co-Host, PowerScripting Podcast (http://powerscripting.net)
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
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!!
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
You've reported it to them, right?
Hal Rottenberg
Co-Host, PowerScripting Podcast (http://powerscripting.net)
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.
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
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