Add files via upload
This commit is contained in:
6
Modules/VMFSIncrease/LICENSE.txt.URL
Normal file
6
Modules/VMFSIncrease/LICENSE.txt.URL
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[InternetShortcut]
|
||||||
|
URL=https://github.com/lucdekens/LogInsight/blob/v1.0/LICENSE.txt
|
||||||
|
IDList=
|
||||||
|
HotKey=0
|
||||||
|
IconFile=C:\Users\ldekens\AppData\Local\Mozilla\Firefox\Profiles\2ahnnh1i.default\shortcutCache\ec4nFcIEAQBPFmSiPtTJ2w==.ico
|
||||||
|
IconIndex=0
|
||||||
@@ -1 +1,18 @@
|
|||||||
|
@{
|
||||||
|
ModuleToProcess = 'VMFSIncrease.psm1'
|
||||||
|
ModuleVersion = '1.0.0.0'
|
||||||
|
GUID = '9f167385-c5c6-4a65-ac14-949c67519001'
|
||||||
|
Author = 'Luc Dekens '
|
||||||
|
CompanyName = 'Community'
|
||||||
|
Copyright = '(c) 2016. All rights reserved.'
|
||||||
|
Description = 'Expand and Extend VMFS DatastoresModule description'
|
||||||
|
PowerShellVersion = '3.0'
|
||||||
|
FunctionsToExport = 'Get-VmfsDatastoreInfo','Get-VmfsDatastoreIncrease','New-VmfsDatastoreIncrease'
|
||||||
|
PrivateData = @{
|
||||||
|
PSData = @{
|
||||||
|
Tags = @('VMFS','Expand','Extend','vSphere')
|
||||||
|
LicenseUri = 'https://www.tldrlegal.com/l/mit'
|
||||||
|
ProjectUri = 'https://github.com/lucdekens/VMFSIncrease'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
247
Modules/VMFSIncrease/VMFSIncrease.psm1
Normal file
247
Modules/VMFSIncrease/VMFSIncrease.psm1
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
function Get-VmfsDatastoreInfo
|
||||||
|
{
|
||||||
|
[CmdletBinding(SupportsShouldProcess = $True)]
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True)]
|
||||||
|
[PSObject]$Datastore
|
||||||
|
)
|
||||||
|
|
||||||
|
Process
|
||||||
|
{
|
||||||
|
if ($Datastore -is [String])
|
||||||
|
{
|
||||||
|
$Datastore = Get-Datastore -Name $Datastore -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
if ($Datastore -isnot [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore])
|
||||||
|
{
|
||||||
|
Write-Error 'Invalid value for Datastore.'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ($Datastore.Type -ne 'VMFS')
|
||||||
|
{
|
||||||
|
Write-Error "$($Datastore.Name) is not a VMFS datastore"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the Datastore System Manager from an ESXi that has the Datastore
|
||||||
|
$esx = Get-View -Id ($Datastore.ExtensionData.Host | Get-Random | Select -ExpandProperty Key)
|
||||||
|
$hsSys = Get-View -Id $esx.ConfigManager.StorageSystem
|
||||||
|
|
||||||
|
foreach ($extent in $Datastore.ExtensionData.Info.Vmfs.Extent)
|
||||||
|
{
|
||||||
|
$lun = $esx.Config.StorageDevice.ScsiLun | where{ $_.CanonicalName -eq $extent.DiskName }
|
||||||
|
|
||||||
|
$hdPartInfo = $hsSys.RetrieveDiskPartitionInfo($lun.DeviceName)
|
||||||
|
$hdPartInfo[0].Layout.Partition | %{
|
||||||
|
New-Object PSObject -Property ([ordered]@{
|
||||||
|
Datastore = $Datastore.Name
|
||||||
|
CanonicalName = $lun.CanonicalName
|
||||||
|
Model = "$($lun.Vendor.TrimEnd(' ')).$($lun.Model.TrimEnd(' ')).$($lun.Revision.TrimEnd(' '))"
|
||||||
|
DiskSizeGB = $hdPartInfo[0].Layout.Total.BlockSize * $hdPartInfo[0].Layout.Total.Block / 1GB
|
||||||
|
DiskBlocks = $hdPartInfo[0].Layout.Total.Block
|
||||||
|
DiskBlockMB = $hdPartInfo[0].Layout.Total.BlockSize/1MB
|
||||||
|
PartitionFormat = $hdPartInfo[0].Spec.PartitionFormat
|
||||||
|
Partition = if ($_.Partition -eq '') { '<free>' }else{ $_.Partition }
|
||||||
|
Used = $extent.Partition -eq $_.Partition
|
||||||
|
Type = $_.Type
|
||||||
|
PartitionSizeGB = [math]::Round(($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize / 1GB, 1)
|
||||||
|
PartitionBlocks = $_.End.Block - $_.Start.Block + 1
|
||||||
|
PartitionBlockMB = $_.Start.BlockSize/1MB
|
||||||
|
Start = $_.Start.Block
|
||||||
|
End = $_.End.Block
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-VmfsDatastoreIncrease
|
||||||
|
{
|
||||||
|
[CmdletBinding(SupportsShouldProcess = $True)]
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True)]
|
||||||
|
[PSObject]$Datastore
|
||||||
|
)
|
||||||
|
|
||||||
|
Process
|
||||||
|
{
|
||||||
|
if ($Datastore -is [String])
|
||||||
|
{
|
||||||
|
$Datastore = Get-Datastore -Name $Datastore -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
if ($Datastore -isnot [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore])
|
||||||
|
{
|
||||||
|
Write-Error 'Invalid value for Datastore.'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Datastore.Type -ne 'VMFS')
|
||||||
|
{
|
||||||
|
Write-Error "$($Datastore.Name) is not a VMFS datastore"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the Datastore System Manager from an ESXi that has the Datastore
|
||||||
|
$esx = Get-View -Id ($Datastore.ExtensionData.Host | Get-Random | Select -ExpandProperty Key)
|
||||||
|
$hsSys = Get-View -Id $esx.ConfigManager.StorageSystem
|
||||||
|
$hdSys = Get-View -Id $esx.ConfigManager.DatastoreSystem
|
||||||
|
|
||||||
|
$extents = $Datastore.ExtensionData.Info.Vmfs.Extent | Select -ExpandProperty DiskName
|
||||||
|
|
||||||
|
$hScsiDisk = $hdSys.QueryAvailableDisksForVmfs($Datastore.ExtensionData.MoRef)
|
||||||
|
foreach ($disk in $hScsiDisk)
|
||||||
|
{
|
||||||
|
$partInfo = $hsSys.RetrieveDiskPartitionInfo($disk.DeviceName)
|
||||||
|
$partUsed = ($partInfo[0].Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||||
|
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||||
|
if ($extents -contains $disk.CanonicalName)
|
||||||
|
{
|
||||||
|
$incType = 'Expand'
|
||||||
|
$vmfsExpOpt = $hdSys.QueryVmfsDatastoreExpandOptions($Datastore.ExtensionData.MoRef)
|
||||||
|
$PartMax = ($vmfsExpOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||||
|
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$incType = 'Extend'
|
||||||
|
$vmfsExtOpt = $hdSys.QueryVmfsDatastoreExtendOptions($Datastore.ExtensionData.MoRef, $disk.DevicePath, $null)
|
||||||
|
$partMax = ($vmfsExpOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||||
|
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||||
|
}
|
||||||
|
New-Object PSObject -Property ([ordered]@{
|
||||||
|
Datastore = $Datastore.Name
|
||||||
|
CanonicalName = $disk.CanonicalName
|
||||||
|
Model = "$($disk.Vendor.TrimEnd(' ')).$($disk.Model.TrimEnd(' ')).$($disk.Revision.TrimEnd(' '))"
|
||||||
|
DiskSizeGB = $partInfo[0].Layout.Total.BlockSize * $hdPartInfo[0].Layout.Total.Block / 1GB
|
||||||
|
DiskBlocks = $partInfo[0].Layout.Total.Block
|
||||||
|
DiskBlockMB = $partInfo[0].Layout.Total.BlockSize/1MB
|
||||||
|
AvailableGB = [math]::Round($partMax - $partUsed, 2)
|
||||||
|
Type = $incType
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function New-VmfsDatastoreIncrease
|
||||||
|
{
|
||||||
|
[CmdletBinding(SupportsShouldProcess = $True)]
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $True)]
|
||||||
|
[PSObject]$Datastore,
|
||||||
|
[int]$IncreaseSizeGB,
|
||||||
|
[Parameter(Position = 1)]
|
||||||
|
[string]$CanonicalName,
|
||||||
|
[Parameter(Mandatory = $true, ParameterSetName = 'Expand')]
|
||||||
|
[switch]$Expand,
|
||||||
|
[Parameter(Mandatory = $true, ParameterSetName = 'ExTend')]
|
||||||
|
[switch]$Extend
|
||||||
|
)
|
||||||
|
|
||||||
|
Process
|
||||||
|
{
|
||||||
|
if ($Datastore -is [String])
|
||||||
|
{
|
||||||
|
$Datastore = Get-Datastore -Name $Datastore -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
if ($Datastore -isnot [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore])
|
||||||
|
{
|
||||||
|
Write-Error 'Invalid value for Datastore.'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Datastore.Type -ne 'VMFS')
|
||||||
|
{
|
||||||
|
Write-Error "$($Datastore.Name) is not a VMFS datastore"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the Datastore System Manager from an ESXi that has the Datastore
|
||||||
|
$esx = Get-View -Id ($Datastore.ExtensionData.Host | Get-Random | Select -ExpandProperty Key)
|
||||||
|
$hsSys = Get-View -Id $esx.ConfigManager.StorageSystem
|
||||||
|
$hdSys = Get-View -Id $esx.ConfigManager.DatastoreSystem
|
||||||
|
|
||||||
|
$extents = $Datastore.ExtensionData.Info.Vmfs.Extent | Select -ExpandProperty DiskName
|
||||||
|
|
||||||
|
$hScsiDisk = $hdSys.QueryAvailableDisksForVmfs($Datastore.ExtensionData.MoRef)
|
||||||
|
|
||||||
|
# Expand or Extend
|
||||||
|
switch ($PSCmdlet.ParameterSetName)
|
||||||
|
{
|
||||||
|
'Expand' {
|
||||||
|
$expOpt = $hdSys.QueryVmfsDatastoreExpandOptions($Datastore.ExtensionData.MoRef)
|
||||||
|
if ($CanonicalName)
|
||||||
|
{
|
||||||
|
$dsOpt = $expOpt | where{ $_.Spec.Extent.DiskName -eq $CanonicalName }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$dsOpt = $expOpt | Sort-Object -Property { $_.Spec.Extent.Diskname } | select -first 1
|
||||||
|
}
|
||||||
|
if ($IncreaseSizeGB -ne 0)
|
||||||
|
{
|
||||||
|
$lun = $hScsiDisk | where{ $_.CanonicalName -eq $dsOpt.Spec.Extent.DiskName }
|
||||||
|
$partInfo = $hsSys.RetrieveDiskPartitionInfo($lun.DeviceName)
|
||||||
|
$partMax = ($vmfsExpOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||||
|
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||||
|
$partUsed = ($partInfo[0].Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||||
|
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||||
|
if (($partMax - $partUsed) -ge $IncreaseSizeGB)
|
||||||
|
{
|
||||||
|
$spec = $dsOpt.Spec
|
||||||
|
$spec.Partition.Partition[0].EndSector -= ([math]::Floor(($partMax - $partUsed - $IncreaseSizeGB) * 1GB/512))
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-Error "Requested expand size $($IncreaseSizeGB)GB not available on $($lun.CanonicalName)"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$spec = $dsOpt.Spec
|
||||||
|
}
|
||||||
|
$hdSys.ExpandVmfsDatastore($Datastore.ExtensionData.MoRef, $spec)
|
||||||
|
}
|
||||||
|
'Extend' {
|
||||||
|
if ($CanonicalName)
|
||||||
|
{
|
||||||
|
$lun = $hScsiDisk | where{ $extents -notcontains $_.CanonicalName -and $_.CanonicalName -eq $CanonicalName }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$lun = $hScsiDisk | where{ $extents -notcontains $_.CanonicalName } | Sort-Object -Property CanonicalName | select -First 1
|
||||||
|
}
|
||||||
|
if (!$lun)
|
||||||
|
{
|
||||||
|
Write-Error "No valid LUN provided or found for extent"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$vmfsExtOpt = $hdSys.QueryVmfsDatastoreExtendOptions($Datastore.ExtensionData.MoRef, $lun.DevicePath, $null)
|
||||||
|
if ($IncreaseSizeGB -ne 0)
|
||||||
|
{
|
||||||
|
$partInfo = $hsSys.RetrieveDiskPartitionInfo($lun.DeviceName)
|
||||||
|
$partMax = ($vmfsExpOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } |
|
||||||
|
Measure-Object -Sum | select -ExpandProperty Sum)/1GB
|
||||||
|
if ($partMax -ge $IncreaseSizeGB)
|
||||||
|
{
|
||||||
|
$spec = $vmfsExtOpt[0].Spec
|
||||||
|
$spec.Partition.Partition[0].EndSector = $spec.Partition.Partition[0].StartSector + [math]::Floor($IncreaseSizeGB * 1GB / 512)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-Error "No valid LUN for extent with $($IncreaseSizeGB)GB space found"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$spec = $vmfsExtOpt.Spec
|
||||||
|
}
|
||||||
|
|
||||||
|
$hdSys.ExtendVmfsDatastore($Datastore.ExtensionData.MoRef, $spec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Export-ModuleMember -Function Get-VmfsDatastoreInfo,Get-VmfsDatastoreIncrease,New-VmfsDatastoreIncrease
|
||||||
Reference in New Issue
Block a user