VMware Cloud Community
Govi033
Contributor
Contributor
Jump to solution

Script to create snaphsot before that check datastore space

Hi Folks,

We want to run some  Predeloyment script before we install Windows Update on VM. This script should make snapshot of VM and post deployment task, we will delete snapshot after X number of days or should delete in Predeployment task (so that we have only one snapshot available all the time) . I would like to delete only snapshot which is created by predeployment script without touching other snapshot(non script snapshot). I have created basic script for this task and it works well but I would like to first check if we have enough space in datastore before making snapshot of VM.  So script should check if vm belongs to that perticular datastore and we have enought space in that datastore. Datastore has less then 20%, then we do will not do the snapshot and sent email to administrator about less space . We use office 365 SMTP. if we have enough space then start with snapshot with "VMName+Predeployment". script should check datastore space for each VM.

We have datastore like datastore_prod and datastore_nonproduction

data_prod has around 6 VM and data datastore_nonproduction has around 3 vm. 

Sorry, i am not good at scripts and very new to powercli. 

I am aware how to connect to vcenter server using encrypted username and password which is saved in two separate files and passing those arguments in script 

Only part which is not clear to me is to how to check free space in datastore and VM's belonging to that datastore. Preferably i will would like to avoid ouputting anything in csv files. 

Many thanks in Advance.

Govinda Naik

 

 

0 Kudos
2 Solutions

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

That probably means that this VM is sitting on more than 1 Datastore.
In $ds you have more than 1 object


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could do

Get-Datastore | 
Select-Object name,@{name="PercentFree";Expression={[math]::Round(($_.freespacegb / $_.capacitygb * 100),2)}} |
ForEach-Object -Process {
    if($_.PercentFree -lt 20){
        Write-Host "Less than 20% free space on $($_.name)"
    }
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

11 Replies
LucD
Leadership
Leadership
Jump to solution

You can use the CapacityGB and FreeSpaceGB properties of the Datastore object

$vmName = 'MyVM'

$vm = Get-VM -Name $vmName
$ds = Get-Datastore -RelatedObject $vm

if($ds.FreeSpaceGB/$ds.CapacityGB -lt 0.2){
    Write-Host "Less than 20% free space on $($ds.Name)"
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Govi033
Contributor
Contributor
Jump to solution

HI,

Thank you for the reply, when i ran this code, i received below error.

Method invocation failed because [System.Object[]] does not contain a method named 'op_Division'.
At D:\Scripts\Snapshot\VMCred\vmware_snapshot_creation_secure_creds_with_DatastorespaceUpdate1.ps1:23 char:4
+ if($ds.FreeSpaceGB/$ds.CapacityGB -lt 0.2){
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (op_Division:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

Method invocation failed because [System.Object[]] does not contain a method named 'op_Division'.
At D:\Scripts\Snapshot\VMCred\vmware_snapshot_creation_secure_creds_with_DatastorespaceUpdate1.ps1:23 char:4
+ if($ds.FreeSpaceGB/$ds.CapacityGB -lt 0.2){
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (op_Division:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

 

Any input on this?

 

Thanks

 

Govinda Naik

Tags (1)
0 Kudos
Govi033
Contributor
Contributor
Jump to solution

Below is the script which i created.

#Powershell user credentials retrieving from encrypted file

# here you configure the path of the secure key and of the encrypted credentials file, to be used for password fetching (change the path based on where you save those ones!)
$password = Get-Content D:\Scripts\Snapshot\VMCred\vcred.cred | ConvertTo-SecureString -Key (Get-Content D:\Scripts\Snapshot\VMCred\aes.key)
# after key definition, here, you save credentials into a logical variable. Notice: the username used is in clear text!
$username = @xxx@vsphere.local"
$credential = New-Object System.Management.Automation.PsCredential($Username,$Password)
# here you decrypt the password!
$Password = $credential.GetNetworkCredential().password
#Vcenter connection!

Connect-VIServer -Server XXX.XX.local -User $Username -Password $password
#Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
## get the datastore matching datastore_* that has the most freespace

$AppsVMs="DC***","BKP***" (VM Names)
ForEach ($VMName in $AppsVMs) {

$vm = Get-VM -Name $vmName
$ds = Get-Datastore -RelatedObject $VM

if($ds.FreeSpaceGB/$ds.CapacityGB -lt 0.2){
$snapshotname = $vm + "-PredeploymentSnapshot"
write-host "Creating snapshot [$snapshotname] for the VM [$vm]"
New-Snapshot -vm $vm -name $snapshotname -confirm:$false -runasync:$true
}
else
{
write-host "Not Enough Space in Datastore, Cannot Proceed with Snapshot"
}
}

 

Thanks

Govinda Naik

 

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That probably means that this VM is sitting on more than 1 Datastore.
In $ds you have more than 1 object


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Govi033
Contributor
Contributor
Jump to solution

Hi,

yes, i have 2 datastores. But both VM which is specified are in same datastore. 


Thanks

 

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That is not what the error is saying.
Check with

Get-VM -Name <a VM name> | Get-Datastore


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Govi033
Contributor
Contributor
Jump to solution

Below is the output for VM DC****

We have two data store

1)DataStore_Prod

2) DataStore_NonProd


FileSystemVersion : 6.82
DatacenterId : Datacenter-datacenter-21
Datacenter : ****HQ-Datacenter
ParentFolderId : Folder-group-s24
ParentFolder : datastore
DatastoreBrowserPath : vmstores:\vc***.****.local@443\****HQ-Datacenter\DataStore_Prod
FreeSpaceMB : 1763840
CapacityMB : 3814656
Accessible : True
Type : VMFS
StorageIOControlEnabled : False
CongestionThresholdMillisecond : 30
State : Available
ExtensionData : VMware.Vim.Datastore
CapacityGB : 3725.25
FreeSpaceGB : 1722.5
Name : DataStore_Prod
Id : Datastore-datastore-30
Uid : /VIServer=vsphere.local\*****@****.*****.local:443/Datastore=Datastore-datastore-30/


FileSystemVersion : 6.82
DatacenterId : Datacenter-datacenter-21
Datacenter : ****HQ-Datacenter
ParentFolderId : Folder-group-s24
ParentFolder : datastore
DatastoreBrowserPath : vmstores:\******.*****.local@443\*****-Datacenter\DataStore_NonProd
FreeSpaceMB : 2325856
CapacityMB : 2860800
Accessible : True
Type : VMFS
StorageIOControlEnabled : False
CongestionThresholdMillisecond : 30
State : Available
ExtensionData : VMware.Vim.Datastore
CapacityGB : 2793.75
FreeSpaceGB : 2271.34375
Name : DataStore_NonProd
Id : Datastore-datastore-31
Uid : /VIServer=vsphere.local\*****@******.*****.local:443/Datastore=Datastore-datastore-31/

0 Kudos
LucD
Leadership
Leadership
Jump to solution

If those VMs can be on any of those you have to check the one where the snapshot will be stored.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Govi033
Contributor
Contributor
Jump to solution

Found on more way to find free space in % and get all database name and free space in it 

Code as below

Get-Datastore | Select-Object name,@{name="PercentFree";Expression={[math]::Round(($_.freespacegb / $_.capacitygb * 100),2)}}

Output as below

Name Port User
---- ---- ----
vc.****.local 443 VSPHERE.LOCAL\*******

Name : datastore1
PercentFree : 99.94


Name : DataStore_Prod
PercentFree : 46.23


Name : DataStore_NonProd
PercentFree : 80.25

Now i want to use PercentFree in If statement something like this

if (PercentFree -lt 20 )
{
Write-Host "Less than 20% free space on $($ds.Name)"
}

But PercentFree is not recognised thats very obvious

so dont know how to grab percentfree output and put in if loop 🙂 

Please help me.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could do

Get-Datastore | 
Select-Object name,@{name="PercentFree";Expression={[math]::Round(($_.freespacegb / $_.capacitygb * 100),2)}} |
ForEach-Object -Process {
    if($_.PercentFree -lt 20){
        Write-Host "Less than 20% free space on $($_.name)"
    }
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Govi033
Contributor
Contributor
Jump to solution

Yes, thats correct  "That probably means that this VM is sitting on more than 1 Datastore.
In $ds you have more than 1 object "

This is suppose to be only one datastore but somehow it is two datastore.

 

0 Kudos