#requires -version 2.0 Function Get-NaLun { <# .Synopsis Get the status of the given LUN, or all LUNs. .Description Get the status (size, online/offline state, shared state, comment string, serial number, LUN mapping) of the given LUN, or all LUNs. .Parameter Path Path of LUN. If specified, only the information of that LUN is returned. If not specified, then information of all LUNs are returned. .Parameter Server NaServer to query .Example # Get Get-NaLun -Path /vol/vol_test/lun1 .Outputs NetApp.SDK.NaLun[] .Link Set-NaLun New-NaLun Remove-NaLun Move-NaLun Set-NaLunSize #> [CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")] param ( [Parameter(ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of LUN.")] [string] $Path, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Process { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-list-info") #$request.AddNewChild("get-clone-backing-snapshot",$True) if ($Path) { $request.AddNewChild("path",$Path) } try { $result = ([xml]$server.InvokeElem($request)).results } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message $result = $null continue; } if ($? -and $result.luns){ if (ConvertFrom-NaBool $result."are-vols-onlining") { Write-Warning "Volumes are still in the process of onlining.the output of this command cannot be considered authoritative." } $result."luns"."lun-info" |% { return New-Object NetApp.SDK.NaLun -ArgumentList @( $_."path", $_."size", $_."block-size", (ConvertFrom-NaBool $_."online"), $_."serial-number", (ConvertFrom-NaBool $_."read-only"), (ConvertFrom-NaBool $_."is-space-reservation-enabled"), (ConvertFrom-NaBool $_."mapped"), $_."multiprotocol-type", $_."share-state", $_."uuid", $_."device-id", $_."backing-snapshot", $_."clone-backing-snapshot" ) } } } } Function New-NaLun { <# .Synopsis Create a new lun .Description Create a new lun, with initially zero contents. The lun is created at the path given. No file should already exist at the given path. .Parameter Path Path of the LUN. .Parameter Size New size for the LUN in bytes. Create a new lun of given size, with initially zero contents. The lun is created at the path given. No file should already exist at the given path. The directory specified in the path must be a qtree root directory. The size of the created lun could be larger than the size specified, in order to get an integral number of cylinders while reporting the geometry using SAN protocols. .Parameter FromFile A fully qualified filer path to the file to create the LUN from. This must be in the same qtree as the LUN being created. Create a lun from an existing file. A new lun is created, at the given path (which must be at a qtree root). A hard link is created to the existing file. The file contents are not copied or changed. The file can be resized to a larger size, rounding up to a cylinder boundary. .Parameter FromSnapshot LUN path in the snapshot to be created from. Creates a LUN in the active file system. The lun has the same initial contents as the referenced snapshot copy of an existing lun. (Note that no copy of the data is made.) Future writes go into the new lun. Reads of unmodified data are satisfied from the snapshot location. Reads of modified data are satisfied by first attempting to find the required buffer in the new lun. If a buffer is not found (buffer corresponds to a hole), it is looked for in the snapshot copy instead. .Parameter OSType Type of LUN. While optional, the caller should specify a non-default ostype. Currently, supported ostypes: "solaris" the lun will be used to store a Solaris raw disk in a single-slice partition "windows" the lun will be used to store a raw disk device in a single-partition Windows disk "hpux" the lun will be used to store HP-UX data "aix" the lun will be used to store AIX data "linux" the lun will be used to store a Linux raw disk without any partition table "netware" the lun will be used to store NetWare data "vmware" the lun will be used to store VMWARE data "windows_gpt" the lun will be used to store Windows data using the GPT partitioning style "windows_2008" the lun will be used to store Windows data on Windows 2008 systems "openvms" the lun will be used to store OpenVMS data .Parameter NoSpaceReserve By default, the lun is space-reserved. If it is desired to manage space usage manually instead, the NoSpaceReserve switch will create a LUN without any space being reserved. .Parameter Server NaServer to query .Example #Create a 20GB LUN Named lun0 in vmdata3 PS > New-NaLun -Path /vol/vmdata3/lun0 -Size 20GB .Example # Create a new lun from a snapshot PS > New-NaSnapshot -Name clone_base -Volume vmdata3 PS > New-NaLun -Path /vol/vmdata3/lun2 -FromSnapshot /vol/vmdata3/.snapshot/clone_base/lun0 -NoSpaceReserve .Outputs NetApp.SDK.NaLun[] .Link Get-NaLun Set-NaLun Remove-NaLun Move-NaLun .Notes NAME: New-NaLun AUTHOR: Glenn Sizemore #Requires -Version 2.0 #> [CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")] param ( [Parameter(Mandatory=$TRUE,Position=0,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [STRING] $Path, [Parameter(Mandatory=$TRUE,ParameterSetName="size",ValueFromPipelineByPropertyName=$TRUE,HelpMessage="New size for the LUN in Bytes.")] [Int64] $Size, [Parameter(Mandatory=$TRUE,ParameterSetName="file",HelpMessage="A fully qualified filer path to the file to create the LUN from.")] [string] $FromFile, [Parameter(Mandatory=$TRUE,ParameterSetName="snapshot",HelpMessage="LUN path in the snapshot to be created from.")] [string] $FromSnapshot, [Parameter(Position=2,ValueFromPipelinebypropertyname=$TRUE,HelpMessage="The ostype for the LUN.")] [ValidateSet("image", "solaris", "windows", "hpux", "aix", "linux", "netware", "vmware", "windows_gpt", "windows_2008", "openvms")] [string] $OSType, [Parameter()] [switch] $NoSpaceReserve, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) process { if ($Server.Version -gt 1.8) { if ($FromFile) { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-from-file") $request.AddNewChild("file-name",$FromFile) if ($OSType) { $request.AddNewChild("ostype", $OSType) } } elseif ($FromSnapshot) { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-from-snapshot") $request.AddNewChild("snapshot-lun-path",$FromSnapshot) if ($OSType) { $request.AddNewChild("type", $OSType) } } else { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-by-size") $request.AddNewChild("size",$Size) if ($OSType) { $request.AddNewChild("OStype", $OSType) } } } Else { if ($FromFile) { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-from-file") $request.AddNewChild("file-name",$FromFile) if ($OSType) { $request.AddNewChild("type", $OSType) } } elseif ($FromSnapshot) { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-from-snapshot") $request.AddNewChild("snapshot-lun-path",$FromSnapshot) if ($OSType) { $request.AddNewChild("type", $OSType) } } else { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-create-by-size") $request.AddNewChild("size",$Size) if ($OSType) { $request.AddNewChild("type", $OSType) } } } $request.AddNewChild("path",$Path) if ($NoSpaceReserve) { $request.AddNewChild("space-reservation-enabled",$FALSE) } else { $request.AddNewChild("space-reservation-enabled",$TRUE) } if ($pscmdlet.ShouldProcess($Server.server, "Creating lun $Path")) { try { $server.InvokeElem($request)|out-null } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message continue; } if ($?){ return Get-NaLun -Path $Path -Server $Server } } } } Function Set-NaLun { <# .Synopsis Create a new lun .Description Create a new lun, with initially zero contents. The lun is created at the path given. No file should already exist at the given path. .Parameter Path Path of the LUN. .Parameter Offline Disables block-protocol accesses to the LUN. Mappings, if any, configured for the lun are not altered. Note that unless explicitly offlined, a lun is online. .Parameter Online Re-enables block-protocol accesses to the lun. .Parameter Force Forcibly online the lun, disabling mapping onflict checks with the cluster partner. If not specified all conflict checks are performed. .Parameter Description Set the optional descriptive comment for a LUN. .Parameter SerialNumber Set the serial number for the specified LUN. The lun must first be made offline before changing the serial number. The serial number is a 12-character string formed of upper and lower-case letters, numbers, and slash (/) and hyphen (-) characters. .Parameter DeviceID Set the SCSI Device Identifier for the Lun. .Parameter Server NaServer to query .Example # offline lun0 PS > Set-NaLun -Path /vol/vol1/lun0 -offline .Example # online lun0 PS > Set-NaLun -Path /vol/vol1/lun0 -online .Example # Set the description for the /vol/vol1/vmdata lun PS > Set-NaLun -Path /vol/vol1/vmdata -Description "testing lun" .Outputs NetApp.SDK.NaLun[] .Link Get-NaLun New-NaLun Remove-NaLun .Notes NAME: Set-NaLun AUTHOR: Glenn Sizemore #Requires -Version 2.0 #> [CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")] param( [Parameter(ParameterSetName="offline",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [Parameter(ParameterSetName="online",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [Parameter(ParameterSetName="desc",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [Parameter(ParameterSetName="sn",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [Parameter(ParameterSetName="deviceID",Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [string] $Path, [Parameter(ParameterSetName="offline")] [switch] $Offline, [Parameter(ParameterSetName="online")] [switch] $Online, [Parameter(ParameterSetName="desc")] [string] $Description, [Parameter(HelpMessage="Set the serial number for the specified LUN.",ParameterSetName="sn")] [string] $SerialNumber, [Parameter(HelpMessage="Set the SCSI Device Identifier for the Lun.",ParameterSetName="deviceID")] [string] $DeviceID, [Parameter(ParameterSetName="online")] [switch] $Force, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Process { switch ($PSCmdlet.ParameterSetName) { "online" { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-online") $msg = "Online Lun $($path)" if ($force) { $request.AddNewChild("force",$TRUE) } } "offline" { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-offline") $msg = "Offline Lun $($path)" } "desc" { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-set-comment") $request.AddNewChild("comment",$Description) $msg = "Setting $($path) description to $($Description)" } "sn" { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-set-serial-number") $request.AddNewChild("serial-number",$SerialNumber) $msg = "Changing $($path) serial number to $($serialNumber)" } "deviceID" { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-set-device-id") $request.AddNewChild("device-id",$DeviceID) $msg = "Changing $($path) SCSI Device Identifier to $($DeviceID)" } } $request.AddNewChild("path",$path) if ($pscmdlet.ShouldProcess($path,$msg)) { try { $server.InvokeElem($request)#|out-null } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message continue; } if ($?){ return Get-NaLun -Path $Path -Server $Server } } } } Function Remove-NaLun { <# .Synopsis Destroy the specified LUN. .Description Destroy the specified LUN. This operation will fail if the LUN is currently mapped and is online. The force option can be used to destroy it regardless of being online or mapped. .Parameter Path Path of the LUN. .Parameter Force Forcibly destroy the LUN regardless of it being online or mapped. .Parameter Server NaServer to query .Example # Delete the /vol/vol1/lun6 lun PS > Set-NaLun -Path /vol/vol1/lun6 | Remove-NaLun -confirm .Link Get-NaLun New-NaLun Set-NaLun #> [CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="high",DefaultParameterSetName="")] param( [Parameter(Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [string] $Path, [Parameter()] [switch] $Force, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Process { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-destroy") if ($force) { $request.AddNewChild("force",$TRUE) } $request.AddNewChild("path",$path) if ($pscmdlet.ShouldProcess($server.server,"Destroying lun $path")) { try { $server.InvokeElem($request)|out-null } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message continue; } } } } function Set-NaLunSize { <# .Synopsis Changes the size of the lun. .Description Changes the size of the lun. Note that client-side operations may be needed to ensure that client software recognizes the changed size. .Parameter Path Path of the LUN. .Parameter Size New size for the LUN. .Parameter Force Forcibly reduce the size. This is required for reducing the size of the LUN to avoid accidentally reducing the LUN size. .Parameter Server NaServer to query .Example Resize Lun0 to 50GB PS > Set-NaLunSize -Path /vol/vol1/Lun0 -Size 50GB .Outputs PSObject .Link Get-NaLun New-NaLun Remove-NaLun #> [CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")] param( [Parameter(Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [string] $Path, [Parameter(Position=1,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="New size for the LUN in Bytes.")] [int] $Size, [Parameter()] [switch] $Force, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Process { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-resize") if ($force) { $request.AddNewChild("force",$TRUE) } $request.AddNewChild("path",$Path) $request.AddNewChild("size",$Size) if ($pscmdlet.ShouldProcess($server.server, "Resizing $Path to $($size/1mb)MB")) { try { $server.InvokeElem($request)|out-null } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message continue; } if ($?){ return Get-NaLun -Path $Path -Server $Server } } } } function Move-NaLun { <# .Synopsis Move (rename) a LUN. .Description Move (rename) a LUN. .Parameter Path Path of the LUN. .Parameter NewPath New path of the LUN being moved to. .Parameter Server NaServer to query .Example Move/Rename Lun0 to Lun1 PS > Move-NaLunSize -Path /vol/vol1/Lun0 -NewPath /vol/vol1/Lun1 .Outputs PSObject .Link Get-NaLun New-NaLun Set-NaLun #> [CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")] param( [Parameter(Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [string] $Path, [Parameter(Position=1,Mandatory=$TRUE,HelpMessage="New path of the LUN being moved(renamed) to.")] [string] $NewPath, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Process { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-move") $request.AddNewChild("path",$path) $request.AddNewChild("new-path",$NewPath) if ($pscmdlet.ShouldProcess("moving $path to $NewPath ")) { try { $server.InvokeElem($request)|out-null } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message continue; } if ($?){ return Get-NaLun -Path $NewPath -Server $Server } } } } Function Test-NaLunPortSCSIReservations { <# .Synopsis Queries for all types of scsi reservations. .Description Queries for all types of scsi reservations covering both iSCSI and FCP for a given initiator portname. .Parameter Path Path of the LUN. .Parameter PortName Name of the port. .Parameter Server NaServer to query .Example .Outputs Bool .Link Get-NaLun New-NaLun Set-NaLun #> [CmdletBinding(SupportsShouldProcess=$False,SupportsTransactions=$False,ConfirmImpact="none",DefaultParameterSetName="" )] param( [Parameter(Position=0,Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of the LUN.")] [string] $Path, [Parameter(Position=1,Mandatory=$TRUE,HelpMessage="Name of the port.")] [string] $portname, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Process { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-port-has-scsi-reservations") $request.AddNewChild("path",$path) $request.AddNewChild("portname",$portname) try { $result = ([xml]$server.InvokeElem($request)).results } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message $result = $null continue; } if ($?) { return ConvertFrom-NaBool $result."is-reservation-held" } } } Function Get-NaLunMap { <# .Synopsis Returns a list of initiator groups and their members (the initiators) mapped to the given LUN. .Description Returns a list of initiator groups and their members (the initiators) mapped to the given LUN. .Parameter Path LUN for which the initiator group list is requested. .Parameter Server NaServer to query .Example # Get the Lun Map info for all luns PS > Get-NaLun | Get-NaLunMap .Outputs NetApp.SDK.NaLun[] .Link Set-NaLun New-NaLun Remove-NaLun Move-NaLun Set-NaLunSize #> [CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")] param ( [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of LUN.")] [string] $Path, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Process { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-map-list-info") $request.AddNewChild("path",$Path) try { $result = ([xml]$server.InvokeElem($request)).results } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message $result = $null continue; } if ($?){ $result."initiator-groups"."initiator-group-info" | ?{$_."initiator-group-name"}|% { return New-Object NetApp.SDK.NaLunMap -ArgumentList @( $Path, $_."initiator-group-name", $_."lun-id", $_."initiator-group-os-type", $_."initiator-group-portset-name", $_."initiator-group-type", [array]($_."initiators"."initiator-info"|%{$_."initiator-name"}), (ConvertFrom-NaBool $_."initiator-group-alua-enabled"), (ConvertFrom-NaBool $_."initiator-group-throttle-borrow"), $_."initiator-group-throttle-reserve", (ConvertFrom-NaBool $_."initiator-group-vsa-enabled"), (ConvertFrom-NaBool $_."initiator-group-use-partner") ) } } } } function Add-NaLunMap { <# .Synopsis Maps the LUN to all the initiators in the specified initiator group. .Description Maps the LUN to all the initiators in the specified initiator group. .Parameter Path LUN for which the initiator group list is requested. .Parameter IGroup Initiator group to map to the given LUN. .Parameter LunID If the lun-id is not specified, the smallest number that can be used for the various initiators in the group is automatically picked. .Parameter Force Forcibly map the lun, disabling mapping conflict checks with the cluster partner. If not specified all conflict checks are performed. .Parameter Server NaServer to query .Example # Map /vol/vmdata3/lun3 to the VMware IGroup with a lunID of 3 PS > Add-NaLunMap -Path /vol/vmdata3/lun3 -IGroup VMware -LunID 3 .Outputs NetApp.SDK.NaLunMap[] .Link Get-NaLun Get-NaLunMap Remove-NaLunMap #> [CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")] param ( [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of LUN.")] [string] $Path, [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Initiator group to map to the given LUN. ")] [string] $IGroup, [Parameter(ValueFromPipelineByPropertyName=$TRUE,HelpMessage="ID to map lun to.")] [string] $LunID, [Parameter(ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Forcibly map the lun.")] [string] $Force, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Process { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-map") $request.AddNewChild("path",$Path) $request.AddNewChild("initiator-group",$IGroup) if ($LunID) { $request.AddNewChild("lun-id",$LunID) } if ($Force) { $request.AddNewChild("force",$Force) } if ($pscmdlet.ShouldProcess($Server.server, "Mapping $Path to $($IGroup):$($LunID)")) { Try { $server.InvokeElem($request)|out-null } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message continue; } if ($?){ return Get-NaLunMap -Path $Path -Server $Server } } } } function Remove-NaLunMap { <# .Synopsis Reverses the effect of lun-map on the specified LUN for the specified group. .Description Reverses the effect of lun-map on the specified LUN for the specified group. .Parameter Path Path of the LUN. .Parameter IGroup Name of the IGroup to unmap. .Parameter Server NaServer to query .Example Get-NaLunMap -Path /vol/vol1/lun1 -IGroup VMware .Example Get-NaLun | Get-NaLunMap |?{$_.IGroup -match "VMware2"}|Remove-NaLunMap .Outputs NetApp.SDK.NaLunMap[] .Link Get-NaLun Get-NaLunMap Add-NaLunMap #> [CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="high",DefaultParameterSetName="")] param ( [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Path of LUN.")] [string] $Path, [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Initiator group to map to the given LUN.")] [string] $IGroup, [Parameter(HelpMessage="NaServer to query")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Process { $request = New-Object Netapp.Manage.NaElement -ArgumentList @("lun-unmap") $request.AddNewChild("path",$Path) $request.AddNewChild("initiator-group",$IGroup) if ($pscmdlet.ShouldProcess($Server.server, "Unmapping $($Path) From $($IGroup)")) { Try { $server.InvokeElem($request)|out-null } catch [NetApp.Manage.NaApiFailedException]{ Write-Warning $_.Exception.GetBaseException().message continue; } if ($?){ return Get-NaLunMap -Path $Path -Server $Server } } } }