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.
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
Seems my problem is array as InputObject, so need to do it with $line[0] till $line[n] in Add-Member
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
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.
My bad, I forgot the PassThru switch
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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"
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
Thanks a lot, everything is working fine.
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...
@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
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.
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
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.
The $report variable is also defined outside the Foreach block
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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?
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