VMware Cloud Community
emcclure
Enthusiast
Enthusiast
Jump to solution

Batch file script does not pick up all VM's in a folder of which some have newest version of tools

So here's the setup:

I use vRA 7.3.1 to build a Windows 10 x64 VM that users can build thru a blueprint.  It had RS3 initially and VM Tools 10.2.  Users could build just fine.  I then upgraded to RS4 and it still builds fine.  However when I run the following script (generic info used below for user/pass/server):

Connect-VIServer servername -User username -Password password

$vm = Read-Host "Enter VM name"

$string = 'query user /server:$vm'

Invoke-VMScript -vm $vm -ScriptText $string -ScriptType Powershell -GuestUser 'administrator' -GuestPassword 'password'

And I enter the VM I get the query response I want

vCenterserver.lab        443   VSPHERE.LOCAL\Administrator
Enter VM name: myvm

VM           : myvm
ExitCode     : 0
ScriptOutput :  USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
                user              rdp-tcp#1           2  Active          .  6/4/2018 11:32 AM

The above is on a VM that's running Win 10 RS4 x64 with Tools 10.2.5 that was upgraded via a PowerCLI script.

And that just outputs to the window.  Unfortunately I have more than one machine, so I created a batch script below:

Connect-VIServer vCenterserver.lab -User username -Password password

$GetVM = Get-VM -location VRM | sort Name

$obj = foreach ($vm in $GetVM)

{

$string = 'query user /server:$vm'

Invoke-VMScript -vm $vm -ScriptText $string -ScriptType Powershell -GuestUser 'administrator' -GuestPassword 'password' | Out-File VRM.txt -append

}

So the above script I will get a list of machines that only appear to be running Tools 10.2 as the script will continually tell me that the version of tools is out of date on the machines.  I get the output in the text file, but what's odd is the machines that have the newer version of tools, there's a line, but it's blank as shown below:

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------
|   USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
|   user1                                2  Disc     10+00:16  5/25/2018 8:43 AM

-----------------------------------------------------------------------------------------------------------------------

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------
|   USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
|   user2               rdp-tcp#13          2  Active         48  5/29/2018 9:08 PM

-----------------------------------------------------------------------------------------------------------------------

I know those machines that are missing, if I query them I'll get a response with the first script mentioned here.  Why would an upgraded version of tools appear to break this?  Am I missing something?  Those machines that are missing did show up before the tools upgrade.  I ran a script to update the tools on the machines remotely and it didn't work for all machines, as it appears that I need to have some sort of custom attribute: https://blog.vmpros.nl/2015/05/15/vmware-vix-error-code-21009-during/ .

I have tried uninstalling VM Tools from the machine and reinstalling it, but that made no difference, even when running the script from one of the machines that's affected.  Yes I am running Anti-Virus stuff, however on the machines that are working it's running there as well, and all machines should have the same version of the software, so I don't think that's an issue.  I have now just taken my test machine and downgraded Tools to 10.2.0, re-ran the batch-script and it detected my machine.

I have also upgraded VM Tools on the template to 10.2.5 and am re-running the blueprint thru vRA to see what happens.  It fails to recognize the machine in the batch script.  So do I have a problem here with tools 10.2.5?  Something else?  Please advise.  Thanks.

Edit: I should also mention I was originally using PowerCLI 6.5.0 build 4624819.  I upgraded to 10.1.0 but I still get the same issue.

Edit 2: I took one of the machines and put VMware Tools 10.2.1 on it and re-ran the batch script.  This time it detected the VM in the script.

0 Kudos
1 Solution

Accepted Solutions
emcclure
Enthusiast
Enthusiast
Jump to solution

Aaannddd....here's my final version.  I made a change at the beginning to ask the user for the log file name, so that way you wouldn't wind up overwriting or constantly adding to the same one.

Connect-VIServer

$log = Read-Host "Enter log name i.e. VRM.txt"
$GetVM = Get-VM -location VRM | sort Name

$obj = foreach ($vm in $GetVM)
{
   $string = "query user /server:$vm"
   Invoke-VMScript -vm $vm -ScriptText $string -ScriptType Powershell -GuestUser 'administrator' -GuestPassword 'password' | Format-List | Out-File $log -append
}

View solution in original post

0 Kudos
13 Replies
LucD
Leadership
Leadership
Jump to solution

The difference between script 1 (standalone) and script 2 (ForEach loop), is how you substitute the name in the query command.

In script 1 you substitute with $vm which is a string, in script 2 you substitute also with $vm, but now it is a VirtualMachine .Net object.

Try script 2 like this

Connect-VIServer vCenterserver.lab -User username -Password password

$GetVM = Get-VM -location VRM | sort Name


$obj = foreach ($vm in $GetVM)

{

   $string = "query user /server:$($vm.Name)"

   Invoke-VMScript -vm $vm -ScriptText $string -ScriptType Powershell -GuestUser 'administrator' -GuestPassword 'password' | Out-File VRM.txt -append

}


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

0 Kudos
emcclure
Enthusiast
Enthusiast
Jump to solution

Hi Luc,

Unfortunately that didn't make a difference.  A couple machines that I got to Tools 10.2.1 didn't show up and the ones with Tools 10.2.5 still didn't show up.  Even when I run my original script now the machines with Tools 10.2.1 don't show whereas they showed up yesterday.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Do you get any errors or warnings on the console when you run the script?
What are they?

Did you try restarting the VMware Tools (10.2.1 and 10.2.5) service on the machines that didn't produce any output?


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

0 Kudos
emcclure
Enthusiast
Enthusiast
Jump to solution

Hi Luc,

No errors.  It just never shows the machines at all, basically like the original post, it shows a spot where a machine should be, but no output for it.  I've created a new machine with Tools 10.2.1 on it and it still didn't show, I've downgraded machines with 10.2.5 to 10.2.1 and they don't show now for some reason.

Yesterday I decided to downgrade the tools on the hosts from 10.2.5 to 10.2.1 since 10.2.1 seemed to work yesterday.  Now it's not working at all and I don't understand why.  I'm now downgrading the hosts to just Tools 10.2.0 and will create a new VM and see what happens.  Hopefully the new one will work.  If so I'd probably need to write a script to uninstall 10.2.5 from the affected machines and install 10.2 on them, either thru the vCenter patch manager or a script.

0 Kudos
emcclure
Enthusiast
Enthusiast
Jump to solution

So I downgraded the tools on the template to 10.2.0 and built a new VM from it.  When I run either batch script I get results for the machines that have either 10.2.0 or 10.2.1, but still nothing for 10.2.5.  When I run the script I no longer see the error for the tools being out of date which is fine, however when I look at the results from the batch I don't see the machine names, just the RDP session.  Is there a way to have it list the VM/machine name in the output as it does with just the single machine check?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I'm wondering if this is not related to the ScriptType you pass.

When I do PowerShell, some of the VMs' don't return anything either.

But when I use 'bat', all seem to return results.

I also added some more logic to extract the individual fields from the lines.

Give this a try

$GetVM = Get-VM -Name MyVM

foreach ($vm in $GetVM)

{

   $string = 'query user'

   $result = Invoke-VMScript -vm $vm -ScriptText $string -ScriptTypE Bat -GuestUser 'administrator' -GuestPassword 'WhatEver1!'

   $result.ScriptOutput.split("`r`n") | where{$_ -match 'rdp'} | %{

   $user,$session,$id,$state,$idletime,$logontime = $_.TrimStart(' ') -split '\s+'

   $result |

  Select @{N='VM';E={$result.VM.Name}},

  @{N='User';E={$user}},

  @{N='Session';E={$session}},

  @{N='Id';E={$id}},

  @{N='State';E={$state}},

  @{N='IdleTime';E={$idletime}},

  @{N='LogonTime';E={[DateTime]($logontime -join  ' ')}}

  }

}


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

0 Kudos
emcclure
Enthusiast
Enthusiast
Jump to solution

Hi Luc,

So that helps with seeing the VM name but only in the PowerCLI console, and I still don't get the machines that have the newer version of tools.  When I output this to a file I get this for the machines that fail:

ScriptOutput

-------------------------------------------------------------------------------

|  No User exists for *

|

-------------------------------------------------------------------------------

Rather odd as I've logged into some of these machines as the local admin which the script should even pick up.

Edit: It also appears that the most recent script you gave also just shows current active users which is why I could be seeing the response above.  What I want to find is what I originally had where if they were logged in or not, last time logged in, if so and idle time along with the machine name to an output file.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you try by adding a domain or the servername to the guestcredential?

Like -GuestUser "$(vm.Name)\administrator"


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

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I think you need 'query session /counter' for that.


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

0 Kudos
emcclure
Enthusiast
Enthusiast
Jump to solution

Hi Luc,

So if I do the query session I get this:

ScriptOutput

-------------------------------------------------------------------------------

|   SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE

|  >services                                    0  Disc                      

|   console                                     2  Conn                      

|   rdp-tcp                                 65536  Listen                    

|  Total sessions created: 3

|  Total sessions disconnected: 1

|  Total sessions reconnected: 0

|

-------------------------------------------------------------------------------

However that's for a machine that's recently had Tools downgraded to 10.2.0 and doesn't have anybody active on it at the moment.  From what I can tell since the reboot nobody has logged into it, so I logged in and re-ran the script and I see the session, however it doesn't really tell me when the user logged in, how long, idle time, etc, so I think query user would be better for what I need.  Since I have it sort by name I'm pretty sure I know which machine it is, but that's not very helpful to have to assume.  What am I missing to get the VM name to output in the text file?

VM           : my-vm

ExitCode     : 0

ScriptOutput :  USERNAME              SESSIONNAME        ID  STATE   IDLE TIME

                LOGON TIME

                administrator         rdp-tcp#1           3  Active         10

                6/5/2018 2:29 PM

0 Kudos
emcclure
Enthusiast
Enthusiast
Jump to solution

I didn't try that, but I didn't think I needed it since it's the same for all machines and can't be changed.

0 Kudos
emcclure
Enthusiast
Enthusiast
Jump to solution

Ok I got what I wanted now for the output:

Here's the script:

Connect-VIServer vCenterserver.lab -User username -Password password
$GetVM = Get-VM -location VRM | sort Name

$obj = foreach ($vm in $GetVM)
{
   $string = "query user /server:$($vm.Name)"
   Invoke-VMScript -vm $vm -ScriptText $string -ScriptType Powershell -GuestUser 'administrator' -GuestPassword 'password' | Format-List | Out-File VRM4.txt -append

I then get this:

VM           : my-vm
ExitCode     : 0
ScriptOutput :  USERNAME              SESSIONNAME        ID  STATE   IDLE TIME
                LOGON TIME
                administrator         rdp-tcp#1           3  Active         31
                6/5/2018 2:29 PM
              
Uid          : /VIServer=vsphere.local\administrator@vCenterserver.lab:44
               3/VirtualMachine=VirtualMachine-vm-3257/VMScriptResult=<removed>
               0_0/
Length       : 160

VM           : my-vm2
ExitCode     : 0
ScriptOutput :
Uid          : /VIServer=vsphere.local\administrator@vCenterserver.lab:44
               3/VirtualMachine=VirtualMachine-vm-3279/VMScriptResult=<removed>
               _0/
Length       : 0

The 2nd one should represent someone not logging into the machine, possibly a reboot cleared out any session info, which can be to the tools change, RS4 upgrade, etc.  Thanks for the help on this.

0 Kudos
emcclure
Enthusiast
Enthusiast
Jump to solution

Aaannddd....here's my final version.  I made a change at the beginning to ask the user for the log file name, so that way you wouldn't wind up overwriting or constantly adding to the same one.

Connect-VIServer

$log = Read-Host "Enter log name i.e. VRM.txt"
$GetVM = Get-VM -location VRM | sort Name

$obj = foreach ($vm in $GetVM)
{
   $string = "query user /server:$vm"
   Invoke-VMScript -vm $vm -ScriptText $string -ScriptType Powershell -GuestUser 'administrator' -GuestPassword 'password' | Format-List | Out-File $log -append
}

0 Kudos