@@ -61,7 +61,10 @@ function Update-PfaVvolVmVolumeGroup {
6161 [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore ]$datastore ,
6262
6363 [Parameter (Position = 2 , ValueFromPipeline = $True )]
64- [PurePowerShell.PureArray []]$flasharray
64+ [PurePowerShell.PureArray []]$flasharray ,
65+
66+ [Parameter (ParameterSetName = ' VM' , Position = 3 )]
67+ [String ]$volumeGroupName
6568 )
6669 $volumeFinalNames = @ ()
6770 if ($null -ne $datastore )
@@ -81,23 +84,6 @@ function Update-PfaVvolVmVolumeGroup {
8184 }
8285 foreach ($vm in $vms )
8386 {
84- $configUUID = $vm.ExtensionData.Config.VmStorageObjectId
85- if ($null -eq $configUUID )
86- {
87- write-warning - message " The input VM $ ( $vm.name ) is not a vVol-based virtual machine. Skipping"
88- continue
89- }
90- add-type @"
91- using System.Net;
92- using System.Security.Cryptography.X509Certificates;
93- public class TrustAllCertsPolicy : ICertificatePolicy {
94- public bool CheckValidationResult(
95- ServicePoint srvPoint, X509Certificate certificate,
96- WebRequest request, int certificateProblem) {
97- return true;
98- }
99- }
100- "@
10187 $vmDatastores = $vm | Get-Datastore
10288 foreach ($vmDatastore in $vmDatastores )
10389 {
@@ -115,62 +101,135 @@ public class TrustAllCertsPolicy : ICertificatePolicy {
115101 {
116102 $fa = get-PfaConnectionOfDatastore - datastore $vmDatastore - flasharrays $flasharray - ErrorAction Stop
117103 }
118- $faSession = new-PfaRestSession - flasharray $fa
119- [Net.ServicePointManager ]::SecurityProtocol = [Net.SecurityProtocolType ]::Tls12
120- [System.Net.ServicePointManager ]::CertificatePolicy = New-Object TrustAllCertsPolicy
121- $volumeConfig = Invoke-RestMethod - Method Get - Uri " https://$ ( $fa.Endpoint ) /api/$ ( $fa.apiversion ) /volume?tags=true&filter=value='${configUUID} '" - WebSession $faSession - ErrorAction Stop
122- $configVVolName = ($volumeConfig | where-object {$_.key -eq " PURE_VVOL_ID" }).name
123- if ($null -eq $configVVolName )
104+ $vmId = $vm.ExtensionData.Config.InstanceUuid
105+ $customVgroupName = $false
106+ if ([string ]::IsNullOrEmpty($volumeGroupName ))
124107 {
125- write-warning - message " The VM $ ( $vm.name ) was not found on this FlashArray. Skipping."
126- continue
108+ $volumeGroupName = $vm.Name
109+ }
110+ else {
111+ $customVgroupName = $true
127112 }
128- if ($vm .Name -match " ^[a-zA-Z0-9\-]+$" )
113+ if ($volumeGroupName -notmatch " ^[a-zA-Z0-9\-]+$" )
129114 {
130- $vmName = $vm.Name
115+ $volumeGroupName = $volumeGroupName -replace " [^\w\-]" , " "
116+ $volumeGroupName = $volumeGroupName -replace " [_]" , " "
117+ $volumeGroupName = $volumeGroupName -replace " " , " "
131118 }
132- else
119+ if ( $customVgroupName -eq $false )
133120 {
134- $vmName = $vm.Name -replace " [^\w\-]" , " "
135- $vmName = $vmName -replace " [_]" , " "
136- $vmName = $vmName -replace " " , " "
121+ $vGroupRand = ' {0:X}' -f (get-random - Minimum 286331153 - max 4294967295 )
122+ $volumeGroupName = " vvol-$ ( $volumeGroupName ) -$ ( $vGroupRand ) -vg"
137123 }
138- $vGroupRand = ' {0:X} ' -f ( get-random - Minimum 286331153 - max 4294967295 )
139- $newName = " vvol- $ ( $vmName ) - $ ( $vGroupRand ) -vg "
140- if ([ Regex ]::Matches( $configVVolName , " / " ).Count -eq 0 )
124+ $vVolInfos = $null
125+ $vVolInfos = Get-PfaVvolVol - vm $vm [ 0 ] - flasharray $fa
126+ if (( $vVolInfos .VolumeGroup | Select-Object - Unique).count -gt 1 )
141127 {
142- $vGroup = New-PfaVolumeGroup - Array $fa - Name $newName
128+ $vgroupsUnique = $vvolInfos.VolumeGroup | Select-Object - Unique
129+ Write-Warning - Message " Skipping the VM $ ( $VM.name ) as it is spread across more than one volume group: `r`n $ ( $vgroupsUnique ) "
130+ continue
143131 }
144- else {
145- $vGroup = $configVVolName .split ( ' / ' )[ 0 ]
146- $vGroup = Invoke-RestMethod - Method Put - Uri " https:// $ ( $fa .Endpoint ) /api/ $ ( $fa .apiversion ) /vgroup/ ${vGroup} ?name= ${newName} " - WebSession $faSession - ErrorAction Stop
132+ elseif (( $vVolInfos .VolumeGroup | Select-Object - Unique).count -eq 0 )
133+ {
134+ New-PfaRestOperation - resourceType " vgroup/ $ ( $volumeGroupName ) " - restOperationType POST - flasharray $fa - SkipCertificateCheck - ErrorAction stop | Out-Null
147135 }
148- $vmId = $vm.ExtensionData.Config.InstanceUuid
149- $volumesVmId = Invoke-RestMethod - Method Get - Uri " https://$ ( $fa.Endpoint ) /api/$ ( $fa.apiversion ) /volume?tags=true&filter=value='${vmId} '" - WebSession $faSession - ErrorAction Stop
150- $volumeNames = $volumesVmId | where-object {$_.key -eq " VMW_VmID" }
151- foreach ($volumeName in $volumeNames )
136+ elseif (($vVolInfos.VolumeGroup | Select-Object - Unique).count -eq 1 )
152137 {
153- if ([Regex ]::Matches($volumeName.name , " /" ).Count -eq 1 )
154- {
155- if ($newName -ne $volumeName.name.split (' /' )[0 ])
156- {
157- $volName = $volumeName.name.split (' /' )[1 ]
158- Add-PfaVolumeToContainer - Array $fa - Container $newName - Name $volName | Out-Null
159- }
160- }
161- else {
162- $volName = $volumeName.name
163- Add-PfaVolumeToContainer - Array $fa - Container $newName - Name $volName | Out-Null
164- }
138+ if ($volumeGroupName -ne ($vVolInfos.VolumeGroup | Select-Object - Unique))
139+ {
140+ $vGroup = $vVolInfos.VolumeGroup | Select-Object - Unique
141+ New-PfaRestOperation - resourceType " vgroup/$ ( $vGroup ) " - restOperationType PUT - jsonBody " {`" name`" :`" $ ( $volumeGroupName ) `" }" - flasharray $fa - SkipCertificateCheck | Out-Null
142+ }
143+ }
144+ $vVolInfos = $null
145+ $vVolInfos = Get-PfaVvolVol - vm $vm [0 ] - flasharray $fa
146+ foreach ($vVolInfo in $vVolInfos )
147+ {
148+ if (($vVolInfo.VolumeGroup -ne $volumeGroupName ) -and ($null -ne $vVolInfo.VolumeGroup ))
149+ {
150+ New-PfaRestOperation - resourceType " volume/$ ( $vVolInfo.VolumeGroup ) /$ ( $vVolInfo.Volume ) " - restOperationType PUT - flasharray $fa - SkipCertificateCheck - jsonBody " {`" container`" :`" $ ( $volumeGroupName ) `" }" | Out-Null
151+ }
152+ elseif ($null -eq $vVolInfo.VolumeGroup )
153+ {
154+ New-PfaRestOperation - resourceType " volume/$ ( $vVolInfo.Volume ) " - restOperationType PUT - flasharray $fa - SkipCertificateCheck - jsonBody " {`" container`" :`" $ ( $volumeGroupName ) `" }" | Out-Null
155+ }
156+ }
157+ $volumesAfterMove = (New-PfaRestOperation - resourceType " volume" - restOperationType GET - queryFilter " ?tags=true&filter=value=`' $ ( $vmId ) `' " - flasharray $fa - SkipCertificateCheck).Name | Select-Object - Unique
158+ foreach ($volumeAfterMove in $volumesAfterMove ) {
159+ $volumeFinalNames += $volumeAfterMove
165160 }
166- $volumesVmId = Invoke-RestMethod - Method Get - Uri " https://$ ( $fa.Endpoint ) /api/$ ( $fa.apiversion ) /volume?tags=true&filter=value='${vmId} '" - WebSession $faSession - ErrorAction Stop
167- $volumeFinalNames += $volumesVmId | where-object {$_.key -eq " VMW_VmID" }
168- remove-PfaRestSession - flasharray $fa - faSession $faSession | Out-Null
169161 }
170162 }
171163 }
172- return $volumeFinalNames.name
164+ return $volumeFinalNames
173165}
166+ function Get-PfaVvolVol {
167+ <#
168+ . SYNOPSIS
169+ Gets the vVol volumes of entered VM
170+ . DESCRIPTION
171+ Takes in a virtual machine
172+ . INPUTS
173+ Virtual machine (get-vm)
174+ . OUTPUTS
175+ Returns the FA volume and volume group name(s)
176+ . NOTES
177+ Version: 2.0
178+ Author: Cody Hosterman https://codyhosterman.com
179+ Creation Date: 05/26/2019
180+ Purpose/Change: Updated for new connection mgmt
181+ . EXAMPLE
182+ PS C:\ New-PfaConnection -endpoint flasharray-m20-2 -credentials (get-credential) -defaultArray
183+ PS C:\ get-vm myVM | get-harddisk | Get-VvolUuidFromVmdk
184+
185+ Pass in one or more vVol hard disks and return the corresponding vVol UUIDs
186+
187+ *******Disclaimer:******************************************************
188+ This scripts are offered "as is" with no warranty. While this
189+ scripts is tested and working in my environment, it is recommended that you test
190+ this script in a test lab before using in a production environment. Everyone can
191+ use the scripts/commands provided here without any written permission but I
192+ will not be liable for any damage or loss to the system.
193+ ************************************************************************
194+ #>
195+
196+ [CmdletBinding ()]
197+ Param (
198+ [Parameter (Position = 0 , ValueFromPipeline = $True , mandatory = $true )]
199+ [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine ]$vm ,
200+
201+ [Parameter (Position = 1 , ValueFromPipeline = $True , mandatory = $true )]
202+ [PurePowerShell.PureArray ]$flasharray
203+ )
204+ $arraySerial = (New-PfaRestOperation - resourceType array - restOperationType GET - flasharray $flasharray - SkipCertificateCheck).id
205+ $datastore = $vm | Get-Datastore | Where-Object {$_.Type -eq ' VVOL' } | Where-Object {$_.ExtensionData.Info.VvolDS.StorageArray [0 ].uuid.Substring(16 ) -eq $arraySerial }
206+ if ($null -eq $datastore )
207+ {
208+ throw " There are no volumes on this FlashArray $ ( $flasharray.EndPoint ) for entered VM $ ( $vm.name ) "
209+ }
210+ else
211+ {
212+ $vmId = $vm.ExtensionData.Config.InstanceUuid
213+ $vVolVolumes = (New-PfaRestOperation - resourceType " volume" - restOperationType GET - queryFilter " ?tags=true&filter=value=`' $ ( $vmId ) `' " - flasharray $flasharray - SkipCertificateCheck).Name | Select-Object - Unique
214+ $vVolInfos = @ ()
215+ foreach ($vVolVolume in $vVolVolumes )
216+ {
217+ $vVolInfo = New-Object - TypeName psobject
218+ if (($vVolVolume.split (" /" )).count -gt 1 )
219+ {
220+ $vVolInfo | Add-Member - MemberType NoteProperty - Name VolumeGroup - Value ($vVolVolume.split (" /" ))[0 ]
221+ $vVolInfo | Add-Member - MemberType NoteProperty - Name Volume - Value ($vVolVolume.split (" /" ))[1 ]
222+ }
223+ else {
224+ $vVolInfo | Add-Member - MemberType NoteProperty - Name VolumeGroup - Value $null
225+ $vVolInfo | Add-Member - MemberType NoteProperty - Name Volume - Value $vVolVolume
226+ }
227+ $vVolInfos += $vVolInfo
228+ }
229+ }
230+ return $vVolInfos
231+ }
232+
174233function Get-VvolUuidFromVmdk {
175234 <#
176235 . SYNOPSIS
0 commit comments