Sorting bits into bytes...

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 "----------------------------"

 

Leave a Reply