Pure.psm1
# Non-Exported Functions . $PSScriptRoot\Local\Get-ArrayInfoXML.ps1 . $PSScriptRoot\Local\Export-PSCredentials.ps1 . $PSScriptRoot\Local\Import-PSCredentials.ps1 function Get-PureIpAddress { Param( [string]$pureName) # Load XMLDB & Validate Org Param $Script:xmlDB = Get-ArrayInfoXML; if ([string]::IsNullOrEmpty($org)){ $unique = $Script:xmlDB.SelectNodes("//Array") | Select-Object -Property Org, Name -Unique; $Script:org = $unique[0].Org } else { $unique = $Script:xmlDB.SelectNodes("//Array") | Where-Object {$_.Org -match $Org } | Select-Object -Property Org, Name -Unique; if ($unique -is [Object]) { $Script:org = $unique[0].Org } else { Write-Host "$Org not not found in the XMLDB" -ForegroundColor Red return $null } } Write-Verbose "Org is $Script:org" # # Get Pure Storage array data $unique = $Script:xmlDB.SelectNodes("//Array") | Where-Object { $_.Class -match "Pure" -and $_.Org -match $Script:org -and $_.Name -eq $pureName} | Select-Object -Property Name, username, remote; if ($unique -is [Object]) { $ip = $unique[0].remote; $Script:username = $unique[0].username; Write-Verbose "Username: $Script:username" return $ip } else { Write-Host "$pureName " -ForegroundColor Red -NoNewline Write-Host "is not a valid " -ForegroundColor Blue -NoNewline Write-Host "Pure Storage " -ForegroundColor Red -NoNewline Write-Host "array in the XMLDB" -ForegroundColor Blue return $null } # } function Set-Credentials { Param ([string]$borg, [string]$username) $credBase = "-" + $borg + "-" + $env:COMPUTERNAME + $credExt; $Script:credfilename = $Global:CRPath + "\" + $username + $credBase; if (!(Test-Path $Script:credfilename)) { # create cache credential Write-Host "Pure Credentials require for $borg Storage" -ForegroundColor Green Export-PSCredential $username $credBase Start-Sleep 3; } $Script:cred = Import-PSCredential $Script:credfilename Write-Verbose "Loaded $Script:credfilename" } function Set-PureArray { param ([string]$ip,[object]$cr) try { $pure = New-PfaArray -EndPoint $ip -Credentials $cr -IgnoreCertificateError } catch { $pure = "New-PfaArray -EndPoint $ip failed"; } return $pure; } function Test-VolumeMasking { param ([object]$pureObj, [string]$server, [string]$volName) $hostvols = Get-PfaHostVolumeConnections -array $pureObj -Name $server; [bool]$volMasked = $false; ForEach-Object -InputObject $hostvols { if ($_.vol -eq $volName) {$volMasked = $true} } return $volMasked } # # Exported Functions <# .SYNOPSIS Show volumes masked to named host on a given PureSystem storage array. .DESCRIPTION Executes cmdlets in the Pure Storage PowerShell SDK 1.7.4 module to display volumes masked to a host on a specific PureSystem storage array. .PARAMETER pureNAME PureSystem array name. .PARAMETER hostName Name of the desired host. .PARAMETER org Name of the organiztion responsible for the PureStorage array. Uses the default org value in the XMLDB .INPUTS <username>-<org>-<hostname>.emc.xml Contains encrypted credentials for the 'username' account. If the file is not present, there will be prompt for the credentials and the file will be regenerated. The file can only be decrypted on system it was created on. .OUTPUTS List of volumes masked to a host. .OUTPUTS <username>-<org>-<hostname>.emc.xml Pureuser account encrypted credentials. .EXAMPLE Show-VePureHostVols -pureName bowpure002 -hostname testdummy02 vol name lun hgroup --- ---- --- ------ testdummy02_T testdummy02 1 testdummy01_S_X testdummy02 2 name created source Size(GB) ---- ------- ------ -------- testdummy02_T 2017-06-05T21:19:59Z 10 testdummy01_S_X 2017-06-09T19:20:33Z testdummy01_S 10 .EXAMPLE Show-VePureHostVols bowpure002 testdummy02 Show-VePureHostVols -pureName bowpure002 -hostname testdummy02 Same as the prior example but the options are explicitedly provided. .NOTES Requires Installation of PureSystem PowerShell module. Execute the following to install PureStorage PowerShell module. Install-Module -Name PureStoragePowerShellSDK -scope currentuser Author: Craig Dayton 0.0.2.4 07/29/2017 : cadayton : Initial Release .LINK https://github.com/cadayton/Venom .LINK http://venom.readthedocs.io #> function Show-VePureHostVols { # Show-VePureHostVols Params [cmdletbinding()] Param ( [Parameter(Position=0, Mandatory=$False, ValueFromPipeline=$True)] [string]$pureName, [Parameter(Position=1, Mandatory=$False, ValueFromPipeline=$True)] [string]$hostName, [Parameter(Position=2, Mandatory=$False, ValueFromPipeline=$True)] [string]$org ) # Write-Host "Show-PureHostVols version 0.0.2.4" -ForegroundColor Green $ip = Get-PureIpAddress $pureName; Write-Verbose "$pureName IpAddress is $ip" if ([string]::IsNullOrEmpty($ip)) { Write-Host "Check your spelling" -ForegroundColor Blue; return 1; } Set-Credentials $Script:org $Script:username $pure = Set-PureArray $ip $Script:cred; if ($pure -is [String]) { # Object expected Write-Host $pure -ForegroundColor Red; Write-Host "Try pinging $pureName using the IP address" -ForegroundColor Blue; return 2; } try { $hostvols = Get-PfaHostVolumeConnections -array $pure -Name $hostName; } Catch { $errRslt = "Error processing Get-PfaHostVolumeConnections" Write-Host $errRslt -ForegroundColor Red Write-Host "Likely the host name $hostName doesn't exist on $pureName" -ForegroundColor Blue return 3; } $hostvols | Format-Table -AutoSize; ForEach-Object -InputObject $hostvols { $vols = $_.vol; $volattrs = @(); if ($_.vol.count -gt 1) { for($i=0; $i -lt $_.vol.count; $i++) { $volattr = Get-PfaVolume -Array $pure -Name $vols[$i]; $volattrs += $volattr; } $volattrs | Select-Object name, created, source, serial, @{Name="Size(GB)"; Expression={$_.size / 1GB}} | Format-Table -AutoSize; } else { Get-PfaVolume -Array $pure -Name $_.vol | Select-Object name, created, source, serial, @{Name="Size(GB)"; Expression={$_.size / 1GB}} | Format-Table -AutoSize; } } } <# .SYNOPSIS Creates a PureStorage SNAP volume from an existing disk volume. .DESCRIPTION Creates a SNAP of a host's volume and optionally masks the SNAP to a different host. If the SNAP volume exists, it will be overwritten. If the SNAP volume does not exist, it will be created. If a target host is specified, the SNAP volume will be masked to the target host. .PARAMETER pureName Name of the PureStorage array were volume exists. .PARAMETER source Host name who owns the volume from which a SNAP volume will be created. .PARAMETER vol Name of disk volume to be copied. .PARAMETER target Specify a target host name to mask the SNAP volume. If a target is not specified, the SNAP volume will not be masked to any host. .PARAMETER suffix A suffix value to be appended to the SNAP volume name. Default is "X" and max size is 4 characters. .INPUTS <username>-<org>-<hostname>.emc.xml Contains encrypted credentials for the user account. If the file is not present, there will be prompt for the credentials and the file will be regenerated. The file can only be decrypted on system it was created on. .OUTPUTS <username>-<org>-<hostname>.emc.xml .EXAMPLE Copy-ArPureHostVol -pureName bowpure002 -source testdummy02 -vol testdummy02_G -target testdummy01 Verifies that the disk volume, testdummy02_G is masked to the source server, testdummy02 and creates or overwrites the SNAP volume, testdummy02_G_X. The SNAP volume, testdummy02_G_X will be masked to the target server, testdummy01 if need be. A different suffix can be applied to the new disk volume by specifying the -suffix option. .EXAMPLE Copy-ArPureHostVol -pureName bowpure002 -source testdummy02 -vol testdummy02_G Creates a SNAP volume, testdummy02_G_X which is not masked to any host. .NOTES Requires Installation of PureSystem PowerShell module. Execute the following to install PureStorage PowerShell module. Install-Module -Name PureStoragePowerShellSDK -scope currentuser Author: Craig Dayton 0.0.2.4 07/29/2017 : cadayton : Initial Release .LINK https://github.com/cadayton/Venom .LINK http://venom.readthedocs.io #> function Copy-VePureHostVol { # Copy-VePureHostVol Params [cmdletbinding()] Param ( [Parameter(Position=0, Mandatory=$False, ValueFromPipeline=$True)] [string]$pureName, [Parameter(Position=1, Mandatory=$False, ValueFromPipeline=$True)] [string]$org, [Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$True)] # [ValidateScript({ # if ($_ -match "dsssar") { $true } else { # Write-Host "$_ source server name must contain 'dsssar'" -ForegroundColor Blue; # Throw; # } # })] [string]$source, [Parameter(Position=2, Mandatory=$true, ValueFromPipeline=$True)] # [ValidateScript({ # if ($_ -match "dsssar") { $true } else { # Write-Host "$_ volume name must contain 'dsssar'" -ForegroundColor Blue; # Throw; # } # })] [string]$vol, [Parameter(Position=3, Mandatory=$true, ValueFromPipeline=$True)] # [ValidateScript({ # if ($_ -match "dsssar") { $true } else { # Write-Host "$_ target server name must contain 'dsssar'" -ForegroundColor Blue; # Throw; # } # })] [string]$target, [Parameter(Position=4, Mandatory=$False, ValueFromPipeline=$True)] [ValidateScript({ if ($_.length -le 4) { $true } else { Write-Host "$_ Max size for suffix option is 4 characters" -ForegroundColor Blue; Throw; } })] [string]$suffix = "X" ) # Write-Host "Copy-PureHostVol version 0.0.2.4" -ForegroundColor Green $ip = Get-PureIpAddress $pureName; Write-Verbose "$pureName IpAddress is $ip" if ($ip -eq $null) { Write-Host "Check your spelling" -ForegroundColor Blue; return 1; } Set-Credentials $Script:org $Script:username $pure = Set-PureArray $ip $Script:cred; if ($pure -is [String]) { # Object expected Write-Host $pure -ForegroundColor Red; Write-Host "Try pinging $pureName using the IP address" -ForegroundColor Blue; return 2; } # Validate source volume is masked to source server. if (!(Test-VolumeMasking $pure $source $vol)) { $err = "Copy-VePureHostVol: The volume $vol is not masked to the source server, $source - $env:USERNAME" Write-Host $err -ForegroundColor Red return 3; } # # Set target volume name and determine masking status $newvol = $vol + "_" + $suffix; [bool]$maskNewVol = $false; if (!(Test-VolumeMasking $pure $target $newvol)) { Write-Verbose "The volume $newvol is not masked to the target server, $target - $env:USERNAME"; $maskNewVol = $true; } # # Create new SNAP or overwrite existing SNAP try { New-PfaVolume -Array $pure -VolumeName $newvol -Source $vol -Overwrite | Out-Null; } Catch { $err = "Copy-VePureHostVol: Error creating or updating volume $newvol for target server, $target" Write-Host $err -ForegroundColor Red return 4; } Write-Host "SNAP created: $newvol" -ForegroundColor Green # # Mask new volume to target server if necessary if (!([string]::IsNullOrEmpty($target))) { if ($maskNewVol) { try { New-PfaHostVolumeConnection -array $pure -VolumeName $newVol -HostName $target | Out-Null } catch { $err = "Copy-VePureHostVol: Error masking $newVol to target server, $target - $env:USERNAME" Write-Host $err -ForegroundColor Red return 5; } Write-Host "SNAP $newVol masked to $target" -ForegroundColor Green } } # } # |