So this next post is about my experience with vSAN when using multiple storage policies and the headache that comes with managing a large vSAN environment when you have too many cooks in the kitchen!!
The environment I help manage has many clusters with many different storage policies… Unfortunately the storage policy “Compliance” status can be misleading and risky at scale especially if that’s all your depending on for desired / expected state of VM storage policy.
Recently we discovered that VM Home directories and VMDKs would end up with a mix and match of police’s if the administrators were not careful when moving, cloning and adding / changing disks! (basically BAU activities)
For example in our configuration we have 1 storage policy per vSAN cluster and depending on the requirement of the customers VM’s … they end up on a specific cluster with a specific storage policy (FTT=1, FTT=2, RAID1, RAID5/6 with Erasure Coding…etc)… now when we looked in the vCenter GUI all the VM’s were showing up as compliant with the storage policy which was great!!! but when we started to dig deeper we found out that VM’s were at risk because some disks would only tolerate 1 host failure where as others would tolerate 2 host failures some were on RAID1 and others on RAID5/6 with EC…!!!!
To manage / report correctly on the desired state and compliance of VM’s I built this report on my home lab (see below), it checks every single VM, it’s home directory and each VMDK and pumps the results out to a CSV.
So while the report above is useful… when you have 1000’s of VM’s to manage some additional logic and checking is required… Currently I visualise this data in Tableau by merging it with some inventory data…. but now I am working on improving this report further by validating against a configuration file that contains the expected policy for that Cluster / Datastore and identifying VM’s with issues (outOfDate, nonCompliant or compliant with the wrong policy for its location)
2 silly things which I discovered while on this adventure…
1). It appears there is no way to extract the current default vSAN policy via PowerCLI or the API… the only way I could do it was by creating a VM on a datastore and then checking what policy it got
2) The default vCenter Read Only role does not have sufficient permissions to run the command get-SpbmEntityConfiguration you need an additional permission for the user: Profile-driven storage view
so to the script!
To create the credentials file run the following command.
$cred = Get-Credential $cred | Export-Clixml -Path "d:\vcenter\config\HOME-VC.xml"
To run the script..
.\getStoragePolicy.ps1 -VC vc.vman.ch -creds HOME-VC -Filename "d:\vCenter\Reports\StoragePolicyReport.csv"
Main script
#Powershell collector script for vSAN storage policy compliance #v1.0 vMan.ch, 28.08.2017 - Initial Version <# Run the command below to store user and pass in secure credential XML for each environment $cred = Get-Credential $cred | Export-Clixml -Path "HOME-VC.xml" #> param ( [String]$VC, [String]$creds, [String]$FileName ) #Logging Function Function Log([String]$message, [String]$LogType, [String]$LogFile){ $date = Get-Date -UFormat '%m-%d-%Y %H:%M:%S' $message = $date + "`t" + $LogType + "`t" + $message $message >> $LogFile } $ScriptPath = (Get-Item -Path ".\" -Verbose).FullName $mods = "$ScriptPath\Modules;" $random = get-random $RunDateTime = (Get-date) $RunDateTime = $RunDateTime.tostring("yyyyMMddHHmmss") $RunDateTime = $RunDateTime + '_' + $random $LogFileLoc = $ScriptPath + '\Log\Logfile.log' if($creds -gt ""){ $cred = Import-Clixml -Path "$ScriptPath\config\$creds.xml" } else { echo "Environment not selected, stop hammer time!" Exit } Log -Message "Starting Script" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Log -Message "Connecting to $VC with credentials $creds" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Connect-VIServer -server $VC -Credential $cred -Force $DiskPolicyReport = @() Log -Message "Getting VM List from vCenter" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc $vms = Get-VM Log -Message "Running loop for VM Home Directory and VMDK Policy" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc foreach ($vm in $vms){ $vmCluster = Get-Cluster -VM $vm $vmDatastore = Get-Datastore -VM $vm $VMHome = $vm | get-SpbmEntityConfiguration Foreach ($VMH in $VMHome){ $DiskPolicyReport += New-Object PSObject -Property @{ VM = $vm Cluster = $vmCluster Datastore = $vmDatastore Entity = 'VMHome' Policy = $VMH.StoragePolicy Status = $VMH.ComplianceStatus DateTime = $VMH.TimeOfCheck } Remove-Variable VMH -Force -ErrorAction SilentlyContinue } $VMDisks = $vm | get-harddisk Foreach ($disk in $VMDisks){ $VMDisk = $disk | get-SpbmEntityConfiguration $DiskPolicyReport += New-Object PSObject -Property @{ VM = $vm Cluster = $vmCluster Datastore = [regex]::match($disk.Filename,'\[(.*?)\]').Groups[1].Value Entity = $VMDisk.Entity Policy = $VMDisk.StoragePolicy Status = $VMDisk.ComplianceStatus DateTime = $VMDisk.TimeOfCheck } Remove-Variable disk -Force -ErrorAction SilentlyContinue } } Log -Message "Generating report $FileName" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc $DiskPolicyReport | select VM,Cluster,Datastore,Entity,Policy,Status,DateTime | export-csv $FileName -NoTypeInformation Log -Message "Disconnecting from $VC" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc Disconnect-VIServer -server $VC -Confirm:$false Log -Message "Script Finished" -LogType "JOB-$RunDateTime" -LogFile $LogFileLoc
vMan
Hello
as per this scrips How to set vCenter environments, I was run this scripts and get Envirements not selected, stop hammer time.
You must be missing one of the mandatory variables, please check the command line parameters you are specifying
Hi,
I used the script on vSAN environment (ESXi and vCenter 6.7u3) but I found this error:
get-SpbmEntityConfiguration : 31/05/2022 13:53:56 Get-SpbmEntityConfiguration Specified argument was out of the range of valid values.
At E:\Scripts\getStoragePolicy.ps1:85 char:31
+ $VMDisk = $disk | get-SpbmEntityConfiguration
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-SpbmEntityConfiguration], CisException
+ FullyQualifiedErrorId : VMware.VimAutomation.ViCore.Impl.V1.Service.Tagging.Cis.TaggingServiceCisImpl.GetTag.Error,VMware.VimAutomation.Storage.Commands.Cmdlets.Spbm.GetSpbmEntityConfiguration
The same script worked correctly on vSphere with vCenter 7 and ESXi 6.7.