
Automating vSAN Policy Application: The PowerShell script 5 of 5
## Introduction:
As we draw the curtains on this series, today’s blog serves as the grand finale, introducing the PowerShell script that adds the finishing touch. This script is the cherry on top, orchestrating the automated assignment of vSAN policies based on VM IOPS.
### Understanding the PowerShell Script
– **Comments for Clarity:**
– Throughout the script, comments are added to guide you through its functionality. A handy companion as you navigate the intricacies.
– **Super Metric ID Adjustment:**
– Note that the Super Metric ID may differ per user. Edit the “get-smMetrics” function by referencing your browser’s URL when editing the “vSAN Policy” Super Metric. Replace the ID accordingly for accurate data retrieval in your browser’s URL.
– **Calculating Optimal vSAN Policy:**
– The script retrieves the Super Metric value for the past 24 hours and calculates the best-fitting vSAN policy based on the Super Metrics and their formula.
– **Smart Policy Change Management:**
– If a better vSAN policy is found, the script checks the past 7 days to ensure consistency before implementing the change. This prevents VMs from constantly switching between policies.
– **Resync Object Check:**
– The script vigilantly monitors ongoing vSAN resynchronization, patiently waiting if the number of resynced objects surpasses 5, ensuring vSAN policy changes occur in a stable and manageable environment.
– **vSAN Cluster Health Assessment:**
– The script prioritizes vSAN cluster health, proceeding to update the vSAN policy in vCenter if the status is green; otherwise, it tactfully skips the current VM, ensuring a strategic approach for stability and integrity.
– **Change Tracking in Aria Operations:**
– The script logs vSAN policy changes in Aria Operations, providing a comprehensive record. The change date is stored for reference.
– **Log File for Monitoring:**
– For further tracking, the script generates a log file, detailing VMs whose vSAN policies have been changed.
### Script Availability:
– The script is available for download, allowing you to seamlessly integrate it into your vSAN management.
## Conclusion:
With the unveiling of this script, the series comes to a close. The automated assignment of vSAN policies based on VM IOPS is now within reach. I appreciate your engagement throughout this journey. If you have any questions or need further clarification, feel free to reach out. Until next time! 🚀 #vSAN #PowerShellScript #Automation #TechSeries #ThankYou
<# .SYNOPSIS Script: Auto SPBM Version: 1.1 (Tested) Date: Jan 21, 2024 Author: Kabir Ali - info@kablog.nl Description: This script will apply the correct vSAN policy based on a super metric Version history: 0.1 - Jan 21 - Initial version 1.0 - Feb 12 - Final version 1.1 - Feb 20 - Added delay to Aria Ops API .EXAMPLE .\auto_spbm.ps1 -vCenter "vCenter@local.domain" -vCenter_user "administrator@vsphere.local" -vCenter_pass "VMware1!" -vROpsServer "vrops01.local.domain" -vROps_user "Admin" -vROps_pass "VMware1!" -log_file "c:\temp\auto_spbm.log" #> Param ( [Parameter(Mandatory = $true)][string]$vCenter, [Parameter(Mandatory = $true)][string]$vCenter_user, [Parameter(Mandatory = $true)][string]$vCenter_pass, [Parameter(Mandatory = $true)][string]$vROpsServer, [Parameter(Mandatory = $true)][string]$vROps_user, [Parameter(Mandatory = $true)][string]$vROps_pass, [Parameter(Mandatory = $false)][string]$log_file = "C:\temp\auto_spbm.log" ) # Clear all variables # Remove-Variable * -ErrorAction SilentlyContinue # Function to get the unique ID of the VM in Aria Ops # Define a function named get-vmUid that takes a virtual machine name as a parameter function get-vmUid ($vmName) { # Construct the URL to query Aria Ops for the virtual machine's unique identifier $UidURI = $vROpsURL + "resources?resourceKind=virtualmachine&name=" + $vmName # Invoke a REST API call to retrieve information about the virtual machine from Aria Ops $vmUid = (Invoke-RestMethod -Method GET -Uri $UidURI -Headers $vROpsSessionHeader -ContentType $Type).resourceList.identifier # Check if there are multiple VMs with the same name in vCenter if ($vmUid.count -ne 1) { # If duplicates exist, retrieve additional information about the VMs $resourceState = (Invoke-RestMethod -Method GET -Uri $UidURI -Headers $vROpsSessionHeader -ContentType $Type).resourceList # Filter VMs based on their health state, picking the first one with a collecting state of "GREEN" (EA OK) $vmUid = ($resourceState | Where-Object { $_.resourceHealth -ne "GREY" }).identifier | Select-Object -First 1 } # Return the unique identifier of the VM return $vmUid } # Function to collect the Super Metric data # Define a function named get-smMetrics that takes a virtual machine unique identifier as a parameter function get-smMetrics ($vmUid) { # Construct the URL to query Aria Ops for the Super Metric data related to the VM $smURI = $vROpsURL + "resources/" + $vmUid + "/stats?latestMaxSamples=288&statKey=Super%20Metric%7Csm_42c5d462-6e93-4a46-b95a-ae28e2d75999&_no_links=true" # Invoke a REST API call to retrieve the Super Metric data for the specified VM $smValues = Invoke-RestMethod -Method GET -Headers $vROpsSessionHeader -Uri $smURI # Return the collected Super Metric data return $smValues } # Function to get vSAN policy in Aria Ops of VM # Define a function named get-vSANProperty to lookup the currenty vSAN Policy of the VM function get-vSANProperty ($vmUid, $harddisk) { # Constructing the URL to retrieve vSAN properties for the specified VM and hard disk $vSANPropertyURI = $vROpsURL + "resources/properties?resourceId=" + $vmUid # Invoke a REST API call to get vSAN properties for the VM $propertyValues = ((Invoke-RestMethod -Method GET -Uri $vSANPropertyURI -ContentType $Type -Headers $vROpsSessionHeader).resourcePropertiesList.property | Where-Object { $_ -like "*vSAN|vSAN Policy|$harddisk*" }).value # Return the vSAN property values return $propertyValues } # Function to display the vSAN policy in Aria Ops # Define a function named set-vSANProperty to update the displayed policy in Aria Ops function set-vSANProperty ($vmUid, $harddisk, $diskStoragePolicy) { # Get the current epoch time $EpochTimeNow = (Get-Date | ConvertTo-UnixTimestamp) # Constructing the JSON body for setting the vSAN property $JSONSetProperty = ' { "property-content": [{ "statKey": "vSAN|vSAN Policy|'+ $harddisk + '", "timestamps": ['+ $EpochTimeNow + '], "values": ["'+ $diskStoragePolicy + '"] }] } ' # Constructing the URL to set vSAN properties for the specified VM and hard disk $vSANPropertyURI = $vROpsURL + "resources/" + $vmUid + "/properties" # Invoke a REST API call to set the vSAN property in Aria Ops Invoke-RestMethod -Method POST -Body $JSONSetProperty -Uri $vSANPropertyURI -TimeoutSec 100 -Headers $vROpsSessionHeader -ContentType $Type | Out-Null } # Function to return the highest occurrence vSAN Policy from Super Metric data # Define a function named return-vSANPolicy that takes Super Metric values as a parameter function return-vSANPolicy ($smValues) { # Group the array elements by their values and count occurrences $groupedCounts = ($smReturn.values.'stat-list'.stat.data) | Group-Object | Sort-Object Count -Descending # Get the value with the highest count $mostCommonValue = $groupedCounts[0].Name # Define a variable to store the vSAN Policy based on the most common value $vSANMode = '' # Set the variable based on the most common value if ($mostCommonValue -eq '1,0') { $vSANMode = 'vSAN RAID 1' } elseif ($mostCommonValue -eq '5,0') { $vSANMode = 'vSAN RAID 5' } else { # Handle any other cases if needed $vSANMode = 'Unknown' Write-Output "Unknown - VM $($filteredVM.vmName)" } # Return the determined vSAN Policy return $vSANMode } # Function used to track the last date of a new vSAN policy # Define a function named get-lastDate that takes a virtual machine unique identifier and a hard disk parameter function get-lastDate ($vmUid, $harddisk) { # Construct the URL to query Aria Ops for the last update date of the vSAN policy for a specific hard disk $lastDateURI = $vROpsURL + "resources/" + $vmUid + "/properties" # Invoke a REST API call to retrieve the last update date value for the specified vSAN policy and hard disk $lastDateValue = ((Invoke-RestMethod -Method GET -Headers $vROpsSessionHeader -Uri $lastDateURI).property | Where-Object { $_.name -eq "vsan|update date|$harddisk" }).value # Return the last update date value return $lastDateValue } # Function to convert DateTime objects to Unix Timestamp (Epoch time) # Define a function named ConvertTo-UnixTimestamp function ConvertTo-UnixTimestamp { # Define the epoch as January 1, 1970, 00:00:00 $epoch = Get-Date -Year 1970 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0 # Process each DateTime input in the pipeline $input | ForEach-Object { # Calculate the milliseconds since the epoch for each DateTime value $milliSeconds = [math]::truncate($_.ToUniversalTime().Subtract($epoch).TotalMilliSeconds) # Output the calculated Unix Timestamp (Epoch time) for each input DateTime Write-Output $milliSeconds } } # Function to update the "last date" property for a vSAN policy # Define a function named set-lastDate that takes a virtual machine unique identifier and a hard disk parameter function set-lastDate ($vmUid, $harddisk) { # Construct the URL to update the "last date" property for the specified vSAN policy and hard disk $lastDateURI = $vROpsURL + "resources/" + $vmUid + "/properties" # Get the current date in a specific format $currentDate = Get-Date -Format "dd-MM-yyyy" # Convert the current date to Epoch timestamp $EpochTimeNow = (Get-Date | ConvertTo-UnixTimestamp) # Create a JSON payload with the updated date information $JSONSetDate = ' { "property-content": [{ "statKey": "vsan|update date|'+ $harddisk + '", "timestamps": ['+ $EpochTimeNow + '], "values": ["'+ $currentDate + '"] }] } ' # Invoke a REST API call to update the "last date" property using the constructed JSON payload $SetDateValue = Invoke-RestMethod -Method POST -Body $JSONSetDate -Uri $lastDateURI -Headers $vROpsSessionHeader -ContentType $Type -TimeoutSec 100 Start-Sleep -Seconds 30 # Return the result of the update operation return $SetDateValue } # Function to get the vSAN property in Aria Ops # Define a function named get-AriaProperty that takes a virtual machine unique identifier and a hard disk parameter function get-AriaProperty ($vmUid, $vmHarddisk) { # Construct the URL to get the vSAN policy property from Aria Ops $AriaPropertyURI = $vROpsURL + "resources/properties?resourceId=" + $vmUid $AriavSANProptery = ((Invoke-RestMethod -Method GET -Uri $AriaPropertyURI -ContentType $Type -Headers $vROpsSessionHeader).resourcePropertiesList.property | Where-Object { $_ -like "*vSAN|vSAN Policy|$vmHarddisk*" }).value return $AriavSANProptery } # Function to update the vSAN property in Aria Ops # Define a function named set-AriaProperty that takes a virtual machine unique identifier and a hard disk parameter function set-AriaProperty ($vmUid, $vmHarddisk, $diskStoragePolicy) { # Construct the URL to update the "last date" property for the specified vSAN policy and hard disk $AriaPropertyURI = $vROpsURL + "resources/" + $vmUid + "/properties" # Get the current date in a specific format #$currentDate = Get-Date -Format "dd-MM-yyyy" # Convert the current date to Epoch timestamp $EpochTimeNow = (Get-Date | ConvertTo-UnixTimestamp) # Create a JSON payload with the updated date information $JSONSetProperty = ' { "property-content": [{ "statKey": "vsan|vsan policy|'+ $vmHarddisk + '", "timestamps": ['+ $EpochTimeNow + '], "values": ["'+ $diskStoragePolicy + '"] }] } ' # Invoke a REST API call to update the "last date" property using the constructed JSON payload $SetPropertyValue = Invoke-RestMethod -Method POST -Body $JSONSetProperty -Uri $AriaPropertyURI -Headers $vROpsSessionHeader -ContentType $Type -TimeoutSec 100 Start-Sleep -Seconds 30 # Return the result of the update operation return $SetPropertyValue } # Function to check the health of a vSAN cluster # Define a function named get-vsanHealth that takes a vSAN cluster name as a parameter function get-vsanHealth ($clusterName) { # Select a random host from the specified cluster $esx = Get-Cluster -Name $clusterName | Get-VMHost | Get-Random # Use esxcli to get vSAN Health information $esxcli = Get-EsxCli -VMHost $esx -v2 # Get vSAN cluster health using the esxcli command $vsanHealth = ($esxcli.vsan.health.cluster.get.Invoke(@{test = 'vSAN object health' })) # Use a regular expression to capture the status after "vSAN object health" $status = $vsanHealth -match "vSAN object health\s+(\w+)" $statusValue = $matches[1] # Return the vSAN cluster health status return $statusValue } # Function to retrieve the number of objects to sync in a vSAN cluster # Define a function named get-objectsToSync that takes a vSAN cluster name as a parameter function get-objectsToSync ($clusterName) { # Use the Get-VsanResyncingOverview cmdlet to retrieve information about resynchronization in the specified vSAN cluster $objectsToSync = Get-VsanResyncingOverview -Cluster $clusterName # Return the total number of objects that are currently in the process of synchronization return $objectsToSync.TotalObjectsToSync } # Function to create and update a log file # Define a function named write-log that takes a log message as a parameter function write-log ($msg) { # Get the current date and time in the desired format $logTimestamp = Get-Date -Format "dd-MM-yyyy - HH:mm.ss.fff" # Create the log entry with timestamp and message $logEntry = "$logTimestamp`t$($msg)" # Append the log entry to the log file Add-Content -Path $log_file -Value $logEntry # Introduce a short sleep to avoid potential race conditions when updating the log file Start-Sleep -Seconds 0.2 } # Script start # Log an entry to mark the beginning of the script execution write-log -msg "----------------------------" write-log -msg "- SCRIPT STARTED -" write-log -msg "----------------------------" # Connect to vCenter # Log an entry indicating an attempt to connect to vCenter write-log -msg "Trying to connect to vCenter: $($vCenter)" # Try to establish a connection to vCenter try { # Use Connect-VIServer cmdlet to connect to vCenter with provided credentials Connect-VIServer -Server $vCenter -User $vCenter_User -Password $vCenter_Pass -ErrorAction Stop # Log a success message upon successful connection to vCenter write-log -msg "Connection successful to vCenter: $($vCenter)" } # Catch any errors that may occur during the connection attempt Catch { # Display a warning message and log an error message if the connection fails Write-Warning -Message "Error: Failed to connect to the vCenter: $($vCenter). Stopping script." write-log -msg "Error: Failed to connect to the vCenter: $($vCenter). Stopping script." # Terminate the script execution if connection fails Break } # Building vROps API string & invoking REST API # Constructing the base URL for vROps API and authentication URL $vROpsURL = "https://" + $vROpsServer + "/suite-api/api/" $vROpsAuthURL = "https://" + $vROpsServer + "/suite-api/api/auth/token/acquire" $Type = "application/json" # Creating JSON for authentication request body $AuthJSON = "{ ""username"": ""$vROps_User"", ""password"": ""$vROps_Pass"" }" # Authenticating with vROps API [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 write-log -msg "Trying to connect to Aria Ops: $($vROpsURL)" Try { # Invoking REST API to acquire authentication token $vROpsSessionResponse = Invoke-RestMethod -Method POST -Uri $vROpsAuthURL -Body $AuthJSON -ContentType $Type # Logging success message upon successful authentication write-log -msg "Connection successful to Aria Ops: $($vROpsServer)" } Catch { # Catching and logging errors if authentication fails $_.Exception.ToString() $error[0] | Format-List -Force Write-Output "Error: Failed to connect to the vROps: $($vROpsServer). Stopping script." write-log -msg "Error: Failed to connect to the vROps: $($vROpsServer). Stopping script." # Terminate the script execution if authentication fails Break } # Extracting the session ID from the authentication response for further API requests $vROpsSessionHeader = @{ "Authorization" = "vRealizeOpsToken " + $vROpsSessionResponse.'auth-token'.token "Accept" = "application/json" "X-vRealizeOps-API-use-unsupported" = "true" } # Get all VMs from vCenter # Log an entry indicating the start of retrieving a list of VMs from vCenter write-log -msg "Getting a list of VMs from vCenter" # Use the get-vm cmdlet to retrieve all VMs from the specified vCenter server $allVMs = (Get-VM -Server $vCenter) | Where-Object { $_.PowerState -eq "PoweredOn" -and $_.Name -notlike "vCLS*" } # Log the number of powered-on VMs found in vCenter write-log -msg "Found a total of $($allVMs.Count) powered-on VMs" # Get storage policy of each disk # Log an entry indicating the start of searching for the number of disks of VMs and their assigned vSAN policies write-log -msg "Searching for the number of disks of VMs and their assigned vSAN policies" # Create an array to store information about each VM's disks and their assigned vSAN policies [array]$vmDiskPolicy = @() # Iterate through each VM in the list of powered-on VMs foreach ($vmName in $allVMs) { # Get the unique ID of the current VM $currentUid = get-vmUid -vmName $vmName.Name # Get all disks of the current VM foreach ($vmDisk in (Get-SpbmEntityConfiguration -HardDisk (Get-HardDisk -VM $vmName))) { # non vSAN VMs don't have a disk storage policy, set those to $null if ($null -eq $vmDisk.StoragePolicy.name) { $diskStoragePolicyValue = "None" } else { $diskStoragePolicyValue = $vmDisk.StoragePolicy.name } # Add information about each disk to the array $vmDiskPolicy += New-Object PSObject -Property @{ "vmHarddisk" = $vmDisk.name "diskStoragePolicy" = $diskStoragePolicyValue "vmName" = $vmName.name "vmUid" = $currentUid } } } # Log the total number of disks found write-log -msg "Found a total of $($vmDiskPolicy.count) disks." # Exclude vDisks with the Fixed storage policy # Use the 'where' cmdlet to filter out disks with the Fixed storage policy from the previously collected information $filteredVMDiskPolicy = $vmDiskPolicy | Where-Object { $_.diskStoragePolicy.Name -notlike "*FIXED*" } # Log the number of disks to process after applying the vSAN exclude policy write-log -msg "Number of disks to process after applying vSAN exclude policy: $($filteredVMDiskPolicy.count)" ### Main code ### # Track VMs to process # Initialize an array to store information about VMs that need to be processed [array]$vmsToProcess = @() # Log an entry indicating the start of the main code write-log -msg "Starting main code." # Iterate through each filtered VM and its disks foreach ($filteredVM in $filteredVMDiskPolicy) { # Get the unique ID of the current VM $currentUid = get-vmUid -vmName $filteredVM.vmName # Log an entry indicating the start of processing the current VM write-log -msg "Processing $($filteredVM.vmName) with Uid $currentUid" # Get Super Metric values for the current VM $smReturn = get-smMetrics -vmUid $currentUid # Determine the vSAN policy to use based on Super Metric values $policyToUse = return-vSANPolicy -smValues $smReturn # Log an entry indicating the processed VM and the determined vSAN policy write-log -msg "Processed $($filteredVM.vmName) should have $policyToUse" # Check if a vSAN policy is found in Aria Ops if ($null -eq $policyToUse) { Write-Warning "For VM: $($filteredVM.vmName) there is no vSAN policy found in Aria Ops. $($policyToUse)" write-log -msg "For VM: $($filteredVM.vmName) there is no vSAN policy found in Aria Ops. $($policyToUse)" } # Check if the currently assigned vSAN policy is different from the determined policy if ($filteredVM.diskStoragePolicy -ne $policyToUse) { Write-Output "For VM: $($filteredVM.vmName) $($filteredVM.vmHarddisk) the vSAN policy must be updated: $($policyToUse). Currently using $($filteredVM.diskStoragePolicy)" # Get the unique ID for the current VM $vmUid = get-vmUid -vmName $filteredVM.vmName # Get the date when the latest update was performed $lastDate = get-lastDate -vmUid $vmUid -harddisk $filteredVM.vmHarddisk # If the last update date is not available, set a default value if ([string]::IsNullOrEmpty($lastDate)) { $lastDate = "01-01-1900" } # Log information about the VM that needs an update write-log -msg "For VM: $($filteredVM.vmName) $($filteredVM.vmHarddisk) the vSAN policy must be updated: $($policyToUse). Currently using $($filteredVM.diskStoragePolicy). Last update: $lastDate" # Add information about the VM to the array of VMs to be processed $vmsToProcess += New-Object PSObject -Property @{ "vmHarddisk" = $filteredVM.vmHarddisk "diskStoragePolicy" = $filteredVM.diskStoragePolicy "vmName" = $filteredVM.vmName "vmCluster" = (Get-VM -Name $filteredVM.vmName | Get-Cluster).Name "vmUid" = $vmUid "lastUpdate" = $lastDate "newPolicy" = $policyToUse } } } # Log the number of disks that should get a different vSAN policy write-log -msg "Number of disks that should get a different vSAN policy: $($vmsToProcess.count)" ## Update vSAN policy part ## # Iterate through each VM that needs to have its vSAN policy updated foreach ($vmToProcess in $vmsToProcess) { # Get the date of 7 days ago $daysAgoThreshold = (Get-Date).AddDays(-7) # Log an entry indicating the start of checking and updating vSAN policies for the current VM and disk write-log -msg "Checking and updating vSAN policy for $($vmToProcess.vmName) - Disk: $($vmToProcess.vmHarddisk)" # Check the number of active resync objects write-log -msg "Checking the number of vSAN objects in resync on cluster: $($vmToProcess.vmCluster)" $objSync = get-objectsToSync $vmToProcess.vmCluster write-log -msg "Currently resyncing objects: $objSync" # Wait if there are more than 5 active resync objects, check every 60 seconds while ($objSync -gt 5) { write-log -msg "vSAN Object sync is out of threshold. Waiting 60 seconds before continuing" start-sleep 60 $objSync = get-objectsToSync $vmToProcess.vmCluster write-log -msg "Currently resyncing objects: $objSync" } # Convert the last update date to a DateTime object $lastUpdateDate = Get-Date $vmToProcess.lastUpdate # Check if the last update date is more than 7 days ago if ($lastUpdateDate -lt $daysAgoThreshold) { Write-Host "$($vmToProcess.vmName) - Last update is more than 7 days ago." write-log -msg "$($vmToProcess.vmName) $($vmToProcess.vmHarddisk) will be updated." # Check the cluster health write-log -msg "Checking vSAN cluster health of: $($vmToProcess.vmCluster)" $clusterHealth = get-vsanHealth -clusterName $vmToProcess.vmCluster # If the cluster health is green, proceed with updating the vSAN policy if ($clusterHealth -eq "green") { write-log -msg "vSAN cluster health is: $clusterHealth. Good to continue." # Set the new vSAN policy for the specified VM and disk write-log -msg "Applying new vSAN Policy: $($vmToProcess.newPolicy) on $($vmToProcess.vmName) on disk $($vmToProcess.vmHarddisk). Old policy $($vmToProcess.diskStoragePolicy)" write-Output "Applying new vSAN Policy: $($vmToProcess.newPolicy) on $($vmToProcess.vmName) on disk $($vmToProcess.vmHarddisk). Old policy $($vmToProcess.diskStoragePolicy)" Set-SpbmEntityConfiguration -Configuration (Get-SpbmEntityConfiguration (Get-VM -Name $vmToProcess.vmName | Get-HardDisk -Name ($vmToProcess.vmHarddisk))) -StoragePolicy $vmToProcess.newPolicy | Out-Null # Log an entry indicating the setting of the new date in Aria Ops write-Output "Setting a new date in Aria Ops" write-log -msg "Setting a new date in Aria Ops" # Update the "last date" property in Aria Ops set-lastDate -vmUid $vmToProcess.vmUid -harddisk $vmToProcess.vmHarddisk } else { # Log an entry indicating that the vSAN cluster health is not green, and skipping to the next disk write-Output "vSAN cluster health is: $clusterHealth. Skipping to the next disk!" write-log -msg "vSAN cluster health is: $clusterHealth. Skipping to the next disk!" } } else { # Log an entry indicating that the VM and disk will not be updated because it was updated within the last 7 days write-Output "$($vmToProcess.vmName) $($vmToProcess.vmHarddisk) will not be updated because it was updated within the last 7 days." write-log -msg "$($vmToProcess.vmName) $($vmToProcess.vmHarddisk) will not be updated because it was updated within the last 7 days." } } ## Update vSAN policy in Aria Ops part ## # Iterate through each VM that needs to have its vSAN policy updated foreach ($diskPolicy in $vmDiskPolicy) { # Log an entry indicating checking the vSAN property in Aria Ops write-log -msg "Collecting for $($diskPolicy.vmName) $($diskPolicy.vmHarddisk) the property in Aria Ops." # Get the current vSAN policy in Aria Ops and update if not same as vCenter policy if ((get-AriaProperty -vmUid $diskPolicy.vmUid -vmHarddisk $diskPolicy.vmHarddisk) -ne $diskPolicy.diskStoragePolicy) { # Log an entry indicating the property will be updated in Aria Ops write-log -msg "For $($diskPolicy.vmName) $($diskPolicy.vmHarddisk) the property will be updated in Aria Ops." write-Output "For $($diskPolicy.vmName) $($diskPolicy.vmHarddisk) the property will be updated in Aria Ops." # Update vSAN policy as shown in Aria Ops set-AriaProperty -vmUid $diskPolicy.vmUid -vmHarddisk $diskPolicy.vmHarddisk -diskStoragePolicy $diskPolicy.diskStoragePolicy } } # Iterate through each VM that needs to have its vSAN policy updated foreach ($diskPolicy in $vmsToProcess) { # Log an entry indicating checking the vSAN property in Aria Ops write-log -msg "Collecting for $($diskPolicy.vmName) $($diskPolicy.vmHarddisk) the property in Aria Ops." # Get the current vSAN policy in Aria Ops and update if not same as vCenter policy if ((get-AriaProperty -vmUid $diskPolicy.vmUid -vmHarddisk $diskPolicy.vmHarddisk) -ne $diskPolicy.newPolicy) { # Log an entry indicating the property will be updated in Aria Ops write-log -msg "For $($diskPolicy.vmName) $($diskPolicy.vmHarddisk) the property will be updated in Aria Ops." write-Output "For $($diskPolicy.vmName) $($diskPolicy.vmHarddisk) the property will be updated in Aria Ops." # Update vSAN policy as shown in Aria Ops set-AriaProperty -vmUid $diskPolicy.vmUid -vmHarddisk $diskPolicy.vmHarddisk -diskStoragePolicy $diskPolicy.newPolicy } } # Release Aria Ops token # Log an entry indicating the release of the Aria Ops token write-log -msg "Released Aria Ops token" # Display a message indicating the completion of the script and release of vROps API token Write-Output "All done. Releasing vROps API token and disconnecting vCenter." # Invoke a REST API call to release the vROps API token Invoke-RestMethod -Method POST -Uri https://$vROpsServer/suite-api/api/auth/token/release -Headers $vROpsSessionHeader -ContentType $Type # Close vCenter connection # Disconnect from vCenter write-log -msg "Closed vCenter connection" Disconnect-VIServer -Server * -Confirm:$false # Script stop # Log entries marking the end of the script execution write-log -msg "----------------------------" write-log -msg "- SCRIPT STOPPED -" write-log -msg "----------------------------"