Hi,
I'm writing a script to remediate clusters in our vSphere environment. I quite like the idea of outputting a KB link for each patches that will be applied to each host. The snippet that will do this looks like:
Write-Output "3. Checking host compliance:"
foreach($esxiHost in $clusterHosts)
{
$complianceCheck = Get-Compliance -Entity $esxiHost -Detailed
if(($complianceCheck.Status) -eq "NotCompliant")
{
Write-Output "$($esxiHost) state: NOT compliant. Needs the following patches:"
[array]$remediateArray = $remediateArray + $esxiHost
foreach($patch in $complianceCheck.NotCompliantPatches)
{
Write-Output "- $($patch.IdByVendor)"# Write-Output "- KB Lookup: ......................."
}}
The problem I have with the code above is that $patch only seems to have the following properties (example):
Name : Updates ESXi 4.1 VMware Tools
Id : 8491
Description : For more information, see http://kb.vmware.com/kb/2002341
Product : {embeddedEsx 4.1.0}
ReleaseDate : 27/10/2011 09:00:00
Severity : Critical
IdByVendor : ESXi410-201110202-UG
Vendor : VMware, Inc.
Language : INTL
TargetType : HOST
BundleType : Update
InstallationImpact :
LastUpdateTime : 30/10/2011 13:05:08
IsRecalled : False
I initially thought I could use some regex/string manipulation on the "Description" property but I checked other patches and they don't all have "For more information, see <URL>". Some say "...see the KB article".
When looking at patches needed via the vSphere client / GUI window there appears to be a "property" called "Details URL" containing a nice clean URL! I realise this appears not to be a property of the above $patch object but I was wondering if it is located anywhere obtainable with PowerCLI?
Any help much appreciated ![]()
Why not just do a regex, looking for http, and when it finds it grabbing that until the end of the line....and maybe taking a period off of the end?
I initially thought I could use some regex/string manipulation on the "Description" property but I checked other patches and they don't all have "For more information, see <URL>". Some say "...see the KB article".
That's why
To be clearer, the description property doesn't always have a link. The clean URL link must be stored somewhere in relation to the actual patch, but I don't know what needs "interogating" in order to find this... perhaps it's stored in the SQL db and is not available through Powershell objects... ?
The script I use to list missing patches seems to always find a KB article in the description.
foreach($esx in Get-VMHost){ foreach($baseline in (Get-Compliance -Entity $esx -Detailed | where {$_.Status -eq "NotCompliant"})){ $baseline.NotCompliantPatches | select @{N="Host";E={$esx.Name}}, @{N="Baseline";E={$baseline.Baseline.Name}},Name,ReleaseDate,IdByVendor, @{N="KB";E={(Select-String "(?<url>http://[\w|\.|/]*\w{1})" -InputObject $_.Description).Matches[0].Groups['url'].Value}} } }
Which patches do you see that do not have a KB link ?
Update: or do you perhaps mean Update bundles ? They don't have a KB URL afaik.
Exactly right LucD (let's face it, when are you not?
)
When I saw *no* KB url link for the "description" property *in the GUI* I must have been looking at an update and not a patch. I just double checked this and it seems you're correct:
- patches "description" property contain a KB url links
- updates "description" property contains a lot more text, and just *refer* to the mysterious "Details URL" "property".
Anyway because of this it seems regex was the way to go afterall and you've saved me some time
I was quickly able to add the following into mine and it worked:
$patchKB = (Select-String "(?<url>http://[\w|\.|/]*\w{1})" -InputObject $patch.Description).Matches[0].Groups['url'].Value
I marked your answer as helpful rather than correct. Is it possible to change this?
Thanks!
Thanks ![]()
I can't change the Helpfull to Correct, but no problem.
Hi,
why the Get-Compliance is not recognized in PowerGUI and PowerCLI 4.1u2 ?
here's the error message that I mean:
The term 'Get-Compliance' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.At C:\Temp\28ef26ef-3385-4ca3-8273-1ea67e7f9ba1.ps1:3 char:41+ foreach($baseline in (Get-Compliance <<<< -Entity $esxiHost -Detailed | where {$_.Status -eq "NotCompliant"})){+ CategoryInfo : ObjectNotFound: (Get-Compliance:String) [], CommandNotFoundException+ FullyQualifiedErrorId : CommandNotFoundException
Albert,
Do get-pssnapin and make sure you have the vmware.VUMautomation snapin loaded.
If you don't...you can download it here