{"id":1939,"date":"2024-03-26T09:18:03","date_gmt":"2024-03-26T13:18:03","guid":{"rendered":"https:\/\/enterpriseadmins.org\/blog\/?p=1939"},"modified":"2024-03-26T09:18:03","modified_gmt":"2024-03-26T13:18:03","slug":"fine-tuning-updates-targeted-host-remediation-with-vsphere-lifecycle-manager","status":"publish","type":"post","link":"https:\/\/enterpriseadmins.org\/blog\/scripting\/fine-tuning-updates-targeted-host-remediation-with-vsphere-lifecycle-manager\/","title":{"rendered":"Fine-Tuning Updates: Targeted Host Remediation with vSphere Lifecycle Manager"},"content":{"rendered":"\n<p>In vSphere 7.0 functionality was introduced to be able to manage a cluster of ESXi hosts with a single image.  In addition to being a bit easier to configure than the prior Update Manager Baselines, this feature also integrates with Hardware Support Managers to be able to update host firmware.  <\/p>\n\n\n\n<p>PowerCLI 12.1 introduced the ability to remediate against these single images, using syntax like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Get-Cluster img-test | Set-Cluster -Remediate -AcceptEULA<\/code><\/pre>\n\n\n\n<p>This and other vLCM cmdlets are discussed in this blog post: <a href=\"https:\/\/blogs.vmware.com\/PowerCLI\/2020\/10\/new-release-powercli-12-1-vlcm-enhancements.html\">https:\/\/blogs.vmware.com\/PowerCLI\/2020\/10\/new-release-powercli-12-1-vlcm-enhancements.html<\/a>.<\/p>\n\n\n\n<p>This is a very simple command and works very well to programmatically interact with the clusters if you have many to remediate.  However, sometimes we need to remediate hosts in a more controlled order, or as part of a larger workflow.  For example, perhaps we need to notify an operations management product or team before a host goes into maintenance to prevent after hour pages or service desk issues being logged.  This can be done, but requires a few extra cmdlets.  The code block below provides sample commands to remediate a specific host in a cluster.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$clusterid = (Get-Cluster 'Img-Test').ExtensionData.MoRef.Value\r\n$vmhostid = (Get-VMHost 'h178-vesx-04.lab.enterpriseadmins.org').ExtensionData.MoRef.Value\r\n\r\n# Initialize hosts to updates, hostids can be specified comma separated.\r\n$SettingsClustersSoftwareApplySpec = Initialize-SettingsClustersSoftwareApplySpec -Hosts $vmhostid -AcceptEula $true \r\n\r\n# Apply the specification object to the cluster\r\n$taskId = Invoke-ApplyClusterSoftwareAsync -Cluster $clusterid -SettingsClustersSoftwareApplySpec $SettingsClustersSoftwareApplySpec\r\n\r\n# The apply task runs async so we need to watch tasks for it to complete.\r\n$task=Get-Task |?{$_.Id -eq \"CisTask-$taskId\"} \r\n\r\n# Loop until the task finishes\r\nWhile ($task.State -eq \"Running\") {\r\n    \"sleeping...\"\r\n    Start-Sleep -Seconds 60 \r\n    $task=Get-Task |?{$_.Id -eq \"CisTask-$taskId\"} \r\n}<\/code><\/pre>\n\n\n\n<p>In the example above we get the ID value of the cluster and host, these are the values like <code>domain-c3146330<\/code> and <code>host-3146220<\/code> and are the values required by the cmdlets we are using.  <\/p>\n\n\n\n<p>We then create a spec to apply.  The parameters are described here: <a href=\"https:\/\/developer.vmware.com\/apis\/vsphere-automation\/latest\/esx\/api\/esx\/settings\/clusters\/cluster\/softwareactionapplyvmw-tasktrue\/post\/\">https:\/\/developer.vmware.com\/apis\/vsphere-automation\/latest\/esx\/api\/esx\/settings\/clusters\/cluster\/softwareactionapplyvmw-tasktrue\/post\/<\/a>.  I was originally confused by the <code>-commit<\/code> parameter until I found this documentation.  I had assumed the property was similar to a git commit message and was passing in random strings of text.  The property is optional, so in the above example I do not pass in the argument at all.  However, if you&#8217;d like to find the current\/expected value, you can get it from the cluster object like this: <code>(Invoke-GetClusterSoftwareCompliance -Cluster 'domain-c3146214').commit<\/code><\/p>\n\n\n\n<p>Next we pass our clusterid and above spec to the &#8216;Invoke&#8217; function.  The command returns a task ID, so we are capturing the output to a variable so we can use it later.  The Invoke command runs asynchronously, so we will use this ID to check on the status until the task completes.<\/p>\n\n\n\n<p>At the end we are checking for the task to complete.  The <code>Get-Task<\/code> cmdlet has an <code>-ID<\/code> parameter, but in my testing I would get an error of <code>The identifier CisTask-525d3596-4a7a-60ab-df10-ab97999b8511:com.vmware.esx.settings.clusters.software resulted in no objects.<\/code> when I tried to pass the ID to <code>Get-Task<\/code>.  Using where-object instead worked reliably, so I used it instead.<\/p>\n\n\n\n<p>Hopefully this helps if you have the need to remediate a single host in a cluster using a vLCM Image.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In vSphere 7.0 functionality was introduced to be able to manage a cluster of ESXi hosts with a single image. In addition to being a bit easier to configure than the prior Update Manager Baselines, this feature also integrates with &hellip; <a href=\"https:\/\/enterpriseadmins.org\/blog\/scripting\/fine-tuning-updates-targeted-host-remediation-with-vsphere-lifecycle-manager\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[9,3,4],"tags":[],"class_list":["post-1939","post","type-post","status-publish","format-standard","hentry","category-lab-infrastructure","category-scripting","category-virtualization"],"_links":{"self":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1939","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/comments?post=1939"}],"version-history":[{"count":3,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1939\/revisions"}],"predecessor-version":[{"id":1942,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1939\/revisions\/1942"}],"wp:attachment":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/media?parent=1939"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/categories?post=1939"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/tags?post=1939"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}