VMware Cloud Community
ngillettspio
Contributor
Contributor
Jump to solution

Script to verify activation of VM Windows License

I have deployed over 50 VM's via powercli Script and noticed the customization on some of the VM's didn't activate windows license. Is it possible to run a powercli script on these 50 VM's to see which VM's completed with windows activated or not? This would save loads of time without having to check every VM individually. 

35 Replies
LucD
Leadership
Leadership
Jump to solution

Yes, if you have 2 objects in $line, that means you have an array.
In that case you will have to loop through the array, and add the new property on each element in the array.

Testing in PSv7 will not make a difference in this case


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

Reply
0 Kudos
salcinad
Enthusiast
Enthusiast
Jump to solution

Seems my problem is array as InputObject, so need to do it with $line[0] till $line[n]  in Add-Member

 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try something like this 

 

$line = $result.ScriptOutput | ConvertFrom-Csv
$vmName = $_.Name
$line = $line | Foreach-Object -Process {
  Add-Member -InputObject $_ -Name VM -Value $vmName -MemberType NoteProperty -PassThru
}
$report += $line

 


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

salcinad
Enthusiast
Enthusiast
Jump to solution

The $report Variable is now with your example empty. Isn't the new code on line 3 the one which overrides the $line input itself? Also the $report | Get-Member give me the "You must supply an object to the Get-Member cmdlet " error.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

My bad, I forgot the PassThru switch


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

Reply
0 Kudos
salcinad
Enthusiast
Enthusiast
Jump to solution

Now it works as it should.. Kudos to your support on this Add-Member issue at my side. I really appreciate it.

Last question in regards to it. Is it possible to add new object VM to the beginning of the line?

The output (shorten to just few line) looks like this now:

#TYPE System.Management.Automation.PSCustomObject
"DeviceID","Caption","InfFilename","DriverVersion","DriverDate","PNPDeviceID","VM"
"VideoController1","VMware Horizon Indirect Display Driver","oem16.inf","1.4.12.0","08.09.2020 02:00:00","ROOT\VMWVIDD\0000","VDI0001"
"VideoController2","Microsoft Basic Display Adapter","display.inf","10.0.18362.1","21.06.2006 02:00:00","PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD&REV_00\3&61AAA01&0&78","VDI0001"
"VideoController1","VMware Horizon Indirect Display Driver","oem18.inf","1.4.12.0","08.09.2020 02:00:00","ROOT\VMWVIDD\0000","VDI0002"

 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can do a Select-Object with the properties in the order you want and pipe the output to Export-Csv.


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

salcinad
Enthusiast
Enthusiast
Jump to solution

Thanks a lot, everything is working fine.

Reply
0 Kudos
salcinad
Enthusiast
Enthusiast
Jump to solution

Do you know maybe if the Invoke-VMScript can be used with "ForEach-Object -Parallel" which was introduced with PowerShell 7 and PowerCLI 12.2 ?

I was reading the PowerCLI 12.2 Release Note [1] and the "Inline -Server parameter" or "Use PowerCLI Context", but both of these I am unable to use with the script on link [2].

I would like to make Invoke-VMScript script faster, as it takes a lot of time to execute in Environment with 100+ VMs (VDIs)

 

[1] https://blogs.vmware.com/PowerCLI/2021/02/new-release-vmware-powercli-12-2.html
[2] https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/Script-to-verify-activation-of-VM-Wind...

 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution


@salcinad wrote:

... but both of these I am unable to use with the script ...

 


How did you try to use that feature, and what is the issue you encounter?


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

Reply
0 Kudos
salcinad
Enthusiast
Enthusiast
Jump to solution

I tried to do the "Inline -Server parameter" way.

script:

# Establish connection to vCenter
$vcserver = Connect-VIServer -Server $vc -Credential $xcredential
 
$code = @'
 
 Get-CimInstance -ClassName Win32_VideoController |

  Select-Object -Property DeviceID, Caption, InfFilename, DriverVersion, DriverDate, PNPDeviceID |

  ConvertTo-Csv -NoTypeInformation

'@

$report = @()

# ForEach-Object -Parallel
Get-Folder -Id "Folder-group-v101" | Get-VM | Where-Object {$_.PowerState -eq "PoweredOn" -and $_.GuestId -eq 'windows9_64Guest' -and $_.Guest.State -eq "Running" } |
  ForEach-Object -Parallel {
    $result = Invoke-VMScript -Server $using:vcserver -VM $_ -GuestCredential $xcredential -ScriptType PowerShell -ScriptText $code
    $line = $result.ScriptOutput | ConvertFrom-Csv
    $vmName = $_.Name
    $line = $line | Foreach-Object -Process {
      Add-Member -InputObject $_ -Name VM -Value $vmName -MemberType NoteProperty -PassThru
    }
    $report += $line
}

$report | Select-Object "VM","DeviceID","Caption","InfFilename","DriverVersion","DriverDate","PNPDeviceID" | 
    Export-Csv -NoTypeInformation -Path "c:\Temp\Horizon_VDIs03.csv"

 

It complains about ScriptText is missing, which is somehow weird, If i put instead -Parallel the -Process, and remove from Invoke-VMScript this "-Server $using:vcserver", it works fine (PowerShell 7.1.5)

PS C:\scripts> Measure-Command { .\Horizon_Get-SVGA_Drivers.ps1 | Out-Default }
Invoke-VMScript:
Line |
   2 |  …   $result = Invoke-VMScript -Server $using:vcserver -VM $_ -GuestCred …
     |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | 21.10.2021 22:44:42      Invoke-VMScript         Value cannot be found for the mandatory parameter ScriptText
ConvertFrom-Csv:

 

I did not find much information about "$using:**" variable so that above is copy/paste from release note page.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Since you define the $code variable outside the Foreach -Parallel block, you will also refer to it with $using:


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

Reply
0 Kudos
salcinad
Enthusiast
Enthusiast
Jump to solution

I changed the Invoke-VMScript line to

 

$result = Invoke-VMScript -Server $using:vcserver -VM $_ -GuestCredential $using:xcredential -ScriptType PowerShell -ScriptText $using:code

 

(GuestCredentials and $code are now added to that line).

Now that error above is gone, but $report seems empty as the output file is 0 bytes. I'll try to debug this, there is no new error shown.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The $report variable is also defined outside the Foreach block


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

Reply
0 Kudos
salcinad
Enthusiast
Enthusiast
Jump to solution

Sure but it gets input from $line, and the line from $result of Invoke-VMScript. I am not quite sure what to use with $report that it gets the input from ForEach block?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can also just place the result on the pipeline, and assign all that to a variable

$result = Foreach-Object -Parallel {
  # The code to be executed in parallel
  $line
}


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

Reply
0 Kudos