We are looking to get a report of missing patches and such from our hosts. I found this document from bbambalova, and wanted to see if anyone could assist me with it. From what I can tell, right now this script will run against ALL hosts found via the $vmHosts = Get-VMHost variable. We want to be able to run this against a specific set of hosts or even select clusters only; not the entire environment. I have tested with the following:
$vmHosts = Get-Content "C:\esxihosts.txt"
Within that text file, I have a few hostnames that I'd like to run the report against. When I run the script (ExportCompliance.ps1 $vmHOsts "C:\Reports\"), I get the following error:
Cannot process argument transformation on parameter 'inventoryItems'. Cannot convert the "esx1.host.com" value of type "system.String" to type "VMware.VimAutomation.ViCore.Types.V1.Inventory.InventoryItem[]".
Is there any way I can set this up to run as I'd like? Or is there a better way to go about accomplishing my goal? Thank you.
How do you call the script ExportComplianceToCSV.ps1 with this new setup ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Definitely digging your shortcut! I pretty much abandoned the original script. Here's is how I have been running my query:
$vmesxi = (Get-VMHost -Name (Get-Content "C:\esxihosts.txt"))
# Get today's date
$CurrentDate = Get-Date
$CurrentDate = $CurrentDate.ToString('MM-dd-yyyy_hhmmss')
# Set Output Path
$path = "C:\Reports\"
foreach ($i in $vmesxi) {
Get-Compliance -Entity $i -Detailed |
Select @{N="Host Name";E={$_.Entity.Name}},
@{N="Baseline";E={$_.Baseline.Name}},
@{N="Compliant Patches";E={$_.CompliantPatches | Measure-Object | Select -ExpandProperty Count}},
@{N="Not Compliant Patches";E={$_.NotCompliantPatches | Measure-Object | Select -ExpandProperty Count}},
@{N="Unknown Patches";E={$_.UnknownPatches | Measure-Object | Select -ExpandProperty Count}},
@{N="Not Applicable Patches";E={$_.NotApplicablePatches | Measure-Object | Select -ExpandProperty Count}},
Status |
Export-Csv "$path\PatchComplianceReport_$CurrentDate.csv" -UseCulture -NoTypeInformation
}
And there are two hostnames in the text file.
To make sure the reading of the hostnames works correctly, can you check if the following actually produces 2 objects ?
Get-VMHost -Name (Get-Content "C:\esxihosts.txt")
Since the Get-Compliance cmdlet accepts multiple objects on the Entity parameter, and since the values can come from the pipeline, you could drop the ForEach altogether.
Something like this
# Get today's date
$CurrentDate = Get-Date
$CurrentDate = $CurrentDate.ToString('MM-dd-yyyy_hhmmss')
# Set Output Path
$path = "C:\Reports\"
Get-VMHost -Name (Get-Content "C:\esxihosts.txt") |
Get-Compliance -Detailed |
Select @{N="Host Name";E={$_.Entity.Name}},
@{N="Baseline";E={$_.Baseline.Name}},
@{N="Compliant Patches";E={$_.CompliantPatches | Measure-Object | Select -ExpandProperty Count}},
@{N="Not Compliant Patches";E={$_.NotCompliantPatches | Measure-Object | Select -ExpandProperty Count}},
@{N="Unknown Patches";E={$_.UnknownPatches | Measure-Object | Select -ExpandProperty Count}},
@{N="Not Applicable Patches";E={$_.NotApplicablePatches | Measure-Object | Select -ExpandProperty Count}},
Status |
Export-Csv "$path\PatchComplianceReport_$CurrentDate.csv" -UseCulture -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Very cool! I initially had a problem with it until I noticed the "|" after the text file. Once I added that in, everything ran perfectly. Output successful for both servers.
And is there any downside to running this code like it is versus the original ExportCompliance script? Thank you.
The script provides more details about patches and upgrades, but if the info the last script produces is sufficient for your needs, use that one.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
And the only prerequisite to running the script is to have an existing scan correct? It pulls against the compliance report right?
You can always run a Scan-Inventory from the script.
That way it will always produce a result, even if there was no scan done before your script runs.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
What would be the best way to put that in? Just input before the "Get-Compliance" line?
No, I wouldn't do that in the same pipeline construct, it would break it since it doesn't do a Passthru of the HostSystem objects.
Make a separate one before the one with Get-Compliance.
...
$esx = Get-VMHost -Name (Get-Content "C:\esxihosts.txt")
$esx |
Scan-Inventory
$esx |
Get-Compliance -Detailed |
...
To avoid doing a Get-Content and the Get-VMHost twice, I placed that on a separate line, and store the results in a variable
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Awesome! Thank you again LucD!!
Dropping in by to this old thread.
How do we use this script? I don't see any clear instructions. Thanks.
What instructions do you mean?
How to run a PowerShell/PowerCLI script?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for the reply mate.
If I execute .\ExportComplianceToCSV.ps1 (Get-VMHost -Name $vmHosts) "C:\MyReports\", I get ONLY the first compliance report, which is PatchComplianceReport.CSV
I expected it will provide me with HostUpgradeComplianceReport.csv, VMHWUpgradeComplianceReport.csv, GetVMToolsUpgradeBaselineComplianceReport.csv and GetVAUpgradeBaselineComplianceReport.csv as well.
Am I missing something?
When there are no entries for a specific report, the file is not created.
Could that be the case?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
I tried to execute the script/command , but it throws an error. Need your help.
ExportCompliance.ps1 (Get-VMHost -Name $vmHosts) "C:\ABC\complinace-Reports\"
Thanks
V
Looks your $vmHosts variable is empty.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I tried the script and it worked great. Is there a way to get the install date for the patches?