-
1. Re: Unmount datastores if unused and dettach them based on NAA
LucD Apr 17, 2019 6:04 AM (in response to momox1)Unmounting and detaching is shown in Datastore Mount/Unmount Detach/Attach functions
But how would you determine that a datastore is empty and/or unused?
-
2. Re: Unmount datastores if unused and dettach them based on NAA
momox1 Apr 17, 2019 6:08 AM (in response to LucD)I meant If there is no VMs or vmdks hosted on the datatastore. It is possible?
Thank you
-
3. Re: Unmount datastores if unused and dettach them based on NAA
LucD Apr 17, 2019 6:50 AM (in response to momox1)You could do something like this.
It looks if there are VMs on the datastore or VMDK (and ignores eventual orphaned VMDK).
Can you chekc if that would find your empty and/or unused datastores?$dsName = 'MyDS'$ds = Get-Datastore -Name $dsName
$vm = Get-VM -Datastore $ds
$vmVmdk = (Get-VM | Get-HardDisk).FileName
New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root '\' | Out-Null
$vmdk = (Get-ChildItem -Path DS: -Recurse -Include '*.vmdk' | where{$vmVmdk -notcontains $_.DatastoreFullPath}).DatastoreFullPath
Remove-PSDrive -Name DS -Confirm:$false
if(-not $vm -and -not $vmdk){
Write-Host "Datastore $dsName is empty"
}
else{
Write-Host "Datastore $dsName is not empty"
}
-
4. Re: Unmount datastores if unused and dettach them based on NAA
momox1 Apr 17, 2019 7:05 AM (in response to LucD)great!! it does the work, now I have to add the function to unmount and dettach that datastore...
As soon as i get it done I will post it here.
Feel free to share some code if already done.
Thank you for your support.
-
5. Re: Unmount datastores if unused and dettach them based on NAA
LucD Apr 17, 2019 7:12 AM (in response to momox1)If you use the functions I pointed to earlier, it would just be adding some lines when the datastore is empty.
$dsName = 'MyDS'$ds = Get-Datastore -Name $dsName
$vm = Get-VM -Datastore $ds
$vmVmdk = (Get-VM | Get-HardDisk).FileName
New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root '\' | Out-Null
$vmdk = (Get-ChildItem -Path DS: -Recurse -Include '*.vmdk' | Where-Object { $vmVmdk -notcontains $_.DatastoreFullPath }).DatastoreFullPath
Remove-PSDrive -Name DS -Confirm:$false
if (-not $vm -and -not $vmdk)
{
Get-DatastoreMountInfo -Datastore $ds
Unmount-Datastore -Datastore $ds
Detach-Datastore -Datastore $ds
}
else
{
Write-Host "Datastore $dsName is not empty"
}
-
6. Re: Unmount datastores if unused and dettach them based on NAA
momox1 Apr 18, 2019 1:45 AM (in response to momox1)HI LucD,
Is there any way to create a loop so I can check all vcenter's datastores without having to specify the datastore name at the begining?
Thank you
-
7. Re: Unmount datastores if unused and dettach them based on NAA
momox1 Apr 18, 2019 2:39 AM (in response to momox1) -
8. Re: Unmount datastores if unused and dettach them based on NAA
LucD Apr 18, 2019 3:27 AM (in response to momox1)Great!
Feel free to ask if you have further questions. -
9. Re: Unmount datastores if unused and dettach them based on NAA
momox1 Apr 18, 2019 4:51 AM (in response to LucD)last questions , I promise^^
Do you see an easy way to merge the check if datastore is umountable fonction ( Test if the datastore can be unmounted - LucD notes ) with the unmount it and dettached if true.
An easy way to run it over all vCenter's datastores and if it's unmountable do it and dettach it?
Thank you
-
10. Re: Unmount datastores if unused and dettach them based on NAA
LucD Apr 18, 2019 5:30 AM (in response to momox1)Try something like this
function Get-DatastoreUnmountStatus{
<#
.SYNOPSIS Check if a datastore can be unmounted.
.DESCRIPTION The function checks a number of prerequisites
that need to be met to be able to unmount a datastore.
.NOTES Author: Luc Dekens
.PARAMETER Datastore
The datastore for which you want to chekc the conditions.
You can pass the name of the datastore or the Datastore
object returned by Get-Datastore
.EXAMPLE
PS> Get-DatastoreUnmountStatus -Datastore DS1
.EXAMPLE
PS> Get-Datastore | Get-DatastoreUnmountStatus
#>
param(
[CmdletBinding()]
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[PSObject[]]$Datastore
)
process
{
foreach ($ds in $Datastore)
{
if ($ds.GetType().Name -eq "string")
{
$ds = Get-Datastore -Name $ds
}
$parent = Get-View $ds.ExtensionData.Parent
New-Object PSObject -Property @{
Datastore = $ds.Name
# No Virtual machines
NoVM = $ds.ExtensionData.VM.Count -eq 0
# Not in a Datastore Cluster
NoDastoreClusterMember = $parent -isnot [VMware.Vim.StoragePod]
# Not managed by sDRS
NosDRS = & {
if ($parent -is [VMware.Vim.StoragePod])
{
!$parent.PodStorageDrsEntry.StorageDrsConfig.PodConfig.Enabled
}
else { $true }
}
# SIOC disabled
NoSIOC = !$ds.StorageIOControlEnabled
# No HA heartbeat
NoHAheartbeat = & {
$hbDatastores = @()
$cls = Get-View -ViewType ClusterComputeResource -Property Host |
Where-Object { $_.Host -contains $ds.ExtensionData.Host[0].Key }
if ($cls)
{
$cls | % {
( $_.RetrieveDasAdvancedRuntimeInfo()).HeartbeatDatastoreInfo | % {
$hbDatastores += $_.Datastore
}
}
$hbDatastores -notcontains $ds.ExtensionData.MoRef
}
else { $true }
}
# No vdSW file
NovdSwFile = & {
New-PSDrive -Location $ds -Name ds -PSProvider VimDatastore -Root '\' | Out-Null
$result = Get-ChildItem -Path ds:\ -Recurse |
Where-Object { $_.Name -match '.dvsData' }
Remove-PSDrive -Name ds -Confirm:$false
if ($result) { $false }else { $true }
}
# No scratch partition
NoScratchPartition = & {
$result = $true
$ds.ExtensionData.Host | % { Get-View $_.Key } | % {
$diagSys = Get-View $_.ConfigManager.DiagnosticSystem
$dsDisks = $ds.ExtensionData.Info.Vmfs.Extent | % { $_.DiskName }
if ($dsDisks -contains $diagSys.ActivePartition.Id.DiskName)
{
$result = $false
}
}
$result
}
}
}
}
}
Get-Datastore -PipelineVariable ds |
ForEach-Object -Process {
$result = Get-DatastoreUnmountStatus -Datastore $ds
if (($result.PSObject.Properties | Where-Object { $_.Name -match "^No" }).Value -notcontains $false)
{
$vm = Get-VM -Datastore $ds
$vmVmdk = (Get-VM | Get-HardDisk).FileName
New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root '\' | Out-Null
$vmdk = (Get-ChildItem -Path DS: -Recurse -Include '*.vmdk' | Where-Object { $vmVmdk -notcontains $_.DatastoreFullPath }).DatastoreFullPath
Remove-PSDrive -Name DS -Confirm:$false
if (-not $vm -and -not $vmdk)
{
Get-DatastoreMountInfo -Datastore $ds
Unmount-Datastore -Datastore $ds
Detach-Datastore -Datastore $ds
}
else
{
Write-Host "Datastore $dsName is not empty"
}
}
}
-
11. Re: Unmount datastores if unused and dettach them based on NAA
momox1 Apr 18, 2019 7:41 AM (in response to LucD)Hola
I have commented all the checks except the VM and scratch check, I have a datastore empty, but still getting the datastore is not empty result.
any hint?
Thank you
function Get-DatastoreUnmountStatus
{
<#
.SYNOPSIS Check if a datastore can be unmounted.
.DESCRIPTION The function checks a number of prerequisites
that need to be met to be able to unmount a datastore.
.NOTES Author: Luc Dekens
.PARAMETER Datastore
The datastore for which you want to chekc the conditions.
You can pass the name of the datastore or the Datastore
object returned by Get-Datastore
.EXAMPLE
PS> Get-DatastoreUnmountStatus -Datastore DS1
.EXAMPLE
PS> Get-Datastore | Get-DatastoreUnmountStatus
#>
param(
[CmdletBinding()]
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[PSObject[]]$Datastore
)
process
{
foreach ($ds in $Datastore)
{
if ($ds.GetType().Name -eq "string")
{
$ds = Get-Datastore -Name $ds
}
$parent = Get-View $ds.ExtensionData.Parent
New-Object PSObject -Property @{
Datastore = $ds.Name
# No Virtual machines
NoVM = $ds.ExtensionData.VM.Count -eq 0
<#
# Not in a Datastore Cluster
NoDastoreClusterMember = $parent -isnot [VMware.Vim.StoragePod]
# Not managed by sDRS
NosDRS = & {
if ($parent -is [VMware.Vim.StoragePod])
{
!$parent.PodStorageDrsEntry.StorageDrsConfig.PodConfig.Enabled
}
else { $true }
}
# SIOC disabled
NoSIOC = !$ds.StorageIOControlEnabled
# No HA heartbeat
NoHAheartbeat = & {
$hbDatastores = @()
$cls = Get-View -ViewType ClusterComputeResource -Property Host |
Where-Object { $_.Host -contains $ds.ExtensionData.Host[0].Key }
if ($cls)
{
$cls | % {
( $_.RetrieveDasAdvancedRuntimeInfo()).HeartbeatDatastoreInfo | % {
$hbDatastores += $_.Datastore
}
}
$hbDatastores -notcontains $ds.ExtensionData.MoRef
}
else { $true }
}
# No vdSW file
NovdSwFile = & {
New-PSDrive -Location $ds -Name ds -PSProvider VimDatastore -Root '\' | Out-Null
$result = Get-ChildItem -Path ds:\ -Recurse |
Where-Object { $_.Name -match '.dvsData' }
Remove-PSDrive -Name ds -Confirm:$false
if ($result) { $false }else { $true }
}
#>
# No scratch partition
NoScratchPartition = & {
$result = $true
$ds.ExtensionData.Host | % { Get-View $_.Key } | % {
$diagSys = Get-View $_.ConfigManager.DiagnosticSystem
$dsDisks = $ds.ExtensionData.Info.Vmfs.Extent | % { $_.DiskName }
if ($dsDisks -contains $diagSys.ActivePartition.Id.DiskName)
{
$result = $false
}
}
$result
}
}
}
}
}
Get-Datastore -PipelineVariable ds |
ForEach-Object -Process {
$result = Get-DatastoreUnmountStatus -Datastore $ds
if (($result.PSObject.Properties | Where-Object { $_.Name -match "^No" }).Value -notcontains $false)
{
$vm = Get-VM -Datastore $ds
$vmVmdk = (Get-VM | Get-HardDisk).FileName
New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root '\' | Out-Null
$vmdk = (Get-ChildItem -Path DS: -Recurse -Include '*.vmdk' | Where-Object { $vmVmdk -notcontains $_.DatastoreFullPath }).DatastoreFullPath
Remove-PSDrive -Name DS -Confirm:$false
if (-not $vm -and -not $vmdk)
{
Get-DatastoreMountInfo -Datastore $ds
Unmount-Datastore -Datastore $ds
Detach-Datastore -Datastore $ds
}
else
{
Write-Host "Datastore $dsName is not empty"
}
}
}
-
12. Re: Unmount datastores if unused and dettach them based on NAA
LucD Apr 18, 2019 9:30 AM (in response to momox1)What is Get-DatastoreUnmountStatus -Datastore $ds returning?
-
13. Re: Unmount datastores if unused and dettach them based on NAA
momox1 Apr 19, 2019 12:49 AM (in response to LucD) -
14. Re: Unmount datastores if unused and dettach them based on NAA
LucD Apr 19, 2019 2:56 AM (in response to momox1)Looks like the $ds variable is empty.
The limited output is mots probably due to the fact the the output doesn't fit on the console.
Pipe the result to Format-List.