PowerCLI

 View Only
Expand all | Collapse all

Mount Replicated LUNs

  • 1.  Mount Replicated LUNs

    Posted Aug 26, 2013 02:31 AM

    Hi Team,

    I am trying to mount the replicated LUN(s) at a DR Site via PowerCLI Script. but getting some errors:

    Can someone please help?

    Here is the script:

    #prompt for ClusterName

    $cluster = Read-Host "Please enter the Cluster name"

    Get-Cluster $cluster | Get-VMHost | Get-VMHostStorage -RescanAllHba

    ForEach($esx in $cluster){

          # Check for unresolved UUID

          $VMHost = Get-VMHost

          $HstSys = Get-View $esx.id

          $HstDsSys = Get-View $HstSys.ConfigManager.DatastoreSystem

          $UnresVols = @($HstDsSys.QueryUnresolvedVmfsVolumes())

          # Resolve UUID for each on each ESXi host in the cluster

          $HstSSys = Get-view $esx.StorageInfo

          $UnresVols | %{

               $Extent = $_.Extent

               $DevicePath = $Extent.DevicePath

               $ResSpec = New-Object Vmware.Vim.HostUnresolvedVmfsResolutionSpec[](1)

               $ResSpec[0].ExtentDevicePath = $DevicePath

               $ResSpec[0].UuidResolution = “forceMount”

               $HstSSys.ResolveMultipleUnresolvedVmfsVolumes($ResSpec)

          }

          # Rescan for VMFS volumes

          #$esx | Get-VMHostStorage -RescanVmfs

       Get-VMHostStorage -VMHost $VMHost -RescanVmfs

    }

    Here is the output:

    Get-View : Cannot validate argument on parameter 'VIObject'. The argument is

    null or empty. Supply an argument that is not null or empty and then try the

    command again.

    At C:\Citi_Scripts\MountLUNs.ps1:48 char:26

    +       $HstSys = Get-View $esx.id

    +                          ~~~~~~~

        + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingVal

       idationException

        + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom

       ation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView

    Get-View : Cannot validate argument on parameter 'VIObject'. The argument is

    null or empty. Supply an argument that is not null or empty and then try the

    command again.

    At C:\Citi_Scripts\MountLUNs.ps1:49 char:28

    +       $HstDsSys = Get-View $HstSys.ConfigManager.DatastoreSystem

    +                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingVal

       idationException

        + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom

       ation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView

    You cannot call a method on a null-valued expression.

    At C:\Citi_Scripts\MountLUNs.ps1:50 char:22

    +       $UnresVols = @($HstDsSys.QueryUnresolvedVmfsVolumes())

    +                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

        + FullyQualifiedErrorId : InvokeMethodOnNull

    Get-View : Cannot validate argument on parameter 'VIObject'. The argument is

    null or empty. Supply an argument that is not null or empty and then try the

    command again.

    At C:\Citi_Scripts\MountLUNs.ps1:53 char:27

    +       $HstSSys = Get-view $esx.StorageInfo

    +                           ~~~~~~~~~~~~~~~~

        + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingVal

       idationException

        + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom

       ation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView



  • 2.  RE: Mount Replicated LUNs

    Posted Aug 26, 2013 04:22 AM

    Hi,

    I used to use esxcli command to mount replicated VMFS Volume, this is a simpler way of doing it.

    Please do some testing before applying the script to the Production environment.

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Script:

    $esxcli = Get-EsxCli -VMHost (Get-VMHost -Name)

    #Foreach replicated VMFS Volumes, using existing signature:

    foreach ($vmfs in $esxcli.storage.vmfs.snapshot.list())

    {

         $esxcli.storage.vmfs.snapshot.mount($false, $vmfs.VolumeName, $null)

    }

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------

    I suggest you to run $esxcli.storage.vmfs.snapshot.list() to see how it outputs.

    From the above, I think you will be able to write up a script that meets your requirement.

    Hope this helps,

    Steven.



  • 3.  RE: Mount Replicated LUNs

    Posted Aug 26, 2013 03:09 PM

    Hi Steven,

    The irony is, we do not have a test environment where we can test this script, not sure if this would work with an iSCSI LUN.

    Also, to stimulate, can we unmount the datastore and use the script to force mount it using the same signature?

    The requirements are simple, need to mount the replicated volumes onto the ESXi hosts are the DR site.

    Your thoughts please.

    Regards,

    Mohammed



  • 4.  RE: Mount Replicated LUNs

    Posted Aug 26, 2013 09:49 PM

    Hi Mohammed,


    It's going to work for iSCSI as you are simply mounting existing VMFS Volume (the raw disk is formatted and created as VMFS).

    Unmounting won't work, I've tried this myself in the past to see if this could be tested. Eventually, I had to setup a test mirror.


    I used the script above to migrate some virtual machines + DR situation, I don't see a problem with it.

    I think a test mirror should be setup, no matter how the script is written, even like a 1GB of mirrored disk should be fine!


    -Steven





  • 5.  RE: Mount Replicated LUNs

    Posted Aug 26, 2013 10:27 AM

    you do not have $esx variable in your script.

          $VMHost = Get-VMHost

          $HstSys = Get-View $esx.id

    So i guess you want to find $esx and replace it with $VMHost.



  • 6.  RE: Mount Replicated LUNs

    Posted Aug 26, 2013 03:13 PM

    Shouldn't it assume the $esxi variable from the foreach loop.

    ForEach($esx in $cluster){

          # Check for unresolved UUID

          $VMHost = Get-VMHost

          $HstSys = Get-View $esx.id

          $HstDsSys = Get-View $HstSys.ConfigManager.DatastoreSystem

          $UnresVols = @($HstDsSys.QueryUnresolvedVmfsVolumes())

    Do you the below should work?

    ForEach($esx in $cluster){

          # Check for unresolved UUID

          $VMHost = Get-Cluster $Cluster | Get-VMHost

          $HstSys = Get-View $VMHost.id

          $HstDsSys = Get-View $HstSys.ConfigManager.DatastoreSystem

          $UnresVols = @($HstDsSys.QueryUnresolvedVmfsVolumes())



  • 7.  RE: Mount Replicated LUNs

    Posted Aug 26, 2013 04:28 PM

    $cluster = Read-Host "Please enter the Cluster name"

      Get-Cluster $cluster | Get-VMHost | Get-VMHostStorage -RescanAllHba

    This part is wrong as the $cluster is a string so

    $clustername=Read-Host "Please enter the Cluster name"

    $cluster=get-cluster -name $clustername

    Then this loop

    ForEach($esx in $cluster){

          # Check for unresolved UUID

          $VMHost = Get-VMHost

          $HstSys = Get-View $esx.id

          $HstDsSys = Get-View $HstSys.ConfigManager.DatastoreSystem

          $UnresVols = @($HstDsSys.QueryUnresolvedVmfsVolumes())

    Is still wrong as it should be

    $hostsincluster=get-vmhost -Location $cluster

    ForEach($esx in $hostsincluster){

          # Check for unresolved UUID

          #$VMHost = Get-VMHost  -> that is not needed as it's in the $esx now so

          $VMhost=$esx

          $HstSys = Get-View $esx.id

          $HstDsSys = Get-View $HstSys.ConfigManager.DatastoreSystem

          $UnresVols = @($HstDsSys.QueryUnresolvedVmfsVolumes())

    Greg



  • 8.  RE: Mount Replicated LUNs

    Posted Aug 27, 2013 02:09 AM

    Here's the updated script:

    #prompt for ClusterName

    $clustername = Read-Host "Please enter the Cluster name"

    $cluster = Get-Cluster -name $clustername

    Get-Cluster $cluster | Get-VMHost | Get-VMHostStorage -RescanAllHba

    $hostsincluster = Get-VMHost -Location $cluster

    ForEach($esx in $hostsincluster){

         

       # Check for unresolved UUID

          $VMHost = $esx

          $HstSys = Get-View $esx.id

          $HstDsSys = Get-View $HstSys.ConfigManager.DatastoreSystem

          $UnresVols = @($HstDsSys.QueryUnresolvedVmfsVolumes())

          # Resolve UUID for each on each ESXi host in the cluster

       $HstSSys = Get-view $esx.StorageInfo

          $UnresVols | %{

               $Extent = $_.Extent

               $DevicePath = $Extent.DevicePath

               $ResSpec = New-Object Vmware.Vim.HostUnresolvedVmfsResolutionSpec[](1)

               $ResSpec[0].ExtentDevicePath = $DevicePath

               $ResSpec[0].UuidResolution = “forceMount”

               $HstSSys.ResolveMultipleUnresolvedVmfsVolumes($ResSpec)

          }

          # Rescan for VMFS volumes

          $VMHost | Get-VMHostStorage -RescanVmfs

      

    }



  • 9.  RE: Mount Replicated LUNs

    Posted Nov 12, 2013 09:14 PM

    Hi guys,

    I have been using the small script listed above to mount datastores in a DR site. It has been working fine! But the problem is, the loop below will only work with one ESXi host per time, and then I need your help with a new foreach loop fuction to execute the same command listed below but in all ESXi hosts members of my cluster. I have been trying different ways but unfortunately without success.

    You help is really appreciated!

    $esxHosts = Get-VMHost -Location $cluster | Sort Name

    foreach ($vmfs in $esxcli.storage.vmfs.snapshot.list())

    {

         $esxcli.storage.vmfs.snapshot.mount($false, $vmfs.VolumeName, $null)

    }

    Regards,



  • 10.  RE: Mount Replicated LUNs

    Posted Nov 12, 2013 09:29 PM

    You mean like this

    foreach($esx in (Get-VMHost -Location $cluster)){
       
    $esxcli = Get-EsxCli -VMHost $esx
       
    foreach ($vmfs in $esxcli.storage.vmfs.snapshot.list()){
           
    $esxcli.storage.vmfs.snapshot.mount($false, $vmfs.VolumeName, $null)
        }
    }


  • 11.  RE: Mount Replicated LUNs

    Posted Nov 12, 2013 09:36 PM

    Hi LucD,

    Exactly, its working now.

    I really appreciate your help!

    Regards,



  • 12.  RE: Mount Replicated LUNs

    Posted Nov 12, 2013 09:46 PM

    HI LuCD,

    One more question if you don't mind. The same part of your code I am trying to include a foreach for ESXi Hosts as well, so in this case instead of to work with only one ESXhost the foreach would work with all ESXi hosts members of the cluster.

    I have been trying to include something like:  Get-VMHost -Location $cluster | select Name, but its not woking

    thank you again!

    $Datastores = "prod*"

    $ESXHost =

    foreach($Datastore in Get-Datastore $Datastores) {

       # Set up Search for .VMX Files in Datastore

       $ds = Get-Datastore -Name $Datastore | %{Get-View $_.Id}

       $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec

       $SearchSpec.matchpattern = "*.vmx"

       $dsBrowser = Get-View $ds.browser

       $DatastorePath = "[" + $ds.Summary.Name + "]"

       # Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)

       $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}

       #Register all .vmx Files as VMs on the datastore

       foreach($VMXFile in $SearchResult) {

          New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $VMFolder -RunAsync

       }

    }



  • 13.  RE: Mount Replicated LUNs

    Posted Nov 12, 2013 10:11 PM

    This line

    foreach($esx in (Get-VMHost -Location $cluster)){

    already loops through all the ESXi hosts in the cluster.


    Or do you mean something else ?



  • 14.  RE: Mount Replicated LUNs

    Posted Nov 12, 2013 10:22 PM

    Hi LucD,

    The foreach($esx in (Get-VMHost -Location $cluster)){ for the first question is working fine and all datastores are up and running. Now, I am trying to add all VMs to the inventory using the script listed below. This script used to work in a non-cluster environment, but now I am getting weird errors... 


    $Datastores = "prod*"

    $ESXHost = Get-VMHost -Location $cluster | select -First 1

    $VMFolder = “dr01”

     

    foreach($Datastore in Get-Datastore $Datastores) {

       # Set up Search for .VMX Files in Datastore

       $ds = Get-Datastore -Name $Datastore | %{Get-View $_.Id}

       $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec

       $SearchSpec.matchpattern = "*.vmx"

       $dsBrowser = Get-View $ds.browser

       $DatastorePath = "[" + $ds.Summary.Name + "]"

       # Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)

       $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}

       #Register all .vmx Files as VMs on the datastore

       foreach($VMXFile in $SearchResult) {

          New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $VMFolder -RunAsync

       }

    }

    ERROR:

    New-VM : Cannot validate argument on parameter 'VMFilePath'. The argument is nu

    ll or empty. Supply an argument that is not null or empty and then try the comm

    and again.

    At C:\Users\test\Desktop\VMware DR\loop_foreach.ps1:20 char:25

    +       New-VM -VMFilePath <<<<  $VMXFile -VMHost $ESXHost -Location $VMFolder

    -RunAsync

        + CategoryInfo          : InvalidData: (:) [New-VM], ParameterBindingValid

       ationException

        + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom

       ation.ViCore.Cmdlets.Commands.NewVM



  • 15.  RE: Mount Replicated LUNs

    Posted Nov 12, 2013 10:35 PM

    Hi LucD,

    I got it. it was a wrong command/information that I was passing to the VMFolder variable.

    Everything is green! up and running.

    thank you again for you answers!

    Regards,



  • 16.  RE: Mount Replicated LUNs

    Posted Nov 12, 2013 10:36 PM

    Does this mean that you have datastores that are not shared between all the nodes in that cluster ?

    Otherwise only 1 node should be sufficient.

    You could also try the slightly different version from my VMX Raiders Revisited post.



  • 17.  RE: Mount Replicated LUNs

    Posted Nov 12, 2013 11:08 PM

    Hi LucD,

    I do have datastores shared between all the nodes in the cluster and one node is sufficient to boot all VMs.

    Thank you for sharing the VMX Raiders Revisited, its great and is working fine.

    Thank you again!

    Regards

    Andy



  • 18.  RE: Mount Replicated LUNs

    Posted Nov 27, 2013 06:05 PM

    Hi LucD,

    I have a quick question. As part of this script I am looking for a way to use get-view in combination with get-datastore to search for VMFS datastore status.

    I am working with this great script as found here in our community. This script will mount all datastores, but I am looking for a way to include an if/else statement to check the status of the datastore. So, if the datastore is mounted jump to another part of the code, if not run the Function Mount-Datastore listed below.

    Function Mount-Datastore {

            [CmdletBinding()]

            Param (

                    [Parameter(ValueFromPipeline=$true)]

                    $Datastore

            )

            Process {

                    if (-not $Datastore) {

                            Write-Host "No Datastore defined as input"

                            Break

                    } else {

                            Foreach ($ds in $Datastore) {

                                    $hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname

                                    if ($ds.ExtensionData.Host) {

                                            $attachedHosts = $ds.ExtensionData.Host

                                            Foreach ($VMHost in $attachedHosts) {

                                                    $hostview = Get-View $VMHost.Key

                                                    $StorageSys = Get-View $HostView.ConfigManager.StorageSystem

                                                    Write-Host "Mounting VMFS Datastore $($DS.Name) on host $($hostview.Name)..."

                                                    $StorageSys.MountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);

                                            }

                                    }

                            }

                    }

            }

    }

    Get-Datastore $Datastores | Mount-Datastore

    }

    else {

        Write-Host "The VMware Datastores $Datastores already are mounted!." -ForegroundColor Green

    }

    thanks for your help!



  • 19.  RE: Mount Replicated LUNs

    Posted Nov 27, 2013 06:48 PM

    Have a look at William's post called Automating Datastore/Storage Device Detachment in vSphere 5.

    With the Get-DatastoreMountInfo function in there you easily check on the mount status of a datastore.



  • 20.  RE: Mount Replicated LUNs

    Posted Nov 27, 2013 07:02 PM

    Hi LucD, Sure.

    I have combined those nice scripts and included more filters on at... Now ,I am getting the status of each datastore (if they are mounted or not). So, I am looking for a simple if/else statement that will mount all datastores with "false" output. For example, if "False" mount them, if not jump to another part of the script...

    See below. thank you for your help

    $Datastores = Get-Datastore | where {$_.Type -eq "VMFS"} | Select Name,@{N="NAA";E={$_.ExtensionData.Info.Vmfs.Extent | Select -ExpandProperty DiskName}} | Where-Object {$_.NAA -like "naa.*"}  | Select -ExpandProperty Name | sort Name

    if ($Datastores -eq $null) {

    Function Mount-Datastore {

            [CmdletBinding()]

            Param (

                    [Parameter(ValueFromPipeline=$true)]

                    $Datastore

            )

            Process {

                    if (-not $Datastore) {

                            Write-Host "No Datastore defined as input"

                            Break

                    } else {

                            Foreach ($ds in $Datastore) {

                                    $hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname

                                    if ($ds.ExtensionData.Host) {

                                            $attachedHosts = $ds.ExtensionData.Host

                                            Foreach ($VMHost in $attachedHosts) {

                                                    $hostview = Get-View $VMHost.Key

                                                    $StorageSys = Get-View $HostView.ConfigManager.StorageSystem

                                                    Write-Host "Mounting VMFS Datastore $($DS.Name) on host $($hostview.Name)..."

                                                    $StorageSys.MountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);

                                            }

                                    }

                            }

                    }

            }

    }

    Get-Datastore $Datastores | Mount-Datastore

    } else {

    Function Get-DatastoreMountInfo {

        [CmdletBinding()]

        Param (

            [Parameter(ValueFromPipeline=$true)]

            $Datastore

        )

        Process {

            $AllInfo = @()

            if (-not $Datastore) {

                $Datastore = Get-Datastore

            }

            Foreach ($ds in $Datastore) { 

                if ($ds.ExtensionData.info.Vmfs) {

                    $hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].diskname

                    if ($ds.ExtensionData.Host) {

                        $attachedHosts = $ds.ExtensionData.Host

                        Foreach ($VMHost in $attachedHosts) {

                            $hostview = Get-View $VMHost.Key

                            $hostviewDSState = $VMHost.MountInfo.Mounted

                            $StorageSys = Get-View $HostView.ConfigManager.StorageSystem

                            $devices = $StorageSys.StorageDeviceInfo.ScsiLun

                            Foreach ($device in $devices) {

                                $Info = "" | Select Datastore, VMHost, Lun, Mounted, State

                                if ($device.canonicalName -eq $hostviewDSDiskName) {

                                    $hostviewDSAttachState = ""

                                    if ($device.operationalState[0] -eq "ok") {

                                        $hostviewDSAttachState = "Attached"                           

                                    } elseif ($device.operationalState[0] -eq "off") {

                                        $hostviewDSAttachState = "Detached"                           

                                    } else {

                                        $hostviewDSAttachState = $device.operationalstate[0]

                                    }

                                    $Info.Datastore = $ds.Name

                                    $Info.Lun = $hostviewDSDiskName

                                    $Info.VMHost = $hostview.Name

                                    $Info.Mounted = $HostViewDSState

                                    $Info.State = $hostviewDSAttachState

                                    $AllInfo += $Info

                                }

                            }

                           

                        }

                    }

                }

            }

            $AllInfo

        }

    }

    Get-Datastore $Datastores | Get-DatastoreMountInfo | Select -ExpandProperty Mounted

    }



  • 21.  RE: Mount Replicated LUNs

    Posted Nov 27, 2013 07:40 PM

    You could use a Where-clause like this

    Get-Datastore $Datastores | Where {!($_ | Get-DatasoreMountInfo | Select -ExpandProperty Mounted)} | %{

    # Mount the datastore

    }

    Only the datastores that are not mounted will enter the ForEach code block.



  • 22.  RE: Mount Replicated LUNs

    Posted Apr 10, 2025 05:18 PM

    Thanks LucD - this worked for me although it was very slow and had to run it more than twice to get all 6 hosts in the cluster to pick up the one LUN.  I am planning to use it soon for a migration with ~90 LUNs on 5 hosts. I think it might take hours to complete.

    Is there an updated -V2 version of this? 




  • 23.  RE: Mount Replicated LUNs

    Posted Apr 13, 2025 07:54 AM
    Edited by Ayman Mahmoud Apr 13, 2025 07:55 AM

    Hi Adrian,

    this function will mount replicated LUNs without re-signature them, hope it works

    # Mounting Snapshot without resignature
    # ----------------------------------------
    function MountNoSignature{
    foreach ($HostMount in (Get-VMHost)){

        $esxcli = Get-EsxCli -VMHost $HostMount -v2 
        $ToMountLUNs = $esxcli.storage.vmfs.snapshot.list.Invoke() | select-object VolumeName

        foreach ($Lun2Mount in $ToMountLUNs){
                $MapArgs = $esxcli.storage.vmfs.snapshot.mount.CreateArgs()
                $MapArgs.volumelabel = "$($Lun2Mount.VolumeName)"
                $MapArgs.nopersist   = $true
                $esxcli.storage.vmfs.snapshot.mount.Invoke($MapArgs)
                                                            

        }

    }
    }




  • 24.  RE: Mount Replicated LUNs

    Posted 16 days ago

    Thanks - it's working but...

    For the line:   $MapArgs.nopersist   = $true

    Will this persist through a reboot or not?

    Thanks,

    Adrian



    ------------------------------
    AdrianR
    ------------------------------